Implement capture for generators

pull/2395/head
Niklas Claesson 8 years ago committed by Jussi Pakkanen
parent c93bce7839
commit 68275b32e8
  1. 3
      docs/markdown/Reference-manual.md
  2. 4
      docs/markdown/Release-notes-for-0.43.0/001-generator-capture.md
  3. 15
      mesonbuild/backend/ninjabackend.py
  4. 10
      mesonbuild/backend/vs2010backend.py
  5. 6
      mesonbuild/build.py
  6. 2
      mesonbuild/interpreter.py
  7. 10
      test cases/common/98 gen extra/meson.build
  8. 16
      test cases/common/98 gen extra/srcgen3.py

@ -554,6 +554,9 @@ following:
- `output` a template string (or list of template strings) defining
how an output file name is (or multiple output names are) generated
from a single source file name
- `capture` when this argument is set to true, Meson captures `stdout`
of the `executable` and writes it to the target file specified as
`output`. Available since v0.43.0.
The returned object also has methods that are documented in the
[object methods section](#generator-object) below.

@ -0,0 +1,4 @@
## Generator learned capture
Generators can now be configured to capture the standard output. See
`test cases/common/98 gen extra/meson.build` for an example.

@ -1814,6 +1814,19 @@ rule FORTRAN_DEP_HACK
relout = self.get_target_private_dir(target)
args = self.replace_paths(target, args)
cmdlist = exe_arr + self.replace_extra_args(args, genlist)
if generator.capture:
exe_data = self.serialize_executable(
cmdlist[0],
cmdlist[1:],
self.environment.get_build_dir(),
capture=outfiles[0]
)
cmd = self.environment.get_build_command() + ['--internal', 'exe', exe_data]
abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
os.makedirs(abs_pdir, exist_ok=True)
else:
cmd = cmdlist
elem = NinjaBuildElement(self.all_outputs, outfiles, rulename, infilename)
if generator.depfile is not None:
elem.add_item('DEPFILE', depfile)
@ -1822,7 +1835,7 @@ rule FORTRAN_DEP_HACK
elem.add_item('DESC', 'Generating {!r}.'.format(sole_output))
if isinstance(exe, build.BuildTarget):
elem.add_dep(self.get_target_filename(exe))
elem.add_item('COMMAND', cmdlist)
elem.add_item('COMMAND', cmd)
elem.write(outfile)
def scan_fortran_module_outputs(self, target):

@ -128,6 +128,16 @@ class Vs2010Backend(backends.Backend):
.replace("@BUILD_ROOT@", self.environment.get_build_dir())
for x in args]
cmd = exe_arr + self.replace_extra_args(args, genlist)
if generator.capture:
exe_data = self.serialize_executable(
cmd[0],
cmd[1:],
self.environment.get_build_dir(),
capture=outfiles[0]
)
cmd = self.environment.get_build_command() + ['--internal', 'exe', exe_data]
abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
os.makedirs(abs_pdir, exist_ok=True)
cbs = ET.SubElement(idgroup, 'CustomBuild', Include=infilename)
ET.SubElement(cbs, 'Command').text = ' '.join(self.quote_arguments(cmd))
ET.SubElement(cbs, 'Outputs').text = ';'.join(outfiles)

@ -1019,6 +1019,7 @@ class Generator:
raise InvalidArguments('First generator argument must be an executable.')
self.exe = exe
self.depfile = None
self.capture = False
self.process_kwargs(kwargs)
def __repr__(self):
@ -1062,6 +1063,11 @@ class Generator:
if os.path.split(depfile)[1] != depfile:
raise InvalidArguments('Depfile must be a plain filename without a subdirectory.')
self.depfile = depfile
if 'capture' in kwargs:
capture = kwargs['capture']
if not isinstance(capture, bool):
raise InvalidArguments('Capture must be boolean.')
self.capture = capture
def get_base_outnames(self, inname):
plainname = os.path.split(inname)[1]

@ -1335,7 +1335,7 @@ permitted_kwargs = {'add_global_arguments': {'language'},
'declare_dependency': {'include_directories', 'link_with', 'sources', 'dependencies', 'compile_args', 'link_args', 'version'},
'executable': exe_kwargs,
'find_program': {'required', 'native'},
'generator': {'arguments', 'output', 'depfile'},
'generator': {'arguments', 'output', 'depfile', 'capture'},
'include_directories': {'is_system'},
'install_data': {'install_dir', 'install_mode', 'sources'},
'install_headers': {'install_dir', 'subdir'},

@ -28,3 +28,13 @@ plainname_gen = generator(prog2,
plainname_src = plainname_gen.process('name.l')
test('plainname', executable('plainname', plainname_src))
prog3 = find_program('srcgen3.py')
capture_gen = generator(prog3,
output : ['@BASENAME@.yy.c'],
arguments : ['@INPUT@'],
capture : true)
capture_src = capture_gen.process('name.l')
test('capture', executable('capture', capture_src))

@ -0,0 +1,16 @@
#!/usr/bin/env python3
import os
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('input',
help='the input file')
options = parser.parse_args(sys.argv[1:])
with open(options.input) as f:
content = f.read().strip()
print(content)
Loading…
Cancel
Save