blob: 25c4c0e7706b1dc3ff2b788f3418a9c93b2323bf [file] [log] [blame]
#!/usr/bin/env bash
set -e
function show_usage {
echo "Usage: $0 [options] <dirs>+"
echo
echo "Generate the sdbus++ sources from a directory path."
echo
echo "Options:"
echo " --tool <path> - path to processing tool (default 'sdbus++')."
echo " --output <path> - directory to place output files (default '.')."
echo " --list-all - include all generated files in stdout list."
echo " --jobs <N> - number to run in parallel (default: $(nproc))."
echo " <dirs>+ - any number of subdirectories to generate."
echo
echo "The output on stdout is a list of generated files, which is intended"
echo "to be consumed by build systems, such as Meson."
echo
echo "This tool, by default, generates all files that are able to be"
echo "created by sdbus++. The output is a list of compilable sources that"
echo "were generated by the tool. The tool may generate outputs which are"
echo "not able to be compiled, such as documentation, but it does not put"
echo "them into stdout unless --list-all is given."
}
sdbuspp="sdbus++"
outputdir="."
listall="no"
parallel=$(nproc || grep -c ^processor < /proc/cpuinfo)
options="$(getopt -o ho:t:j: --long help,list-all,output:,tool:,jobs: -- "$@")"
eval set -- "$options"
while true;
do
case "$1" in
-h | --help)
show_usage
exit
;;
-j | --jobs)
shift
parallel="$1"
shift
;;
--list-all)
listall="yes"
shift
;;
-o | --output)
shift
outputdir="$1"
shift
;;
-t | --tool)
shift
sdbuspp="$1"
shift
;;
--)
shift
break
;;
esac
done
if [ $# -eq 0 ];
then
show_usage
exit 1
fi
all_jobs=""
declare -A emitted_file_names
# generate_single -- make a single call to sdbus++.
# $1: sdbus++ TYPE
# $2: sdbus++ PROCESS
# $3: sdbus++ ITEM
# $4: relative output file
# $5: 'append-mode' if present.
function generate_single {
if [ "xempty" == "x$1" ];
then
echo -n > "$outputdir/$4"
elif [ "x" == "x$5" ];
then
$sdbuspp "$1" "$2" "$3" > "$outputdir/$4" &
all_jobs="$all_jobs $!"
else
$sdbuspp "$1" "$2" "$3" >> "$outputdir/$4" &
all_jobs="$all_jobs $!"
fi
# Emit filename as needed.
filename=$outputdir/$4
if [ "x1" != "x${emitted_file_names[$filename]}" ];
then
emitted_file_names[$filename]="1"
# Always emit generated file name for foo-cpp and foo-header.
# Conditionally emit for everything else depending on $listall.
case "$2" in
*-cpp | *-header)
echo "$filename"
;;
*)
if [ "xyes" == "x$listall" ];
then
echo "$filename"
fi
;;
esac
fi
# Ensure that no more than ${parallel} jobs are running at a time and if so
# wait for them to finish.
if [[ $(echo "$all_jobs" | wc -w) -ge $parallel ]];
then
waitall
fi
}
function waitall {
for job in $all_jobs;
do
wait "$job"
done
all_jobs=""
}
for d in "$@";
do
interfaces="$(find "$d" -name '*.interface.yaml')"
errors="$(find "$d" -name '*.errors.yaml')"
# Some files are created from multiple YAML sources, but we don't know
# which YAML sources are present. For these files, we need to first
# create an empty file to ensure the file does not carry old data from
# a previous run.
for y in $interfaces $errors;
do
path="${y%.interface.yaml}"
path="${path%.errors.yaml}"
iface="${path//\//.}"
mkdir -p "$outputdir/$path"
generate_single empty markdown "$iface" "$path.md"
done
for i in $interfaces;
do
path="${i%.interface.yaml}"
iface="${path//\//.}"
generate_single interface server-header "$iface" "$path/server.hpp"
generate_single interface server-cpp "$iface" "$path/server.cpp"
generate_single interface client-header "$iface" "$path/client.hpp"
generate_single interface markdown "$iface" "$path.md" append
done
waitall # finish all before continuing
for e in $errors;
do
path="${e%.errors.yaml}"
iface="${path//\//.}"
generate_single error exception-header "$iface" "$path/error.hpp"
generate_single error exception-cpp "$iface" "$path/error.cpp"
generate_single error markdown "$iface" "$path.md" append
done
waitall # finish all before continuing
done