Repository: mesonbuild/meson

Issue:
configure_file: make input kwarg optional if command is specified?
I'm using configure_file() in the Gtk+ meson build to generate gresource.xml files based on a bunch of input filenames. This is done by calling a python script and passing the output filename and the input files to it.

I wonder if configure_file() really needs to insist on an input kwarg for this case, where `command:` is used?


Discussion:
Hmm, I thought I fixed that. Yes, there is no reason to require an input file.

Resolving patch:
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2267,6 +2267,7 @@ def func_configure_file(self, node, args, kwargs):
                                        'they are mutually exclusive.')
         # Validate input
         inputfile = None
+        ifile_abs = None
         if 'input' in kwargs:
             inputfile = kwargs['input']
             if isinstance(inputfile, list):
@@ -2277,8 +2278,8 @@ def func_configure_file(self, node, args, kwargs):
             if not isinstance(inputfile, (str, mesonlib.File)):
                 raise InterpreterException('Input must be a string or a file')
             ifile_abs = os.path.join(self.environment.source_dir, self.subdir, inputfile)
-        elif 'command' in kwargs:
-            raise InterpreterException('Required keyword argument \'input\' missing')
+        elif 'command' in kwargs and '@INPUT@' in kwargs['command']:
+            raise InterpreterException('@INPUT@ used as command argument, but no input file specified.')
         # Validate output
         output = kwargs['output']
         if not isinstance(output, str):
@@ -2307,7 +2308,10 @@ def func_configure_file(self, node, args, kwargs):
             # We use absolute paths for input and output here because the cwd
             # that the command is run from is 'unspecified', so it could change.
             # Currently it's builddir/subdir for in_builddir else srcdir/subdir.
-            values = mesonlib.get_filenames_templates_dict([ifile_abs], [ofile_abs])
+            if ifile_abs:
+                values = mesonlib.get_filenames_templates_dict([ifile_abs], [ofile_abs])
+            else:
+                values = mesonlib.get_filenames_templates_dict(None, [ofile_abs])
             # Substitute @INPUT@, @OUTPUT@, etc here.
             cmd = mesonlib.substitute_values(kwargs['command'], values)
             mlog.log('Configuring', mlog.bold(output), 'with command')


Test patch:
diff --git a/test cases/common/16 configure file/generator-without-input-file.py b/test cases/common/16 configure file/generator-without-input-file.py
new file mode 100755
--- /dev/null
+++ b/test cases/common/16 configure file/generator-without-input-file.py	
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import sys, os
+from pathlib import Path
+
+if len(sys.argv) != 2:
+    print("Wrong amount of parameters.")
+
+build_dir = Path(os.environ['MESON_BUILD_ROOT'])
+subdir = Path(os.environ['MESON_SUBDIR'])
+outputf = Path(sys.argv[1])
+
+with outputf.open('w') as ofile:
+    ofile.write("#define ZERO_RESULT 0\n")
diff --git a/test cases/common/16 configure file/installed_files.txt b/test cases/common/16 configure file/installed_files.txt
--- a/test cases/common/16 configure file/installed_files.txt	
+++ b/test cases/common/16 configure file/installed_files.txt	
@@ -1,3 +1,4 @@
 usr/share/appdir/config2.h
+usr/share/appdir/config2b.h
 usr/share/appdireh/config2-1.h
 usr/share/appdirok/config2-2.h
diff --git a/test cases/common/16 configure file/meson.build b/test cases/common/16 configure file/meson.build
--- a/test cases/common/16 configure file/meson.build	
+++ b/test cases/common/16 configure file/meson.build	
@@ -36,6 +36,16 @@ configure_file(input : 'dummy.dat',
   install_dir : 'share/appdir')
 run_command(check_file, join_paths(meson.current_build_dir(), 'config2.h'))
 
+# Same again as before, but an input file should not be required in
+# this case where we use a command/script to generate the output file.
+genscript2b = '@0@/generator-without-input-file.py'.format(meson.current_source_dir())
+ofile2b = '@0@/config2b.h'.format(meson.current_build_dir())
+configure_file(
+  output : 'config2b.h',
+  command : [genprog, genscript2b, ofile2b],
+  install_dir : 'share/appdir')
+run_command(check_file, join_paths(meson.current_build_dir(), 'config2b.h'))
+
 found_script = find_program('generator.py')
 # More configure_file tests in here
 subdir('subdir')