diff --git a/build-aux/compile-blueprints.sh b/build-aux/compile-blueprints.sh new file mode 100755 index 00000000..d19546b1 --- /dev/null +++ b/build-aux/compile-blueprints.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# +# Compile blueprint files to UI files all in the same directory. +# +# Usage: ./compile-blueprints.sh PATH_TO_BLUEPRINT_COMPILER OUTPUT_DIR BASE_INPUT_DIR [INPUT_FILE…] +# +# This should be a temporary solution to fix an incompatibility between our +# setup, blueprint-compiler and meson. +# +# The problem is that blueprint advises to use `custom_target()` with `output` +# set to `.`: https://gitlab.gnome.org/GNOME/blueprint-compiler/-/blob/70f32dc069c3ff13a54f24f24c0e720b938f587d/docs/setup.rst#L55 +# This doesn't work well with ninja's caching, as it doesn't know which files +# are actually generated, so it might consider that the output is generated too +# soon, and proceed to compiling the gresource before all blueprint files are +# actually compiled. +# +# The fix for this is to actually set the proper list of generated files for the +# output. This doesn't work with our setup because we generate files in +# subdirectories and `custom_target`'s `output` only accepts a list of files in +# the current directory. +# +# So we have 2 options to fix this: +# +# 1. Use a `meson.build` file per subdirectory to compile the blueprints +# separately which is tedious and results in a lot of duplication. +# 2. Keep our current setup and find a way to generate a list of outputs that is +# accepted by meson. +# +# For simplicity, we want to use the second option and it would be easy if we +# could use `generator()` to compile the blueprints. It requires +# `gnome.compile_resources()` to accept a `generated_list` in `dependencies`, +# but it doesn't: https://github.com/mesonbuild/meson/issues/12336. +# +# So this implements another solution: compile all the UI files in the same +# directory by using a name scheme that avoids collisions. Then we can overwrite +# the path where the resource will be available in the gresource file +# definition by setting an `alias`. +# +# The output files will be located in `OUTPUT_DIR` and their names are the +# path of `INPUT_FILE` relative to the `BASE_INPUT_DIR` with the slashes +# replaced by `-`, and the extension changed. + +set -e + +compiler="$1" +shift +output_dir="$1" +shift +base_input_dir="$1" +shift + +# For debugging. +# echo "Compiling files in $input_dir to $output_dir with $compiler" + +for input_file in "$@" +do + # Change extension. + output_file="${input_file%.blp}.ui" + # Remove base input dir to get relative path. + output_file="${output_file#$base_input_dir\/}" + # Replace slashes with dashes. + output_file="$output_dir/${output_file//\//-}" + + # For debugging + # echo "Compiling $input_file to $output_file" + + "$compiler" compile --output "$output_file" "$input_file" +done diff --git a/src/meson.build b/src/meson.build index d0f11c7e..16996404 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,43 +1,48 @@ if not build_env_only # Compile Blueprint resources blp_files = [] - foreach line : fs.read('ui-blueprint-resources.in').splitlines() - if not line.startswith('#') and line.strip() != '' - blp_files += line + ui_files = [] + ui_files_xml = '' + + # These files are already added manually in the resources file because they + # need custom handling. + blp_gresource_exceptions = [ + 'shortcuts-dialog.blp', # Must use the root prefix for auto-detection, it must not be under `/ui`. + ] + + foreach file : fs.read('ui-blueprint-resources.in').splitlines() + file = file.strip() + + if file.startswith('#') or file == '' + continue + endif + + blp_files += file + + # We need to put all output files in the same directory + ui_alias = file.replace('.blp', '.ui') + ui_file = ui_alias.replace('/', '-') + ui_files += ui_file + + if not blp_gresource_exceptions.contains(file) + ui_files_xml += '\n ' + ui_file + '' endif endforeach blueprints = custom_target( 'blueprints', input: blp_files, - output: '.', + output: ui_files, command: [ - blueprint_compiler, - 'batch-compile', - '@OUTPUT@', + '../build-aux/compile-blueprints.sh', + blueprint_compiler.full_path(), + '@OUTDIR@', '@CURRENT_SOURCE_DIR@', '@INPUT@', ], ) - # Populate the GResource file for the compiled Blueprint files dynamically, - # using the same file list. - # These files are already added manually in the resources file because they - # need custom handling. - blp_exceptions = [ - 'shortcuts-dialog.blp', # Must use the root prefix for auto-detection, it must not be under `/ui`. - ] - - ui_files_xml = '' - foreach file : blp_files - if not blp_exceptions.contains(file) - ui_files_xml += '\n ' + file.replace( - '.blp', - '.ui', - ) + '' - endif - endforeach - + # Populate the GResource file for the compiled Blueprint files dynamically. ui_resources_xml = configure_file( input: 'ui-resources.gresource.xml.in', output: 'ui-resources.gresource.xml',