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',