custom_target: Substitute input into output

This means replacing @PLAINNAME@ and @BASENAME@ in the outputs. This is
the same feature as generator().

This is only allowed when there is only one input file for obvious
reasons + failing test for this.
pull/1403/head
Nirbheek Chauhan 8 years ago
parent 73b2ee08a8
commit f3ff8fe6b7
  1. 20
      mesonbuild/build.py
  2. 2
      test cases/common/118 allgenerate/meson.build
  3. 1
      test cases/failing/42 custom target plainname many inputs/1.txt
  4. 1
      test cases/failing/42 custom target plainname many inputs/2.txt
  5. 9
      test cases/failing/42 custom target plainname many inputs/catfiles.py
  6. 8
      test cases/failing/42 custom target plainname many inputs/meson.build

@ -16,7 +16,9 @@ from . import environment
from . import dependencies
from . import mlog
import copy, os, re
from .mesonlib import File, flatten, MesonException, stringlistify, classify_unity_sources
from .mesonlib import File, MesonException
from .mesonlib import flatten, stringlistify, classify_unity_sources
from .mesonlib import get_filenames_templates_dict, substitute_values
from .environment import for_windows, for_darwin
from .compilers import is_object, clike_langs, lang_suffixes
@ -1331,11 +1333,25 @@ class CustomTarget(Target):
self.output = kwargs['output']
if not isinstance(self.output, list):
self.output = [self.output]
# This will substitute values from the input into output and return it.
inputs = get_sources_string_names(self.sources)
values = get_filenames_templates_dict(inputs, [])
for i in self.output:
if not(isinstance(i, str)):
raise InvalidArguments('Output argument not a string.')
if '/' in i:
raise InvalidArguments('Output must not contain a path segment.')
if '@INPUT@' in i or '@INPUT0@' in i:
m = 'Output cannot contain @INPUT@ or @INPUT0@, did you ' \
'mean @PLAINNAME@ or @BASENAME@?'
raise InvalidArguments(m)
# We already check this during substitution, but the error message
# will be unclear/confusing, so check it here.
if len(inputs) != 1 and ('@PLAINNAME@' in i or '@BASENAME@' in i):
m = "Output cannot contain @PLAINNAME@ or @BASENAME@ when " \
"there is more than one input (we can't know which to use)"
raise InvalidArguments(m)
self.output = substitute_values(self.output, values)
self.capture = kwargs.get('capture', False)
if self.capture and len(self.output) != 1:
raise InvalidArguments('Capturing can only output to a single file.')
@ -1531,7 +1547,7 @@ class TestSetup:
self.timeout_multiplier = timeout_multiplier
self.env = env
def get_sources_output_names(sources):
def get_sources_string_names(sources):
'''
For the specified list of @sources which can be strings, Files, or targets,
get all the output basenames.

@ -13,7 +13,7 @@ c = g.process('foobar.cpp.in')
prog = executable('genexe', c)
c2 = custom_target('c2gen',
output : 'c2gen.cpp',
output : '@BASENAME@',
input : 'foobar.cpp.in',
command : [comp, '@INPUT@', '@OUTPUT@'])

@ -0,0 +1,9 @@
#!/usr/bin/env python3
import sys
out = sys.argv[-1]
with open(out, 'wb') as o:
for infile in sys.argv[1:-1]:
with open(infile, 'rb') as f:
o.write(f.read())

@ -0,0 +1,8 @@
project('plain name many inputs', 'c')
catfiles = find_program('catfiles.py')
custom_target('plainname-inputs',
input : ['1.txt', '2.txt'],
output : '@PLAINNAME@.dat',
command : [catfiles, '@INPUT@', '@OUTPUT@'])
Loading…
Cancel
Save