interpreter: Iterate custom target outputs

pull/6587/head
Xavier Claessens 5 years ago committed by Jussi Pakkanen
parent 8d68fa22e0
commit 15eb0014ac
  1. 6
      docs/markdown/Reference-manual.md
  2. 4
      mesonbuild/build.py
  3. 27
      mesonbuild/interpreter.py
  4. 13
      test cases/common/144 custom target multiple outputs/meson.build

@ -2299,6 +2299,8 @@ contains a target with the following methods:
NOTE: In most cases using the object itself will do the same job as NOTE: In most cases using the object itself will do the same job as
this and will also allow Meson to setup inter-target dependencies this and will also allow Meson to setup inter-target dependencies
correctly. Please file a bug if that doesn't work for you. correctly. Please file a bug if that doesn't work for you.
*Since 0.54.0* it can be also called on indexes objects:
`custom_targets[i].full_path()`.
- `[index]` returns an opaque object that references this target, and - `[index]` returns an opaque object that references this target, and
can be used as a source in other targets. When it is used as such it can be used as a source in other targets. When it is used as such it
@ -2306,6 +2308,10 @@ contains a target with the following methods:
source added will be the one that corresponds to the index of the source added will be the one that corresponds to the index of the
custom target's output argument. custom target's output argument.
- `to_list()` *Since 0.54.0*, returns a list of opaque objects that references
this target, and can be used as a source in other targets. This can be used to
iterate outputs with `foreach` loop.
### `dependency` object ### `dependency` object
This object is returned by [`dependency()`](#dependency) and contains This object is returned by [`dependency()`](#dependency) and contains

@ -2250,6 +2250,10 @@ class CustomTarget(Target):
def __delitem__(self, index): def __delitem__(self, index):
raise NotImplementedError raise NotImplementedError
def __iter__(self):
for i in self.outputs:
yield CustomTargetIndex(self, i)
class RunTarget(Target): class RunTarget(Target):
def __init__(self, name, command, args, dependencies, subdir, subproject): def __init__(self, name, command, args, dependencies, subdir, subproject):
self.typename = 'run' self.typename = 'run'

@ -871,15 +871,23 @@ class JarHolder(BuildTargetHolder):
def __init__(self, target, interp): def __init__(self, target, interp):
super().__init__(target, interp) super().__init__(target, interp)
class CustomTargetIndexHolder(InterpreterObject, ObjectHolder): class CustomTargetIndexHolder(TargetHolder):
def __init__(self, object_to_hold): def __init__(self, target, interp):
InterpreterObject.__init__(self) super().__init__(target, interp)
ObjectHolder.__init__(self, object_to_hold) self.methods.update({'full_path': self.full_path_method,
})
@FeatureNew('custom_target[i].full_path', '0.54.0')
@noPosargs
@permittedKwargs({})
def full_path_method(self, args, kwargs):
return self.interpreter.backend.get_target_filename_abs(self.held_object)
class CustomTargetHolder(TargetHolder): class CustomTargetHolder(TargetHolder):
def __init__(self, target, interp): def __init__(self, target, interp):
super().__init__(target, interp) super().__init__(target, interp)
self.methods.update({'full_path': self.full_path_method, self.methods.update({'full_path': self.full_path_method,
'to_list': self.to_list_method,
}) })
def __repr__(self): def __repr__(self):
@ -892,8 +900,17 @@ class CustomTargetHolder(TargetHolder):
def full_path_method(self, args, kwargs): def full_path_method(self, args, kwargs):
return self.interpreter.backend.get_target_filename_abs(self.held_object) return self.interpreter.backend.get_target_filename_abs(self.held_object)
@FeatureNew('custom_target.to_list', '0.54.0')
@noPosargs
@permittedKwargs({})
def to_list_method(self, args, kwargs):
result = []
for i in self.held_object:
result.append(CustomTargetIndexHolder(i, self.interpreter))
return result
def __getitem__(self, index): def __getitem__(self, index):
return CustomTargetIndexHolder(self.held_object[index]) return CustomTargetIndexHolder(self.held_object[index], self.interpreter)
def __setitem__(self, index, value): # lgtm[py/unexpected-raise-in-special-method] def __setitem__(self, index, value): # lgtm[py/unexpected-raise-in-special-method]
raise InterpreterException('Cannot set a member of a CustomTarget') raise InterpreterException('Cannot set a member of a CustomTarget')

@ -21,8 +21,19 @@ custom_target('only-install-first',
install : true, install : true,
install_dir : [join_paths(get_option('prefix'), get_option('includedir')), false]) install_dir : [join_paths(get_option('prefix'), get_option('includedir')), false])
custom_target('only-install-second', targets = custom_target('only-install-second',
output : ['second.h', 'second.sh'], output : ['second.h', 'second.sh'],
command : [gen, 'second', '@OUTDIR@'], command : [gen, 'second', '@OUTDIR@'],
install : true, install : true,
install_dir : [false, join_paths(get_option('prefix'), get_option('bindir'))]) install_dir : [false, join_paths(get_option('prefix'), get_option('bindir'))])
paths = []
foreach i : targets.to_list()
paths += i.full_path()
endforeach
# Skip on Windows because paths are not identical, '/' VS '\'.
if host_machine.system() != 'windows'
assert(paths == [meson.current_build_dir() / 'second.h',
meson.current_build_dir() / 'second.sh'])
endif

Loading…
Cancel
Save