From dae986073d5ab3a6241cecaf3362065256400772 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 23 May 2022 16:21:39 +0200 Subject: [PATCH] take override_option('unity=...') into account when allowing extract_objects() A single target could be picked for unity build, and in that case extract_objects() should not be allowed. Likewise for the opposite case, where extract_objects() should be allowed if unity build is disabled for a single target. A test that covers that case is added later. --- mesonbuild/backend/backends.py | 6 +----- mesonbuild/backend/ninjabackend.py | 4 ++-- mesonbuild/backend/vs2010backend.py | 2 +- mesonbuild/build.py | 7 +++++-- test cases/failing/126 extract from unity/meson.build | 4 ++++ test cases/failing/126 extract from unity/src1.c | 3 +++ test cases/failing/126 extract from unity/src2.c | 3 +++ test cases/failing/126 extract from unity/test.json | 7 +++++++ 8 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 test cases/failing/126 extract from unity/meson.build create mode 100644 test cases/failing/126 extract from unity/src1.c create mode 100644 test cases/failing/126 extract from unity/src2.c create mode 100644 test cases/failing/126 extract from unity/test.json diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 8524bf908..fb4163fd3 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -836,7 +836,7 @@ class Backend: # With unity builds, sources don't map directly to objects, # we only support extracting all the objects in this mode, # so just return all object files. - if self.is_unity(extobj.target): + if extobj.target.is_unity: compsrcs = classify_unity_sources(extobj.target.compilers.values(), sources) sources = [] unity_size = extobj.target.get_option(OptionKey('unity_size')) @@ -1280,10 +1280,6 @@ class Backend: libs.extend(self.get_custom_target_provided_by_generated_source(t)) return libs - def is_unity(self, target: build.BuildTarget) -> bool: - optval = target.get_option(OptionKey('unity')) - return optval == 'on' or (optval == 'subprojects' and target.subproject != '') - def get_custom_target_sources(self, target: build.CustomTarget) -> T.List[str]: ''' Custom target sources can be of various object types; strings, File, diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index bcc4c535b..c61b98956 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -792,7 +792,7 @@ class NinjaBackend(backends.Backend): # Generate rules for building the remaining source files in this target outname = self.get_target_filename(target) obj_list = [] - is_unity = self.is_unity(target) + is_unity = target.is_unity header_deps = [] unity_src = [] unity_deps = [] # Generated sources that must be built before compiling a Unity target. @@ -1527,7 +1527,7 @@ class NinjaBackend(backends.Backend): # Outputted header hname = os.path.join(self.get_target_dir(target), target.vala_header) args += ['--header', hname] - if self.is_unity(target): + if target.is_unity: # Without this the declarations will get duplicated in the .c # files and cause a build failure when all of them are # #include-d in one .c file. diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 32800b5a0..f8472da2c 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -878,7 +878,7 @@ class Vs2010Backend(backends.Backend): # Prefix to use to access the source tree's subdir from the vcxproj dir proj_to_src_dir = os.path.join(proj_to_src_root, self.get_target_dir(target)) (sources, headers, objects, languages) = self.split_sources(target.sources) - if self.is_unity(target): + if target.is_unity: sources = self.generate_unity_files(target, sources) compiler = self._get_cl_compiler(target) build_args = compiler.get_buildtype_args(self.buildtype) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index ceff2964b..d312abdda 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -753,8 +753,6 @@ class BuildTarget(Target): sources: T.List['SourceOutputs'], structured_sources: T.Optional[StructuredSources], objects, environment: environment.Environment, compilers: T.Dict[str, 'Compiler'], kwargs): super().__init__(name, subdir, subproject, True, for_machine, environment) - unity_opt = environment.coredata.get_option(OptionKey('unity')) - self.is_unity = unity_opt == 'on' or (unity_opt == 'subprojects' and subproject != '') self.all_compilers = compilers self.compilers = OrderedDict() # type: OrderedDict[str, Compiler] self.objects: T.List[T.Union[str, 'File', 'ExtractedObjects']] = [] @@ -810,6 +808,11 @@ class BuildTarget(Target): def __str__(self): return f"{self.name}" + @property + def is_unity(self) -> bool: + unity_opt = self.get_option(OptionKey('unity')) + return unity_opt == 'on' or (unity_opt == 'subprojects' and self.subproject != '') + def validate_install(self): if self.for_machine is MachineChoice.BUILD and self.need_install: if self.environment.is_cross_build(): diff --git a/test cases/failing/126 extract from unity/meson.build b/test cases/failing/126 extract from unity/meson.build new file mode 100644 index 000000000..9e3e65f58 --- /dev/null +++ b/test cases/failing/126 extract from unity/meson.build @@ -0,0 +1,4 @@ +project('extract nonexisting gen', 'c') + +lib1 = library('lib1', 'src1.c', 'src2.c', override_options: ['unity=on']) +lib2 = library('lib2', objects: lib1.extract_objects('src1.c')) diff --git a/test cases/failing/126 extract from unity/src1.c b/test cases/failing/126 extract from unity/src1.c new file mode 100644 index 000000000..da971bbf6 --- /dev/null +++ b/test cases/failing/126 extract from unity/src1.c @@ -0,0 +1,3 @@ +int sub_lib_method1() { + return 1337; +} diff --git a/test cases/failing/126 extract from unity/src2.c b/test cases/failing/126 extract from unity/src2.c new file mode 100644 index 000000000..a46166933 --- /dev/null +++ b/test cases/failing/126 extract from unity/src2.c @@ -0,0 +1,3 @@ +int sub_lib_method2() { + return 1337; +} diff --git a/test cases/failing/126 extract from unity/test.json b/test cases/failing/126 extract from unity/test.json new file mode 100644 index 000000000..9f3a8d88e --- /dev/null +++ b/test cases/failing/126 extract from unity/test.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + { + "line": "test cases/failing/126 extract from unity/meson.build:4:0: ERROR: Single object files can not be extracted in Unity builds. You can only extract all the object files for each compiler at once." + } + ] +}