xref: /openbmc/sdbusplus/tools/sdbus++-gen-meson (revision 847a0c37)
1*847a0c37SPatrick Williams#!/usr/bin/env bash
2*847a0c37SPatrick Williams
3*847a0c37SPatrick Williamsset -e
4*847a0c37SPatrick Williams
5*847a0c37SPatrick Williamsfunction show_usage {
6*847a0c37SPatrick Williams    cat \
7*847a0c37SPatrick Williams<<EOF
8*847a0c37SPatrick WilliamsUsage: $(basename "$0") [options] <command-args>*
9*847a0c37SPatrick Williams
10*847a0c37SPatrick WilliamsGenerate meson.build files from a directory tree containing YAML files and
11*847a0c37SPatrick Williamsfacilitate building the sdbus++ sources.
12*847a0c37SPatrick Williams
13*847a0c37SPatrick WilliamsOptions:
14*847a0c37SPatrick Williams    --help              - Display this message
15*847a0c37SPatrick Williams    --command <cmd>     - Command mode to execute (default 'meson').
16*847a0c37SPatrick Williams    --directory <path>  - Root directory of the YAML source (default '.').
17*847a0c37SPatrick Williams    --output <path>     - Root directory of the output (default '.').
18*847a0c37SPatrick Williams    --tool <path>       - Path to the processing tool (default 'sdbus++').
19*847a0c37SPatrick Williams    --version           - Display this tool's version string.
20*847a0c37SPatrick Williams
21*847a0c37SPatrick WilliamsCommands:
22*847a0c37SPatrick Williams    meson               - Generate a tree of meson.build files corresponding
23*847a0c37SPatrick Williams                          to the source YAML files.
24*847a0c37SPatrick Williams    cpp <intf>          - Generate the source files from a YAML interface.
25*847a0c37SPatrick Williams    markdown <intf>     - Generate the markdown files from a YAML interface.
26*847a0c37SPatrick Williams    version             - Display this tool's version string.
27*847a0c37SPatrick Williams
28*847a0c37SPatrick WilliamsEOF
29*847a0c37SPatrick Williams}
30*847a0c37SPatrick Williams
31*847a0c37SPatrick Williams## The version is somewhat arbitrary but is used to create a warning message
32*847a0c37SPatrick Williams## if a repository contains old copies of the generated meson.build files and
33*847a0c37SPatrick Williams## needs an update.  We should increment the version number whenever the
34*847a0c37SPatrick Williams## resulting meson.build would change.
35*847a0c37SPatrick Williamstool_version="sdbus++-gen-meson version 1"
36*847a0c37SPatrick Williamsfunction show_version {
37*847a0c37SPatrick Williams    echo "$tool_version"
38*847a0c37SPatrick Williams}
39*847a0c37SPatrick Williams
40*847a0c37SPatrick Williams# Set up defaults.
41*847a0c37SPatrick Williamssdbuspp="sdbus++"
42*847a0c37SPatrick Williamsoutputdir="."
43*847a0c37SPatrick Williamscmd="meson"
44*847a0c37SPatrick Williamsrootdir="."
45*847a0c37SPatrick Williams
46*847a0c37SPatrick Williams# Parse options.
47*847a0c37SPatrick Williamsoptions="$(getopt -o hc:d:o:t:v --long help,command:,directory:,output:,tool:,version -- "$@")"
48*847a0c37SPatrick Williamseval set -- "$options"
49*847a0c37SPatrick Williams
50*847a0c37SPatrick Williamswhile true;
51*847a0c37SPatrick Williamsdo
52*847a0c37SPatrick Williams    case "$1" in
53*847a0c37SPatrick Williams        -h | --help)
54*847a0c37SPatrick Williams            show_usage
55*847a0c37SPatrick Williams            exit
56*847a0c37SPatrick Williams            ;;
57*847a0c37SPatrick Williams
58*847a0c37SPatrick Williams        -c | --command)
59*847a0c37SPatrick Williams            shift
60*847a0c37SPatrick Williams            cmd="$1"
61*847a0c37SPatrick Williams            shift
62*847a0c37SPatrick Williams            ;;
63*847a0c37SPatrick Williams
64*847a0c37SPatrick Williams        -d | --directory)
65*847a0c37SPatrick Williams            shift
66*847a0c37SPatrick Williams            rootdir="$1"
67*847a0c37SPatrick Williams            shift
68*847a0c37SPatrick Williams            ;;
69*847a0c37SPatrick Williams
70*847a0c37SPatrick Williams        -o | --output)
71*847a0c37SPatrick Williams            shift
72*847a0c37SPatrick Williams            outputdir="$1"
73*847a0c37SPatrick Williams            shift
74*847a0c37SPatrick Williams            ;;
75*847a0c37SPatrick Williams
76*847a0c37SPatrick Williams        -t | --tool)
77*847a0c37SPatrick Williams            shift
78*847a0c37SPatrick Williams            sdbuspp="$1"
79*847a0c37SPatrick Williams            shift
80*847a0c37SPatrick Williams            ;;
81*847a0c37SPatrick Williams
82*847a0c37SPatrick Williams        -v | --version)
83*847a0c37SPatrick Williams            show_version
84*847a0c37SPatrick Williams            exit
85*847a0c37SPatrick Williams            ;;
86*847a0c37SPatrick Williams
87*847a0c37SPatrick Williams        --)
88*847a0c37SPatrick Williams            shift
89*847a0c37SPatrick Williams            break
90*847a0c37SPatrick Williams            ;;
91*847a0c37SPatrick Williams    esac
92*847a0c37SPatrick Williamsdone
93*847a0c37SPatrick Williams
94*847a0c37SPatrick Williams## Create an initially empty meson.build file.
95*847a0c37SPatrick Williams## $1 - path to create meson.build at.
96*847a0c37SPatrick Williamsfunction meson_empty_file {
97*847a0c37SPatrick Williams    mkdir -p "$1"
98*847a0c37SPatrick Williams    echo "# Generated file; do not modify." > "$1/meson.build"
99*847a0c37SPatrick Williams}
100*847a0c37SPatrick Williams
101*847a0c37SPatrick Williams## Create the root-level meson.build
102*847a0c37SPatrick Williams##
103*847a0c37SPatrick Williams## Inserts rules to run the available version of this tool to ensure the
104*847a0c37SPatrick Williams## version has not changed.
105*847a0c37SPatrick Williamsfunction meson_create_root {
106*847a0c37SPatrick Williams    meson_empty_file "$outputdir"
107*847a0c37SPatrick Williams
108*847a0c37SPatrick Williams    cat >> "$outputdir/meson.build" \
109*847a0c37SPatrick Williams<<EOF
110*847a0c37SPatrick Williamssdbuspp_gen_meson_ver = run_command(
111*847a0c37SPatrick Williams    sdbuspp_gen_meson_prog,
112*847a0c37SPatrick Williams    '--version',
113*847a0c37SPatrick Williams).stdout().strip().split('\n')[0]
114*847a0c37SPatrick Williams
115*847a0c37SPatrick Williamsif sdbuspp_gen_meson_ver != '$tool_version'
116*847a0c37SPatrick Williams    warning('Generated meson files from wrong version of sdbus++-gen-meson.')
117*847a0c37SPatrick Williams    warning(
118*847a0c37SPatrick Williams        'Expected "$tool_version", got:',
119*847a0c37SPatrick Williams        sdbuspp_gen_meson_ver
120*847a0c37SPatrick Williams    )
121*847a0c37SPatrick Williamsendif
122*847a0c37SPatrick Williams
123*847a0c37SPatrick WilliamsEOF
124*847a0c37SPatrick Williams}
125*847a0c37SPatrick Williams
126*847a0c37SPatrick Williams## hash-tables to store:
127*847a0c37SPatrick Williams##      meson_paths - list of subdirectory paths for which an empty meson.build
128*847a0c37SPatrick Williams##                    has already been created.
129*847a0c37SPatrick Williams##      interfaces - list of interface paths which a YAML has been found and
130*847a0c37SPatrick Williams##                   which YAML types (interface, errors, etc.).
131*847a0c37SPatrick Williamsdeclare -A meson_paths
132*847a0c37SPatrick Williamsdeclare -A interfaces
133*847a0c37SPatrick Williams
134*847a0c37SPatrick Williams## Ensure the meson.build files to a path have been created.
135*847a0c37SPatrick Williams## $1 - The path requiring to be created.
136*847a0c37SPatrick Williamsfunction meson_create_path {
137*847a0c37SPatrick Williams
138*847a0c37SPatrick Williams    meson_path="$outputdir"
139*847a0c37SPatrick Williams    prev_meson_path=""
140*847a0c37SPatrick Williams
141*847a0c37SPatrick Williams    # Split the path into segments.
142*847a0c37SPatrick Williams    for part in $(echo "$1" | tr '/' '\n');
143*847a0c37SPatrick Williams    do
144*847a0c37SPatrick Williams        prev_meson_path="$meson_path"
145*847a0c37SPatrick Williams        meson_path="$meson_path/$part"
146*847a0c37SPatrick Williams
147*847a0c37SPatrick Williams        # Create the meson.build for this segment if it doesn't already exist.
148*847a0c37SPatrick Williams        if [ "x" == "x${meson_paths[$meson_path]}" ];
149*847a0c37SPatrick Williams        then
150*847a0c37SPatrick Williams            meson_paths["$meson_path"]="1"
151*847a0c37SPatrick Williams            meson_empty_file "$meson_path"
152*847a0c37SPatrick Williams
153*847a0c37SPatrick Williams            # Add the 'subdir' link into the parent's meson.build.
154*847a0c37SPatrick Williams            # We need to skip adding the links into the 'root' meson.build
155*847a0c37SPatrick Williams            # because most repositories want to selectively add TLDs based
156*847a0c37SPatrick Williams            # on config flags.  Let them figure out their own logic for that.
157*847a0c37SPatrick Williams            if [ "x$outputdir" != "x$prev_meson_path" ];
158*847a0c37SPatrick Williams            then
159*847a0c37SPatrick Williams                echo "subdir('$part')" >> "$prev_meson_path/meson.build"
160*847a0c37SPatrick Williams            fi
161*847a0c37SPatrick Williams        fi
162*847a0c37SPatrick Williams    done
163*847a0c37SPatrick Williams}
164*847a0c37SPatrick Williams
165*847a0c37SPatrick Williams## Generate the meson target for the source files (.cpp/.hpp) from a YAML
166*847a0c37SPatrick Williams## interface.
167*847a0c37SPatrick Williams##
168*847a0c37SPatrick Williams## $1 - The interface to generate a target for.
169*847a0c37SPatrick Williamsfunction meson_cpp_target {
170*847a0c37SPatrick Williams
171*847a0c37SPatrick Williams    # Determine the source and output files based on the YAMLs present.
172*847a0c37SPatrick Williams    sources=""
173*847a0c37SPatrick Williams    outputs=""
174*847a0c37SPatrick Williams    for s in ${interfaces[$1]};
175*847a0c37SPatrick Williams    do
176*847a0c37SPatrick Williams        sources="${sources}meson.source_root() / '$1.$s', "
177*847a0c37SPatrick Williams
178*847a0c37SPatrick Williams        case "$s" in
179*847a0c37SPatrick Williams            errors.yaml)
180*847a0c37SPatrick Williams                outputs="${outputs}'error.cpp', 'error.hpp', "
181*847a0c37SPatrick Williams                ;;
182*847a0c37SPatrick Williams
183*847a0c37SPatrick Williams            interface.yaml)
184*847a0c37SPatrick Williams                outputs="${outputs}'server.cpp', 'server.hpp', "
185*847a0c37SPatrick Williams                outputs="${outputs}'client.hpp', "
186*847a0c37SPatrick Williams                ;;
187*847a0c37SPatrick Williams        esac
188*847a0c37SPatrick Williams    done
189*847a0c37SPatrick Williams
190*847a0c37SPatrick Williams    # Create the target to generate the 'outputs'.
191*847a0c37SPatrick Williams    cat >> "$outputdir/$1/meson.build" \
192*847a0c37SPatrick Williams<<EOF
193*847a0c37SPatrick Williamsgenerated_sources += custom_target(
194*847a0c37SPatrick Williams    '$1__cpp'.underscorify(),
195*847a0c37SPatrick Williams    input: [ $sources ],
196*847a0c37SPatrick Williams    output: [ $outputs ],
197*847a0c37SPatrick Williams    command: [
198*847a0c37SPatrick Williams        sdbuspp_gen_meson_prog, '--command', 'cpp',
199*847a0c37SPatrick Williams        '--output', meson.current_build_dir(),
200*847a0c37SPatrick Williams        '--tool', sdbusplusplus_prog,
201*847a0c37SPatrick Williams        '--directory', meson.source_root(),
202*847a0c37SPatrick Williams        '$1',
203*847a0c37SPatrick Williams    ],
204*847a0c37SPatrick Williams)
205*847a0c37SPatrick Williams
206*847a0c37SPatrick WilliamsEOF
207*847a0c37SPatrick Williams}
208*847a0c37SPatrick Williams
209*847a0c37SPatrick Williams## Generate the meson target for the markdown files from a YAML interface.
210*847a0c37SPatrick Williams## $1 - The interface to generate a target for.
211*847a0c37SPatrick Williamsfunction meson_md_target {
212*847a0c37SPatrick Williams
213*847a0c37SPatrick Williams    # Determine the source files based on the YAMLs present.
214*847a0c37SPatrick Williams    sources=""
215*847a0c37SPatrick Williams    for s in ${interfaces[$1]};
216*847a0c37SPatrick Williams    do
217*847a0c37SPatrick Williams        sources="${sources}meson.source_root() / '$1.$s', "
218*847a0c37SPatrick Williams    done
219*847a0c37SPatrick Williams
220*847a0c37SPatrick Williams    # Create the target to generate the interface.md file.
221*847a0c37SPatrick Williams    cat >> "$outputdir/$(dirname "$1")/meson.build" \
222*847a0c37SPatrick Williams<<EOF
223*847a0c37SPatrick Williamsgenerated_others += custom_target(
224*847a0c37SPatrick Williams    '$1__markdown'.underscorify(),
225*847a0c37SPatrick Williams    input: [ $sources ],
226*847a0c37SPatrick Williams    output: [ '$(basename "$1").md' ],
227*847a0c37SPatrick Williams    command: [
228*847a0c37SPatrick Williams        sdbuspp_gen_meson_prog, '--command', 'markdown',
229*847a0c37SPatrick Williams        '--output', meson.current_build_dir(),
230*847a0c37SPatrick Williams        '--tool', sdbusplusplus_prog,
231*847a0c37SPatrick Williams        '--directory', meson.source_root(),
232*847a0c37SPatrick Williams        '$1',
233*847a0c37SPatrick Williams    ],
234*847a0c37SPatrick Williams    build_by_default: true,
235*847a0c37SPatrick Williams)
236*847a0c37SPatrick Williams
237*847a0c37SPatrick WilliamsEOF
238*847a0c37SPatrick Williams}
239*847a0c37SPatrick Williams
240*847a0c37SPatrick Williams## Handle command=meson by generating the tree of meson.build files.
241*847a0c37SPatrick Williamsfunction cmd_meson {
242*847a0c37SPatrick Williams    TLDs="com net org xyz"
243*847a0c37SPatrick Williams    yamls=""
244*847a0c37SPatrick Williams
245*847a0c37SPatrick Williams    # Find all the YAML files in the TLD subdirectories.
246*847a0c37SPatrick Williams    for d in $TLDs;
247*847a0c37SPatrick Williams    do
248*847a0c37SPatrick Williams        dir="$rootdir/$d"
249*847a0c37SPatrick Williams        if [ ! -d "$dir" ];
250*847a0c37SPatrick Williams        then
251*847a0c37SPatrick Williams            continue
252*847a0c37SPatrick Williams        fi
253*847a0c37SPatrick Williams
254*847a0c37SPatrick Williams        yamls="\
255*847a0c37SPatrick Williams            $yamls \
256*847a0c37SPatrick Williams            $(find "$dir" -name '*.interface.yaml' -o -name '*.errors.yaml') \
257*847a0c37SPatrick Williams            "
258*847a0c37SPatrick Williams    done
259*847a0c37SPatrick Williams
260*847a0c37SPatrick Williams    # Sort YAMLs
261*847a0c37SPatrick Williams    yamls="$(echo "$yamls" | tr " " "\n" | sort)"
262*847a0c37SPatrick Williams
263*847a0c37SPatrick Williams    # Assign the YAML files into the hash-table by interface name.
264*847a0c37SPatrick Williams    for y in $yamls;
265*847a0c37SPatrick Williams    do
266*847a0c37SPatrick Williams        rel="$(realpath "--relative-to=$rootdir" "$y")"
267*847a0c37SPatrick Williams        dir="$(dirname "$rel")"
268*847a0c37SPatrick Williams        ext="${rel#*.}"
269*847a0c37SPatrick Williams        base="$(basename "$rel" ".$ext")"
270*847a0c37SPatrick Williams
271*847a0c37SPatrick Williams        interfaces["$dir/$base"]="${interfaces[$dir/$base]} $ext"
272*847a0c37SPatrick Williams    done
273*847a0c37SPatrick Williams
274*847a0c37SPatrick Williams    # Create the meson.build files.
275*847a0c37SPatrick Williams    meson_create_root
276*847a0c37SPatrick Williams    sorted_ifaces="$(echo "${!interfaces[@]}" | tr " " "\n" | sort)"
277*847a0c37SPatrick Williams    for i in ${sorted_ifaces};
278*847a0c37SPatrick Williams    do
279*847a0c37SPatrick Williams        meson_create_path "$i"
280*847a0c37SPatrick Williams        meson_cpp_target "$i"
281*847a0c37SPatrick Williams        meson_md_target "$i"
282*847a0c37SPatrick Williams    done
283*847a0c37SPatrick Williams}
284*847a0c37SPatrick Williams
285*847a0c37SPatrick Williams## Handle command=cpp by calling sdbus++ as appropriate.
286*847a0c37SPatrick Williams## $1 - interface to generate.
287*847a0c37SPatrick Williams##
288*847a0c37SPatrick Williams## For an interface foo/bar, the outputdir is expected to be foo/bar.
289*847a0c37SPatrick Williamsfunction cmd_cpp {
290*847a0c37SPatrick Williams
291*847a0c37SPatrick Williams    if [ "x" == "x$1" ];
292*847a0c37SPatrick Williams    then
293*847a0c37SPatrick Williams        show_usage
294*847a0c37SPatrick Williams        exit 1
295*847a0c37SPatrick Williams    fi
296*847a0c37SPatrick Williams
297*847a0c37SPatrick Williams    if [ ! -e "$rootdir/$1.interface.yaml" ] && \
298*847a0c37SPatrick Williams        [ ! -e "$rootdir/$1.errors.yaml" ];
299*847a0c37SPatrick Williams    then
300*847a0c37SPatrick Williams        echo "Missing YAML for $1."
301*847a0c37SPatrick Williams        exit 1
302*847a0c37SPatrick Williams    fi
303*847a0c37SPatrick Williams
304*847a0c37SPatrick Williams    mkdir -p "$outputdir"
305*847a0c37SPatrick Williams
306*847a0c37SPatrick Williams    sdbusppcmd="$sdbuspp -r $rootdir"
307*847a0c37SPatrick Williams    intf="${1//\//.}"
308*847a0c37SPatrick Williams
309*847a0c37SPatrick Williams    if [ -e "$rootdir/$1.interface.yaml" ];
310*847a0c37SPatrick Williams    then
311*847a0c37SPatrick Williams        $sdbusppcmd interface server-header "$intf" > "$outputdir/server.hpp"
312*847a0c37SPatrick Williams        $sdbusppcmd interface server-cpp "$intf" > "$outputdir/server.cpp"
313*847a0c37SPatrick Williams        $sdbusppcmd interface client-header "$intf" > "$outputdir/client.hpp"
314*847a0c37SPatrick Williams    fi
315*847a0c37SPatrick Williams
316*847a0c37SPatrick Williams    if [ -e "$rootdir/$1.errors.yaml" ];
317*847a0c37SPatrick Williams    then
318*847a0c37SPatrick Williams        $sdbusppcmd error exception-header "$intf" > "$outputdir/error.hpp"
319*847a0c37SPatrick Williams        $sdbusppcmd error exception-cpp "$intf" > "$outputdir/error.cpp"
320*847a0c37SPatrick Williams    fi
321*847a0c37SPatrick Williams}
322*847a0c37SPatrick Williams
323*847a0c37SPatrick Williams## Handle command=markdown by calling sdbus++ as appropriate.
324*847a0c37SPatrick Williams## $1 - interface to generate.
325*847a0c37SPatrick Williams##
326*847a0c37SPatrick Williams## For an interface foo/bar, the outputdir is expected to be foo.
327*847a0c37SPatrick Williamsfunction cmd_markdown {
328*847a0c37SPatrick Williams
329*847a0c37SPatrick Williams    if [ "x" == "x$1" ];
330*847a0c37SPatrick Williams    then
331*847a0c37SPatrick Williams        show_usage
332*847a0c37SPatrick Williams        exit 1
333*847a0c37SPatrick Williams    fi
334*847a0c37SPatrick Williams
335*847a0c37SPatrick Williams    if [ ! -e "$rootdir/$1.interface.yaml" ] && \
336*847a0c37SPatrick Williams        [ ! -e "$rootdir/$1.errors.yaml" ];
337*847a0c37SPatrick Williams    then
338*847a0c37SPatrick Williams        echo "Missing YAML for $1."
339*847a0c37SPatrick Williams        exit 1
340*847a0c37SPatrick Williams    fi
341*847a0c37SPatrick Williams
342*847a0c37SPatrick Williams    mkdir -p "$outputdir"
343*847a0c37SPatrick Williams
344*847a0c37SPatrick Williams    sdbusppcmd="$sdbuspp -r $rootdir"
345*847a0c37SPatrick Williams    intf="${1//\//.}"
346*847a0c37SPatrick Williams    base="$(basename "$1")"
347*847a0c37SPatrick Williams
348*847a0c37SPatrick Williams    echo -n > "$outputdir/$base.md"
349*847a0c37SPatrick Williams    if [ -e "$rootdir/$1.interface.yaml" ];
350*847a0c37SPatrick Williams    then
351*847a0c37SPatrick Williams        $sdbusppcmd interface markdown "$intf" >> "$outputdir/$base.md"
352*847a0c37SPatrick Williams    fi
353*847a0c37SPatrick Williams
354*847a0c37SPatrick Williams    if [ -e "$rootdir/$1.errors.yaml" ];
355*847a0c37SPatrick Williams    then
356*847a0c37SPatrick Williams        $sdbusppcmd error markdown "$intf" >> "$outputdir/$base.md"
357*847a0c37SPatrick Williams    fi
358*847a0c37SPatrick Williams}
359*847a0c37SPatrick Williams
360*847a0c37SPatrick Williams## Handle command=version.
361*847a0c37SPatrick Williamsfunction cmd_version {
362*847a0c37SPatrick Williams    show_version
363*847a0c37SPatrick Williams}
364*847a0c37SPatrick Williams
365*847a0c37SPatrick Williams"cmd_$cmd" "$*"
366