From ae783b7642d15d659500a489d1316ddd1d5264d2 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Wed, 31 Jul 2024 16:55:50 +0300 Subject: [PATCH] Fix project tests. --- mesonbuild/coredata.py | 22 ------------- mesonbuild/interpreter/interpreterobjects.py | 9 +++++- mesonbuild/options.py | 34 ++++++++++++++++++-- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 5ea02817380e..f8248fb0023b 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -356,22 +356,6 @@ def builtin_options_libdir_cross_fixup(self) -> None: if self.cross_files: options.BUILTIN_OPTIONS[OptionKey('libdir')].default = 'lib' - def sanitize_prefix(self, prefix: str) -> str: - prefix = os.path.expanduser(prefix) - if not os.path.isabs(prefix): - raise MesonException(f'prefix value {prefix!r} must be an absolute path') - if prefix.endswith('/') or prefix.endswith('\\'): - # On Windows we need to preserve the trailing slash if the - # string is of type 'C:\' because 'C:' is not an absolute path. - if len(prefix) == 3 and prefix[1] == ':': - pass - # If prefix is a single character, preserve it since it is - # the root directory. - elif len(prefix) == 1: - pass - else: - prefix = prefix[:-1] - return prefix def sanitize_dir_option_value(self, prefix: str, option: OptionKey, value: T.Any) -> T.Any: ''' @@ -491,12 +475,6 @@ def get_option_object_for_subproject(self, key: T.Union[str, OptionKey], subproj def set_option(self, key: OptionKey, value, first_invocation: bool = False) -> bool: dirty = False - if self.optstore.is_builtin_option(key): - if key.name == 'prefix': - value = self.sanitize_prefix(value) - else: - prefix = self.optstore.get_value_for('prefix') - value = self.sanitize_dir_option_value(prefix, key, value) try: opt = self.optstore.get_value_object_for(key.name) diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index 383fced07034..87fe13dff658 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -927,7 +927,14 @@ def outdir_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str: @noKwargs @typed_pos_args('extract_objects', varargs=(mesonlib.File, str, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList)) def extract_objects_method(self, args: T.Tuple[T.List[T.Union[mesonlib.FileOrString, 'build.GeneratedTypes']]], kwargs: TYPE_nkwargs) -> build.ExtractedObjects: - return self._target_object.extract_objects(args[0]) + tobj = self._target_object + unity_value = self.interpreter.coredata.get_option_for_target(tobj, "unity") + if unity_value == 'on' or \ + (unity_value == 'subprojects' and tobj.subproject != ''): + raise mesonlib.MesonException(('Single object files cannot be extracted ' + 'in Unity builds. You can only extract all ' + 'the object files for each compiler at once.')) + return tobj.extract_objects(args[0]) @noPosargs @typed_kwargs( diff --git a/mesonbuild/options.py b/mesonbuild/options.py index f62782c1a9b3..76f4bc93ed08 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -7,6 +7,7 @@ import argparse import re import itertools +import os from .mesonlib import ( HoldableObject, @@ -793,14 +794,39 @@ def add_module_option(self, modulename: str, key: T.Union[OptionKey, str], valob self.add_system_option_internal(key, valobj) self.module_options.add(key) + def sanitize_prefix(self, prefix: str) -> str: + prefix = os.path.expanduser(prefix) + if not os.path.isabs(prefix): + raise MesonException(f'prefix value {prefix!r} must be an absolute path') + if prefix.endswith('/') or prefix.endswith('\\'): + # On Windows we need to preserve the trailing slash if the + # string is of type 'C:\' because 'C:' is not an absolute path. + if len(prefix) == 3 and prefix[1] == ':': + pass + # If prefix is a single character, preserve it since it is + # the root directory. + elif len(prefix) == 1: + pass + else: + prefix = prefix[:-1] + return prefix + def set_value(self, key: T.Union[OptionKey, str], new_value: 'T.Any') -> bool: key = self.ensure_and_validate_key(key) + if key.name == 'prefix': + new_value = self.sanitize_prefix(new_value) + elif self.is_builtin_option(key): + prefix = self.optstore.get_value_for('prefix') + new_value = self.sanitize_dir_option_value(prefix, key, new_value) if key not in self.options: raise MesonException(f'Internal error, tried to access non-existing option {key.name}.') return self.options[key].set_value(new_value) def set_option(self, name: str, subproject: T.Optional[str], new_value: str): key = OptionKey(name, subproject) + # FIRXME, dupe ofr the on in set_value. + if key.name == 'prefix': + new_value = self.sanitize_prefix(new_value) opt = self.get_value_object_for(key) if opt.deprecated is True: mlog.deprecation(f'Option {key.name!r} is deprecated') @@ -998,8 +1024,12 @@ def set_from_top_level_project_call(self, project_default_options, cmd_line_opti raise MesonException(f'Can not set subproject option {keystr} in machine files.') elif key in self.options: self.options[key].set_value(valstr) - #else: - # self.pending_project_options[key] = valstr + else: + proj_key = key.evolve(subproject='') + if proj_key in self.options: + self.options[proj_key].set_value(valstr) + else: + self.pending_project_options[key] = valstr for keystr, valstr in project_default_options.items(): # Ths is complicated by the fact that a string can have two meanings: #