aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/build.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/build.py')
-rw-r--r--mesonbuild/build.py125
1 files changed, 89 insertions, 36 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 2b4b1b9..4fb977e 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1413,8 +1413,15 @@ class Generator:
relpath = pathlib.PurePath(trial).relative_to(parent)
return relpath.parts[0] != '..' # For subdirs we can only go "down".
- def process_files(self, name, files, state, preserve_path_from=None, extra_args=None):
- output = GeneratedList(self, state.subdir, preserve_path_from, extra_args=extra_args if extra_args is not None else [])
+ def process_files(self, name, files, state, *,
+ preserve_path_from=None,
+ extra_args=None,
+ owning_gentarget=None):
+ output = GeneratedList(self,
+ state.subdir,
+ preserve_path_from=preserve_path_from,
+ extra_args=extra_args if extra_args is not None else [],
+ owning_gentarget=owning_gentarget)
for f in files:
if isinstance(f, str):
f = File.from_source_file(state.environment.source_dir, state.subdir, f)
@@ -1429,7 +1436,7 @@ class Generator:
class GeneratedList:
- def __init__(self, generator, subdir, preserve_path_from=None, extra_args=None):
+ def __init__(self, generator, subdir, *, preserve_path_from=None, extra_args=None, owning_gentarget=None):
self.generator = unholder(generator)
self.name = self.generator.exe
self.subdir = subdir
@@ -1448,6 +1455,11 @@ class GeneratedList:
# Can only add a dependency on an external program which we
# know the absolute path of
self.depend_files.append(File.from_absolute_file(path))
+ # If None, this generated list is of the old freestanding type.
+ # Its output goes in the target private directory. Otherwise it is
+ # the outcome of a generator_target and the output goes in its
+ # output dir.
+ self.owning_gentarget = owning_gentarget
def add_preserved_path_segment(self, infile, outfiles, state):
result = []
@@ -1993,8 +2005,41 @@ class SharedModule(SharedLibrary):
def get_default_install_dir(self, environment):
return environment.get_shared_module_dir()
+class CustomMixin:
+ def __init__(self, *args, **kwargs):
+ self.dependencies = []
+ self.extra_depends = []
+ self.depend_files = [] # Files that this target depends on but are not on the command line.
+ self.depfile = None
-class CustomTarget(Target):
+ def flatten_command(self, cmd):
+ cmd = unholder(listify(cmd))
+ final_cmd = []
+ for c in cmd:
+ if isinstance(c, str):
+ final_cmd.append(c)
+ elif isinstance(c, File):
+ self.depend_files.append(c)
+ final_cmd.append(c)
+ elif isinstance(c, dependencies.ExternalProgram):
+ if not c.found():
+ raise InvalidArguments('Tried to use not-found external program in "command"')
+ path = c.get_path()
+ if os.path.isabs(path):
+ # Can only add a dependency on an external program which we
+ # know the absolute path of
+ self.depend_files.append(File.from_absolute_file(path))
+ 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
+
+class CustomTarget(Target, CustomMixin):
known_kwargs = set([
'input',
'output',
@@ -2016,11 +2061,8 @@ class CustomTarget(Target):
def __init__(self, name, subdir, subproject, kwargs, absolute_paths=False, backend=None):
self.typename = 'custom'
# TODO expose keyword arg to make MachineChoice.HOST configurable
- super().__init__(name, subdir, subproject, False, MachineChoice.HOST)
- self.dependencies = []
- self.extra_depends = []
- self.depend_files = [] # Files that this target depends on but are not on the command line.
- self.depfile = None
+ Target.__init__(self, name, subdir, subproject, False, MachineChoice.HOST)
+ CustomMixin.__init__(self)
self.process_kwargs(kwargs, backend)
self.extra_files = []
# Whether to use absolute paths for all files on the commandline
@@ -2065,33 +2107,6 @@ class CustomTarget(Target):
bdeps.update(d.get_transitive_build_target_deps())
return bdeps
- def flatten_command(self, cmd):
- cmd = unholder(listify(cmd))
- final_cmd = []
- for c in cmd:
- if isinstance(c, str):
- final_cmd.append(c)
- elif isinstance(c, File):
- self.depend_files.append(c)
- final_cmd.append(c)
- elif isinstance(c, dependencies.ExternalProgram):
- if not c.found():
- raise InvalidArguments('Tried to use not-found external program in "command"')
- path = c.get_path()
- if os.path.isabs(path):
- # Can only add a dependency on an external program which we
- # know the absolute path of
- self.depend_files.append(File.from_absolute_file(path))
- 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, backend):
self.process_kwargs_base(kwargs)
self.sources = unholder(extract_as_list(kwargs, 'input'))
@@ -2261,6 +2276,44 @@ class CustomTarget(Target):
for i in self.outputs:
yield CustomTargetIndex(self, i)
+class GeneratorTarget(Target, CustomMixin):
+
+ def __init__(self, name, state, kwargs, backend=None):
+ self.typename = 'gent'
+ Target.__init__(self, name, state.subdir, state.subproject, False, MachineChoice.HOST)
+ CustomMixin.__init__(self)
+ self.sources = unholder(extract_as_list(kwargs, 'input'))
+ self.process_kwargs(kwargs, backend)
+ self.extra_files = []
+ self.output = self.generator.process_files('GeneratorTarget',
+ self.sources,
+ state,
+ owning_gentarget=self)
+ assert(isinstance(self.output, GeneratedList))
+
+ def __repr__(self):
+ repr_str = "<{0} {1}: {2}>"
+ return repr_str.format(self.__class__.__name__, self.get_id(), self.command)
+
+ def type_suffix(self):
+ return "@gta"
+
+ def get_dependencies(self):
+ return self.dependencies
+
+ def process_kwargs(self, kwargs, backend):
+ if 'generator' not in kwargs:
+ raise InvalidArguments('Missing keyword argument "command".')
+ self.generator = unholder(kwargs['generator'])
+ if not isinstance(self.generator, Generator):
+ raise InvalidArguments("Generator argument is not a generator object.")
+
+ def should_install(self):
+ return False
+
+ def get_outputs(self):
+ return []
+
class RunTarget(Target):
def __init__(self, name, command, args, dependencies, subdir, subproject):
self.typename = 'run'