aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2017-02-15 21:26:31 +0530
committerJussi Pakkanen <jpakkane@gmail.com>2017-02-17 15:42:12 -0500
commit15b6915954c7c3d7a06455aeb7995524ac43ff3b (patch)
tree13d44490c03fe116e5961ec80f82c22f3cf25bd8
parent16adedf6bc941745d3f10a2ad70fe710dfe1b206 (diff)
downloadmeson-15b6915954c7c3d7a06455aeb7995524ac43ff3b.zip
meson-15b6915954c7c3d7a06455aeb7995524ac43ff3b.tar.gz
meson-15b6915954c7c3d7a06455aeb7995524ac43ff3b.tar.bz2
custom_target: Recursively flatten `command:`
Without this, files() in the arguments give an error because it's a list of mesonlib.File objects: Array as argument 1 contains a non-string. It also breaks in nested lists. Includes a test for this.
-rw-r--r--mesonbuild/build.py50
-rw-r--r--test cases/common/56 custom target/meson.build4
-rwxr-xr-xtest cases/common/56 custom target/my_compiler.py15
3 files changed, 37 insertions, 32 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 5466431..5f2de3b 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1298,6 +1298,29 @@ class CustomTarget(Target):
deps.append(c)
return deps
+ def flatten_command(self, cmd):
+ if not isinstance(cmd, list):
+ cmd = [cmd]
+ final_cmd = []
+ for c in cmd:
+ if hasattr(c, 'held_object'):
+ c = c.held_object
+ if isinstance(c, (str, File)):
+ final_cmd.append(c)
+ elif isinstance(c, dependencies.ExternalProgram):
+ if not c.found():
+ m = 'Tried to use not-found external program {!r} in "command"'
+ raise InvalidArguments(m.format(c.name))
+ final_cmd += c.get_command()
+ elif isinstance(c, (BuildTarget, CustomTarget)):
+ self.dependencies.append(c)
+ final_cmd.append(c)
+ elif isinstance(c, list):
+ final_cmd += self.flatten_command(c)
+ else:
+ raise InvalidArguments('Argument {!r} in "command" is invalid'.format(c))
+ return final_cmd
+
def process_kwargs(self, kwargs):
super().process_kwargs(kwargs)
self.sources = kwargs.get('input', [])
@@ -1325,32 +1348,7 @@ class CustomTarget(Target):
if os.path.split(depfile)[1] != depfile:
raise InvalidArguments('Depfile must be a plain filename without a subdirectory.')
self.depfile = depfile
- cmd = kwargs['command']
- if not(isinstance(cmd, list)):
- cmd = [cmd]
- final_cmd = []
- for i, c in enumerate(cmd):
- if hasattr(c, 'held_object'):
- c = c.held_object
- if isinstance(c, (str, File)):
- final_cmd.append(c)
- elif isinstance(c, dependencies.ExternalProgram):
- if not c.found():
- raise InvalidArguments('Tried to use not found external program {!r} in a build rule.'.format(c.name))
- final_cmd += c.get_command()
- elif isinstance(c, (BuildTarget, CustomTarget)):
- self.dependencies.append(c)
- final_cmd.append(c)
- elif isinstance(c, list):
- # Hackety hack, only supports one level of flattening. Should really
- # work to arbtrary depth.
- for s in c:
- if not isinstance(s, str):
- raise InvalidArguments('Array as argument %d contains a non-string.' % i)
- final_cmd.append(s)
- else:
- raise InvalidArguments('Argument %s in "command" is invalid.' % i)
- self.command = final_cmd
+ self.command = self.flatten_command(kwargs['command'])
if self.capture:
for c in self.command:
if isinstance(c, str) and '@OUTPUT@' in c:
diff --git a/test cases/common/56 custom target/meson.build b/test cases/common/56 custom target/meson.build
index fd59fbd..2e6f69c 100644
--- a/test cases/common/56 custom target/meson.build
+++ b/test cases/common/56 custom target/meson.build
@@ -8,11 +8,13 @@ endif
# Note that this will not add a dependency to the compiler executable.
# Code will not be rebuilt if it changes.
comp = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler.py')
+# Test that files() in command: works. The compiler just discards it.
+useless = files('installed_files.txt')
mytarget = custom_target('bindat',
output : 'data.dat',
input : 'data_source.txt',
-command : [python, comp, '--input=@INPUT@', '--output=@OUTPUT@'],
+command : [python, comp, '--input=@INPUT@', '--output=@OUTPUT@', useless],
install : true,
install_dir : 'subdir'
)
diff --git a/test cases/common/56 custom target/my_compiler.py b/test cases/common/56 custom target/my_compiler.py
index 4ba2da6..f46d23a 100755
--- a/test cases/common/56 custom target/my_compiler.py
+++ b/test cases/common/56 custom target/my_compiler.py
@@ -1,16 +1,21 @@
#!/usr/bin/env python3
+import os
import sys
+assert(os.path.exists(sys.argv[3]))
+
+args = sys.argv[:-1]
+
if __name__ == '__main__':
- if len(sys.argv) != 3 or not sys.argv[1].startswith('--input') or \
- not sys.argv[2].startswith('--output'):
- print(sys.argv[0], '--input=input_file --output=output_file')
+ if len(args) != 3 or not args[1].startswith('--input') or \
+ not args[2].startswith('--output'):
+ print(args[0], '--input=input_file --output=output_file')
sys.exit(1)
- with open(sys.argv[1].split('=')[1]) as f:
+ with open(args[1].split('=')[1]) as f:
ifile = f.read()
if ifile != 'This is a text only input file.\n':
print('Malformed input')
sys.exit(1)
- with open(sys.argv[2].split('=')[1], 'w') as ofile:
+ with open(args[2].split('=')[1], 'w') as ofile:
ofile.write('This is a binary output file.\n')