aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2017-02-18 21:05:51 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2017-02-20 23:32:04 +0530
commitcb0aa6a83a53afd61572219c1a81f1395d4c4603 (patch)
treeec097d3979ea716a466f0902a6110311669c6c12
parent1f0319c288e2bb989e17cb83f3dad9e412c38838 (diff)
downloadmeson-cb0aa6a83a53afd61572219c1a81f1395d4c4603.zip
meson-cb0aa6a83a53afd61572219c1a81f1395d4c4603.tar.gz
meson-cb0aa6a83a53afd61572219c1a81f1395d4c4603.tar.bz2
configure_file: Substitute @INPUT@/@OUTPUT@/etc in command
The same substitutions and rules as custom_target(). Also generally fix it to actually work when run in a subdir and with anything other than absolute paths for input and output files. We now also log a message when configuring files. Includes tests for all this.
-rw-r--r--mesonbuild/interpreter.py33
-rw-r--r--test cases/common/16 configure file/check_file.py6
-rwxr-xr-xtest cases/common/16 configure file/generator.py16
-rw-r--r--test cases/common/16 configure file/installed_files.txt2
-rw-r--r--test cases/common/16 configure file/meson.build18
-rw-r--r--test cases/common/16 configure file/subdir/meson.build19
6 files changed, 72 insertions, 22 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index f232a93..c036b64 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2218,12 +2218,24 @@ requirements use the version keyword argument instead.''')
raise InterpreterException('Must not specify both "configuration" '
'and "command" keyword arguments since '
'they are mutually exclusive.')
- inputfile = kwargs.get('input', None)
+ # Validate input
+ inputfile = None
+ if 'input' in kwargs:
+ inputfile = kwargs['input']
+ if isinstance(inputfile, list):
+ if len(inputfile) != 1:
+ m = "Keyword argument 'input' requires exactly one file"
+ raise InterpreterException(m)
+ inputfile = inputfile[0]
+ 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')
+ # Validate output
output = kwargs['output']
- if inputfile is not None and not isinstance(inputfile, str):
- raise InterpreterException('Input must be a string.')
if not isinstance(output, str):
- raise InterpreterException('Output must be a string.')
+ raise InterpreterException('Output file name must be a string')
if os.path.split(output)[0] != '':
raise InterpreterException('Output file name must not contain a subdirectory.')
(ofile_path, ofile_fname) = os.path.split(os.path.join(self.subdir, output))
@@ -2232,6 +2244,7 @@ requirements use the version keyword argument instead.''')
conf = kwargs['configuration']
if not isinstance(conf, ConfigurationDataHolder):
raise InterpreterException('Argument "configuration" is not of type configuration_data')
+ mlog.log('Configuring', mlog.bold(output), 'using configuration')
if inputfile is not None:
# Normalize the path of the conffile to avoid duplicates
# This is especially important to convert '/' to '\' on Windows
@@ -2239,15 +2252,19 @@ requirements use the version keyword argument instead.''')
if conffile not in self.build_def_files:
self.build_def_files.append(conffile)
os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True)
- ifile_abs = os.path.join(self.environment.source_dir, self.subdir, inputfile)
mesonlib.do_conf_file(ifile_abs, ofile_abs, conf.held_object)
else:
mesonlib.dump_conf_header(ofile_abs, conf.held_object)
conf.mark_used()
elif 'command' in kwargs:
- if 'input' not in kwargs:
- raise InterpreterException('Required keyword input missing.')
- res = self.func_run_command(node, kwargs['command'], {})
+ # 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])
+ # Substitute @INPUT@, @OUTPUT@, etc here.
+ cmd = mesonlib.substitute_values(kwargs['command'], values)
+ mlog.log('Configuring', mlog.bold(output), 'with command')
+ res = self.func_run_command(node, cmd, {'in_builddir': True})
if res.returncode != 0:
raise InterpreterException('Running configure command failed.\n%s\n%s' %
(res.stdout, res.stderr))
diff --git a/test cases/common/16 configure file/check_file.py b/test cases/common/16 configure file/check_file.py
new file mode 100644
index 0000000..449b77a
--- /dev/null
+++ b/test cases/common/16 configure file/check_file.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+assert(os.path.exists(sys.argv[1]))
diff --git a/test cases/common/16 configure file/generator.py b/test cases/common/16 configure file/generator.py
index 2c7f2f8..e3cc881 100755
--- a/test cases/common/16 configure file/generator.py
+++ b/test cases/common/16 configure file/generator.py
@@ -1,15 +1,17 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
-# On some platforms "python" points to Python 2
-# on others to Python 3. Work with both.
-
-from __future__ import print_function
import sys, os
+from pathlib import Path
if len(sys.argv) != 3:
print("Wrong amount of parameters.")
-assert(os.path.exists(sys.argv[1]))
+build_dir = Path(os.environ['MESON_BUILD_ROOT'])
+subdir = Path(os.environ['MESON_SUBDIR'])
+inputf = Path(sys.argv[1])
+outputf = Path(sys.argv[2])
+
+assert(inputf.exists())
-with open(sys.argv[2], 'w') as ofile:
+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
index 219b4c0..d9fee12 100644
--- a/test cases/common/16 configure file/installed_files.txt
+++ b/test cases/common/16 configure file/installed_files.txt
@@ -1 +1,3 @@
usr/share/appdir/config2.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
index b764c5a..bff041b 100644
--- a/test cases/common/16 configure file/meson.build
+++ b/test cases/common/16 configure file/meson.build
@@ -23,18 +23,22 @@ cfile)
test('inctest', e)
# Now generate a header file with an external script.
-genprog = find_program('python3', required : false)
-if not genprog.found()
- genprog = find_program('python')
-endif
+genprog = import('python3').find_python()
scriptfile = '@0@/generator.py'.format(meson.current_source_dir())
ifile = '@0@/dummy.dat'.format(meson.current_source_dir())
ofile = '@0@/config2.h'.format(meson.current_build_dir())
+check_file = find_program('check_file.py')
+# Configure in source root with command and absolute paths
configure_file(input : 'dummy.dat',
-output : 'config2.h',
-command : [genprog, scriptfile, ifile, ofile],
-install_dir : 'share/appdir')
+ output : 'config2.h',
+ command : [genprog, scriptfile, ifile, ofile],
+ install_dir : 'share/appdir')
+run_command(check_file, join_paths(meson.current_build_dir(), 'config2.h'))
+
+found_script = find_program('generator.py')
+# More configure_file tests in here
+subdir('subdir')
test('inctest2', executable('prog2', 'prog2.c'))
diff --git a/test cases/common/16 configure file/subdir/meson.build b/test cases/common/16 configure file/subdir/meson.build
new file mode 100644
index 0000000..d802c1d
--- /dev/null
+++ b/test cases/common/16 configure file/subdir/meson.build
@@ -0,0 +1,19 @@
+# Configure in subdir with absolute paths for input and relative for output
+configure_file(input : '../dummy.dat',
+ output : 'config2-1.h',
+ command : [genprog, scriptfile, ifile, 'config2-1.h'],
+ install_dir : 'share/appdireh')
+run_command(check_file, join_paths(meson.current_build_dir(), 'config2-1.h'))
+
+# Configure in subdir with files() for input and relative for output
+configure_file(input : '../dummy.dat',
+ output : 'config2-2.h',
+ command : [genprog, scriptfile, files('../dummy.dat'), 'config2-2.h'],
+ install_dir : 'share/appdirok')
+run_command(check_file, join_paths(meson.current_build_dir(), 'config2-2.h'))
+
+# Configure in subdir with string templates for input and output
+configure_file(input : '../dummy.dat',
+ output : 'config2-3.h',
+ command : [found_script, '@INPUT@', '@OUTPUT@'])
+run_command(check_file, join_paths(meson.current_build_dir(), 'config2-3.h'))