Merge pull request #1874 from rindeal/configure_file-capture

add `capture: true` ability to configure_file()
pull/1918/head
Jussi Pakkanen 8 years ago committed by GitHub
commit 3ced977547
  1. 1
      docs/markdown/Reference-manual.md
  2. 6
      docs/markdown/Release-notes-for-0.41.0.md
  3. 13
      mesonbuild/interpreter.py
  4. 28
      test cases/common/16 configure file/basename.py
  5. 22
      test cases/common/16 configure file/file_contains.py
  6. 17
      test cases/common/16 configure file/meson.build
  7. 16
      test cases/common/16 configure file/touch.py

@ -127,6 +127,7 @@ These are all the supported keyword arguments:
- `output` the output file name (since v0.41.0, may contain `@PLAINNAME@` or `@BASENAME@` substitutions). In configuration mode, the permissions of the input file (if it is specified) are copied to the output file.
- `configuration` as explained above, this is where you pass the configuration data object as returned by `configuration_data()`
- `command` as explained above, if specified, Meson does not create the file itself but rather runs the specified command, which allows you to do fully custom file generation
- `capture` when this argument is set to true, Meson captures `stdout` of the `command` and writes it to the target file specified as `output`. Available since v0.41.0.
- `install_dir` the subdirectory to install the generated file to (e.g. `share/myproject`), if omitted the file is not installed.
### custom_target()

@ -80,3 +80,9 @@ but actually isn't. For example when:
- `build_machine` is macOS and `host_machine` is the iOS Simulator
- the `build_machine`'s libc is glibc but the `host_machine` libc is uClibc
- code relies on kernel features not available on the `build_machine`
## Support for capturing stdout of a command in configure_file
`configure_file()` now supports a new keyword - `capture`. When this argument
is set to true, Meson captures `stdout` of the `command` and writes it to
the target file specified as `output`.

@ -2319,6 +2319,12 @@ class Interpreter(InterpreterBase):
raise InterpreterException('Must not specify both "configuration" '
'and "command" keyword arguments since '
'they are mutually exclusive.')
if 'capture' in kwargs:
if not isinstance(kwargs['capture'], bool):
raise InterpreterException('"capture" keyword must be a boolean.')
if 'command' not in kwargs:
raise InterpreterException('"capture" keyword requires "command" keyword.')
# Validate input
inputfile = None
ifile_abs = None
@ -2383,6 +2389,13 @@ class Interpreter(InterpreterBase):
if res.returncode != 0:
raise InterpreterException('Running configure command failed.\n%s\n%s' %
(res.stdout, res.stderr))
if 'capture' in kwargs and kwargs['capture']:
dst_tmp = ofile_abs + '~'
with open(dst_tmp, 'w', encoding='utf-8') as f:
f.writelines(res.stdout)
if ifile_abs:
shutil.copymode(ifile_abs, dst_tmp)
mesonlib.replace_if_different(ofile_abs, dst_tmp)
else:
raise InterpreterException('Configure_file must have either "configuration" or "command".')
idir = kwargs.get('install_dir', None)

@ -0,0 +1,28 @@
#!/usr/bin/env python3
import sys
import argparse
import os
def main():
parser = argparse.ArgumentParser()
parser.add_argument('text', nargs='*', type=str)
args = parser.parse_args()
text = args.text if isinstance(args.text, list) else [args.text]
output = ''
for t in text:
t = os.path.basename(t)
if not output:
output += t
else:
output += ' ' + t
output += '\n'
sys.stdout.write(output)
if __name__ == '__main__':
sys.exit(main())

@ -0,0 +1,22 @@
#!/usr/bin/env python3
import sys
import argparse
def main():
parser = argparse.ArgumentParser()
parser.add_argument('file', nargs=1, type=str)
parser.add_argument('text', nargs=1, type=str)
args = parser.parse_args()
text = args.text[0]
with open(args.file[0], 'r', encoding='utf-8') as f:
for line in f:
if line.strip() == text:
return 0
return 1
if __name__ == '__main__':
sys.exit(main())

@ -86,3 +86,20 @@ foreach config_template : config_templates
endforeach
test('Substituted', executable('prog4', 'prog4.c'))
# Test `capture` keyword
basename_py = find_program('basename.py')
file_contains_py = find_program('file_contains.py')
test_string = 'hello world'
test_input_file = join_paths(meson.current_build_dir(), test_string)
run_command(find_program('touch.py'), test_input_file)
configs = [
# no input
configure_file(command: [ basename_py, test_string ], capture: true, output: 'capture test 1'),
# with input
configure_file(input: test_input_file, command: [ basename_py, '@INPUT@' ], capture: true, output: 'capture test 2'),
]
foreach c : configs
test('@0@'.format(c), file_contains_py, args: [ c, test_string ])
endforeach

@ -0,0 +1,16 @@
#!/usr/bin/env python3
import sys
import argparse
from pathlib import Path
def main():
parser = argparse.ArgumentParser()
parser.add_argument('files', nargs='*', type=str)
args = parser.parse_args()
for filepath in args.files:
Path(filepath).touch()
if __name__ == '__main__':
sys.exit(main())
Loading…
Cancel
Save