From f431cff809ec7159c26792e96055747c724e669c Mon Sep 17 00:00:00 2001 From: Rachel Mant Date: Sat, 17 Aug 2019 19:12:56 +0100 Subject: [PATCH] Make .extract_objects() work correctly as an input to custom_target --- mesonbuild/backend/backends.py | 2 ++ mesonbuild/build.py | 19 ++++++++++++++----- mesonbuild/interpreter.py | 5 +++-- .../check_object.py | 13 +++++++++++++ .../libdir/meson.build | 1 + .../libdir/source.c | 3 +++ .../meson.build | 13 +++++++++++++ 7 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 test cases/common/223 custom target input extracted objects/check_object.py create mode 100644 test cases/common/223 custom target input extracted objects/libdir/meson.build create mode 100644 test cases/common/223 custom target input extracted objects/libdir/source.c create mode 100644 test cases/common/223 custom target input extracted objects/meson.build diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 8c2752a77..40f94118d 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -918,6 +918,8 @@ class Backend: fname = [os.path.join(self.get_target_dir(i), p) for p in i.get_outputs()] elif isinstance(i, build.GeneratedList): fname = [os.path.join(self.get_target_private_dir(target), p) for p in i.get_outputs()] + elif isinstance(i, build.ExtractedObjects): + fname = [os.path.join(self.get_target_private_dir(i.target), p) for p in i.get_outputs(self)] else: fname = [i.rel_to_builddir(self.build_to_src)] if target.absolute_paths: diff --git a/mesonbuild/build.py b/mesonbuild/build.py index b77995ac2..eab205711 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -278,6 +278,13 @@ class ExtractedObjects: 'in Unity builds. You can only extract all ' 'the object files for each compiler at once.') + def get_outputs(self, backend): + # TODO: Consider if we need to handle genlist here + return [ + backend.object_filename_from_source(self.target, source) + for source in self.srclist + ] + class EnvironmentVariables: def __init__(self): self.envvars = [] @@ -1911,7 +1918,7 @@ class CustomTarget(Target): 'console', ]) - def __init__(self, name, subdir, subproject, kwargs, absolute_paths=False): + 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) @@ -1919,7 +1926,7 @@ class CustomTarget(Target): self.extra_depends = [] self.depend_files = [] # Files that this target depends on but are not on the command line. self.depfile = None - self.process_kwargs(kwargs) + self.process_kwargs(kwargs, backend) self.extra_files = [] # Whether to use absolute paths for all files on the commandline self.absolute_paths = absolute_paths @@ -1996,14 +2003,14 @@ class CustomTarget(Target): raise InvalidArguments('Argument {!r} in "command" is invalid'.format(c)) return final_cmd - def process_kwargs(self, kwargs): + def process_kwargs(self, kwargs, backend): super().process_kwargs(kwargs) self.sources = extract_as_list(kwargs, 'input', unholder=True) if 'output' not in kwargs: raise InvalidArguments('Missing keyword argument "output".') self.outputs = listify(kwargs['output']) # This will substitute values from the input into output and return it. - inputs = get_sources_string_names(self.sources) + inputs = get_sources_string_names(self.sources, backend) values = get_filenames_templates_dict(inputs, []) for i in self.outputs: if not(isinstance(i, str)): @@ -2370,7 +2377,7 @@ class TestSetup: self.timeout_multiplier = timeout_multiplier self.env = env -def get_sources_string_names(sources): +def get_sources_string_names(sources, backend): ''' For the specified list of @sources which can be strings, Files, or targets, get all the output basenames. @@ -2383,6 +2390,8 @@ def get_sources_string_names(sources): names.append(s) elif isinstance(s, (BuildTarget, CustomTarget, CustomTargetIndex, GeneratedList)): names += s.get_outputs() + elif isinstance(s, ExtractedObjects): + names += s.get_outputs(backend) elif isinstance(s, File): names.append(s.fname) else: diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index dad15cfbb..c10297879 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -3314,7 +3314,7 @@ external dependencies (including libraries) must go to "dependencies".''') except mesonlib.MesonException: mlog.warning('''Custom target input \'%s\' can\'t be converted to File object(s). This will become a hard error in the future.''' % kwargs['input'], location=self.current_node) - tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, self.subproject, kwargs), self) + tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, self.subproject, kwargs, backend=self.backend), self) self.add_target(name, tg.held_object) return tg @@ -4058,7 +4058,8 @@ Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_s sources = [sources] for s in sources: if isinstance(s, (mesonlib.File, GeneratedListHolder, - TargetHolder, CustomTargetIndexHolder)): + TargetHolder, CustomTargetIndexHolder, + GeneratedObjectsHolder)): pass elif isinstance(s, str): self.validate_within_subproject(self.subdir, s) diff --git a/test cases/common/223 custom target input extracted objects/check_object.py b/test cases/common/223 custom target input extracted objects/check_object.py new file mode 100644 index 000000000..bafcf2c17 --- /dev/null +++ b/test cases/common/223 custom target input extracted objects/check_object.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import sys, os + +if __name__ == '__main__': + if len(sys.argv) != 3: + print(sys.argv[0], 'object', 'output') + sys.exit(1) + elif os.path.exists(sys.argv[1]): + with open(sys.argv[2], 'wb') as out: + pass + else: + sys.exit(1) diff --git a/test cases/common/223 custom target input extracted objects/libdir/meson.build b/test cases/common/223 custom target input extracted objects/libdir/meson.build new file mode 100644 index 000000000..7f833115c --- /dev/null +++ b/test cases/common/223 custom target input extracted objects/libdir/meson.build @@ -0,0 +1 @@ +objlib = static_library('object', 'source.c', override_options : ['unity=off']) diff --git a/test cases/common/223 custom target input extracted objects/libdir/source.c b/test cases/common/223 custom target input extracted objects/libdir/source.c new file mode 100644 index 000000000..7779b332c --- /dev/null +++ b/test cases/common/223 custom target input extracted objects/libdir/source.c @@ -0,0 +1,3 @@ +int func1_in_obj() { + return 0; +} diff --git a/test cases/common/223 custom target input extracted objects/meson.build b/test cases/common/223 custom target input extracted objects/meson.build new file mode 100644 index 000000000..579308c66 --- /dev/null +++ b/test cases/common/223 custom target input extracted objects/meson.build @@ -0,0 +1,13 @@ +project('custom target input extracted objects', 'c') + +checker = find_program('check_object.py') + +cc = meson.get_compiler('c').cmd_array().get(-1) + +subdir('libdir') + +custom_target('check', + input: objlib.extract_objects('source.c'), + output: 'objcheck', + command: [checker, '@INPUT@', '@OUTPUT@'], + build_by_default: true)