diff options
author | Xavier Claessens <xavier.claessens@collabora.com> | 2022-03-22 21:20:15 -0400 |
---|---|---|
committer | Xavier Claessens <xclaesse@gmail.com> | 2022-03-29 16:10:28 -0400 |
commit | 90310116ab683f8b7869836b5ae9b6504f87bcf4 (patch) | |
tree | 3032c1385aa2865b6e8b53182da13ded444215e5 | |
parent | e33ec88ac714b1d41cbfec28e80ee6bc046200eb (diff) | |
download | meson-90310116ab683f8b7869836b5ae9b6504f87bcf4.zip meson-90310116ab683f8b7869836b5ae9b6504f87bcf4.tar.gz meson-90310116ab683f8b7869836b5ae9b6504f87bcf4.tar.bz2 |
Replace backend.get_option_for_target() with target.get_option()
That method had nothing specific to the backend, it's purely a Target
method. This allows to cache the OptionOverrideProxy object on the
Target instance instead of creating a new one for each option lookup.
-rw-r--r-- | mesonbuild/backend/backends.py | 35 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 38 | ||||
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 6 | ||||
-rw-r--r-- | mesonbuild/backend/xcodebackend.py | 8 | ||||
-rw-r--r-- | mesonbuild/build.py | 37 |
5 files changed, 57 insertions, 67 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index b15cfd0..8d3ba88 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -32,7 +32,7 @@ from .. import mesonlib from .. import mlog from ..compilers import LANGUAGES_USING_LDFLAGS, detect from ..mesonlib import ( - File, MachineChoice, MesonException, OrderedSet, OptionOverrideProxy, + File, MachineChoice, MesonException, OrderedSet, classify_unity_sources, OptionKey, join_args ) @@ -310,19 +310,6 @@ class Backend: def get_target_filename_abs(self, target: T.Union[build.Target, build.CustomTargetIndex]) -> str: return os.path.join(self.environment.get_build_dir(), self.get_target_filename(target)) - def get_options_for_target(self, target: build.BuildTarget) -> OptionOverrideProxy: - return OptionOverrideProxy(target.option_overrides, - self.environment.coredata.options, - target.subproject) - - def get_option_for_target(self, key: 'OptionKey', target: build.BuildTarget) -> T.Union[str, int, bool, 'WrapMode']: - options = self.get_options_for_target(target) - # We don't actually have wrapmode here to do an assert, so just do a - # cast, we know what's in coredata anyway. - # TODO: if it's possible to annotate get_option or validate_option_value - # in the future we might be able to remove the cast here - return T.cast('T.Union[str, int, bool, WrapMode]', options[key].value) - def get_source_dir_include_args(self, target: build.BuildTarget, compiler: 'Compiler', *, absolute_path: bool = False) -> T.List[str]: curdir = target.get_subdir() if absolute_path: @@ -420,7 +407,7 @@ class Backend: abs_files: T.List[str] = [] result: T.List[mesonlib.File] = [] compsrcs = classify_unity_sources(target.compilers.values(), unity_src) - unity_size = self.get_option_for_target(OptionKey('unity_size'), target) + unity_size = target.get_option(OptionKey('unity_size')) assert isinstance(unity_size, int), 'for mypy' def init_language_file(suffix: str, unity_file_number: int) -> T.TextIO: @@ -850,7 +837,7 @@ class Backend: if self.is_unity(extobj.target): compsrcs = classify_unity_sources(extobj.target.compilers.values(), sources) sources = [] - unity_size = self.get_option_for_target(OptionKey('unity_size'), extobj.target) + unity_size = extobj.target.get_option(OptionKey('unity_size')) assert isinstance(unity_size, int), 'for mypy' for comp, srcs in compsrcs.items(): @@ -917,7 +904,7 @@ class Backend: # starting from hard-coded defaults followed by build options and so on. commands = compiler.compiler_args() - copt_proxy = self.get_options_for_target(target) + copt_proxy = target.get_options() # First, the trivial ones that are impossible to override. # # Add -nostdinc/-nostdinc++ if needed; can't be overridden @@ -930,27 +917,27 @@ class Backend: commands += compiler.get_no_warn_args() else: # warning_level is a string, but mypy can't determine that - commands += compiler.get_warn_args(T.cast('str', self.get_option_for_target(OptionKey('warning_level'), target))) + commands += compiler.get_warn_args(T.cast('str', target.get_option(OptionKey('warning_level')))) # Add -Werror if werror=true is set in the build options set on the # command-line or default_options inside project(). This only sets the # action to be done for warnings if/when they are emitted, so it's ok # to set it after get_no_warn_args() or get_warn_args(). - if self.get_option_for_target(OptionKey('werror'), target): + if target.get_option(OptionKey('werror')): commands += compiler.get_werror_args() # Add compile args for c_* or cpp_* build options set on the # command-line or default_options inside project(). commands += compiler.get_option_compile_args(copt_proxy) # Add buildtype args: optimization level, debugging, etc. - buildtype = self.get_option_for_target(OptionKey('buildtype'), target) + buildtype = target.get_option(OptionKey('buildtype')) assert isinstance(buildtype, str), 'for mypy' commands += compiler.get_buildtype_args(buildtype) - optimization = self.get_option_for_target(OptionKey('optimization'), target) + optimization = target.get_option(OptionKey('optimization')) assert isinstance(optimization, str), 'for mypy' commands += compiler.get_optimization_args(optimization) - debug = self.get_option_for_target(OptionKey('debug'), target) + debug = target.get_option(OptionKey('debug')) assert isinstance(debug, bool), 'for mypy' commands += compiler.get_debug_args(debug) @@ -1290,7 +1277,7 @@ class Backend: return libs def is_unity(self, target: build.BuildTarget) -> bool: - optval = self.get_option_for_target(OptionKey('unity'), target) + 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]: @@ -1568,7 +1555,7 @@ class Backend: # TODO: Create GNUStrip/AppleStrip/etc. hierarchy for more # fine-grained stripping of static archives. can_strip = not isinstance(t, build.StaticLibrary) - should_strip = can_strip and self.get_option_for_target(OptionKey('strip'), t) + should_strip = can_strip and t.get_option(OptionKey('strip')) assert isinstance(should_strip, bool), 'for mypy' # Install primary build output (library/executable/jar, etc) # Done separately because of strip/aliases/rpath diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 6f560fe..422f6bc 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1311,7 +1311,7 @@ class NinjaBackend(backends.Backend): return args, deps def generate_cs_target(self, target: build.BuildTarget): - buildtype = self.get_option_for_target(OptionKey('buildtype'), target) + buildtype = target.get_option(OptionKey('buildtype')) fname = target.get_filename() outname_rel = os.path.join(self.get_target_dir(target), fname) src_list = target.get_sources() @@ -1320,8 +1320,8 @@ class NinjaBackend(backends.Backend): deps = [] commands = compiler.compiler_args(target.extra_args.get('cs', [])) commands += compiler.get_buildtype_args(buildtype) - commands += compiler.get_optimization_args(self.get_option_for_target(OptionKey('optimization'), target)) - commands += compiler.get_debug_args(self.get_option_for_target(OptionKey('debug'), target)) + commands += compiler.get_optimization_args(target.get_option(OptionKey('optimization'))) + commands += compiler.get_debug_args(target.get_option(OptionKey('debug'))) if isinstance(target, build.Executable): commands.append('-target:exe') elif isinstance(target, build.SharedLibrary): @@ -1362,7 +1362,7 @@ class NinjaBackend(backends.Backend): def determine_single_java_compile_args(self, target, compiler): args = [] - args += compiler.get_buildtype_args(self.get_option_for_target(OptionKey('buildtype'), target)) + args += compiler.get_buildtype_args(target.get_option(OptionKey('buildtype'))) args += self.build.get_global_args(compiler, target.for_machine) args += self.build.get_project_args(compiler, target.subproject, target.for_machine) args += target.get_java_args() @@ -1605,19 +1605,17 @@ class NinjaBackend(backends.Backend): cython = target.compilers['cython'] - opt_proxy = self.get_options_for_target(target) - args: T.List[str] = [] args += cython.get_always_args() - args += cython.get_buildtype_args(self.get_option_for_target(OptionKey('buildtype'), target)) - args += cython.get_debug_args(self.get_option_for_target(OptionKey('debug'), target)) - args += cython.get_optimization_args(self.get_option_for_target(OptionKey('optimization'), target)) - args += cython.get_option_compile_args(opt_proxy) + args += cython.get_buildtype_args(target.get_option(OptionKey('buildtype'))) + args += cython.get_debug_args(target.get_option(OptionKey('debug'))) + args += cython.get_optimization_args(target.get_option(OptionKey('optimization'))) + args += cython.get_option_compile_args(target.get_options()) args += self.build.get_global_args(cython, target.for_machine) args += self.build.get_project_args(cython, target.subproject, target.for_machine) args += target.get_extra_args('cython') - ext = opt_proxy[OptionKey('language', machine=target.for_machine, lang='cython')].value + ext = target.get_option(OptionKey('language', machine=target.for_machine, lang='cython')) for src in target.get_sources(): if src.endswith('.pyx'): @@ -1693,7 +1691,7 @@ class NinjaBackend(backends.Backend): # Rust compiler takes only the main file as input and # figures out what other files are needed via import # statements and magic. - base_proxy = self.get_options_for_target(target) + base_proxy = target.get_options() args = rustc.compiler_args() # Compiler args for compiling this target args += compilers.get_base_compile_args(base_proxy, rustc) @@ -1935,8 +1933,8 @@ class NinjaBackend(backends.Backend): raise InvalidArguments(f'Swift target {target.get_basename()} contains a non-swift source file.') os.makedirs(self.get_target_private_dir_abs(target), exist_ok=True) compile_args = swiftc.get_compile_only_args() - compile_args += swiftc.get_optimization_args(self.get_option_for_target(OptionKey('optimization'), target)) - compile_args += swiftc.get_debug_args(self.get_option_for_target(OptionKey('debug'), target)) + compile_args += swiftc.get_optimization_args(target.get_option(OptionKey('optimization'))) + compile_args += swiftc.get_debug_args(target.get_option(OptionKey('debug'))) compile_args += swiftc.get_module_args(module_name) compile_args += self.build.get_project_args(swiftc, target.subproject, target.for_machine) compile_args += self.build.get_global_args(swiftc, target.for_machine) @@ -2464,7 +2462,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) return linker.get_link_debugfile_args(outname) def generate_llvm_ir_compile(self, target, src): - base_proxy = self.get_options_for_target(target) + base_proxy = target.get_options() compiler = get_compiler_for_source(target.compilers.values(), src) commands = compiler.compiler_args() # Compiler args for compiling this target @@ -2524,7 +2522,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) return commands def _generate_single_compile_base_args(self, target: build.BuildTarget, compiler: 'Compiler') -> 'CompilerArgs': - base_proxy = self.get_options_for_target(target) + base_proxy = target.get_options() # Create an empty commands list, and start adding arguments from # various sources in the order in which they must override each other commands = compiler.compiler_args() @@ -3026,9 +3024,9 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) # options passed on the command-line, in default_options, etc. # These have the lowest priority. if isinstance(target, build.StaticLibrary): - commands += linker.get_base_link_args(self.get_options_for_target(target)) + commands += linker.get_base_link_args(target.get_options()) else: - commands += compilers.get_base_link_args(self.get_options_for_target(target), + commands += compilers.get_base_link_args(target.get_options(), linker, isinstance(target, build.SharedModule)) # Add -nostdlib if needed; can't be overridden @@ -3036,9 +3034,9 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) # Add things like /NOLOGO; usually can't be overridden commands += linker.get_linker_always_args() # Add buildtype linker args: optimization level, etc. - commands += linker.get_buildtype_linker_args(self.get_option_for_target(OptionKey('buildtype'), target)) + commands += linker.get_buildtype_linker_args(target.get_option(OptionKey('buildtype'))) # Add /DEBUG and the pdb filename when using MSVC - if self.get_option_for_target(OptionKey('debug'), target): + if target.get_option(OptionKey('debug')): commands += self.get_link_debugfile_args(linker, target, outname) debugfile = self.get_link_debugfile_name(linker, target, outname) if debugfile is not None: diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 3190630..b2ece1c 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -990,7 +990,7 @@ class Vs2010Backend(backends.Backend): for l, comp in target.compilers.items(): if l in file_args: file_args[l] += compilers.get_base_compile_args( - self.get_options_for_target(target), comp) + target.get_options(), comp) file_args[l] += comp.get_option_compile_args( self.environment.coredata.options) @@ -1114,9 +1114,9 @@ class Vs2010Backend(backends.Backend): ET.SubElement(clconf, 'PreprocessorDefinitions').text = ';'.join(target_defines) ET.SubElement(clconf, 'FunctionLevelLinking').text = 'true' # Warning level - warning_level = self.get_option_for_target(OptionKey('warning_level'), target) + warning_level = target.get_option(OptionKey('warning_level')) ET.SubElement(clconf, 'WarningLevel').text = 'Level' + str(1 + int(warning_level)) - if self.get_option_for_target(OptionKey('werror'), target): + if target.get_option(OptionKey('werror')): ET.SubElement(clconf, 'TreatWarningAsError').text = 'true' # Optimization flags o_flags = split_o_flags_args(build_args) diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py index 1cf1765..72667d7 100644 --- a/mesonbuild/backend/xcodebackend.py +++ b/mesonbuild/backend/xcodebackend.py @@ -1503,8 +1503,8 @@ class XCodeBackend(backends.Backend): if compiler is None: continue # Start with warning args - warn_args = compiler.get_warn_args(self.get_option_for_target(OptionKey('warning_level'), target)) - copt_proxy = self.get_options_for_target(target) + warn_args = compiler.get_warn_args(target.get_option(OptionKey('warning_level'))) + copt_proxy = target.get_options() std_args = compiler.get_option_compile_args(copt_proxy) # Add compile args added using add_project_arguments() pargs = self.build.projects_args[target.for_machine].get(target.subproject, {}).get(lang, []) @@ -1556,9 +1556,9 @@ class XCodeBackend(backends.Backend): if target.suffix: suffix = '.' + target.suffix settings_dict.add_item('EXECUTABLE_SUFFIX', suffix) - settings_dict.add_item('GCC_GENERATE_DEBUGGING_SYMBOLS', BOOL2XCODEBOOL[self.get_option_for_target(OptionKey('debug'), target)]) + settings_dict.add_item('GCC_GENERATE_DEBUGGING_SYMBOLS', BOOL2XCODEBOOL[target.get_option(OptionKey('debug'))]) settings_dict.add_item('GCC_INLINES_ARE_PRIVATE_EXTERN', 'NO') - settings_dict.add_item('GCC_OPTIMIZATION_LEVEL', OPT2XCODEOPT[self.get_option_for_target(OptionKey('optimization'), target)]) + settings_dict.add_item('GCC_OPTIMIZATION_LEVEL', OPT2XCODEOPT[target.get_option(OptionKey('optimization'))]) if target.has_pch: # Xcode uses GCC_PREFIX_HEADER which only allows one file per target/executable. Precompiling various header files and # applying a particular pch to each source file will require custom scripts (as a build phase) and build flags per each diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 24eeb08..72f5950 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -35,7 +35,7 @@ from .mesonlib import ( File, MesonException, MachineChoice, PerMachine, OrderedSet, listify, extract_as_list, typeslistify, stringlistify, classify_unity_sources, get_filenames_templates_dict, substitute_values, has_path_sep, - OptionKey, PerMachineDefaultable, + OptionKey, PerMachineDefaultable, OptionOverrideProxy, MesonBugException ) from .compilers import ( @@ -578,7 +578,7 @@ class Target(HoldableObject): ''')) self.install = False self.build_always_stale = False - self.option_overrides: T.Dict[OptionKey, str] = {} + self.options = OptionOverrideProxy({}, self.environment.coredata.options, self.subproject) self.extra_files = [] # type: T.List[File] if not hasattr(self, 'typename'): raise RuntimeError(f'Target type is not set for target class "{type(self).__name__}". This is a bug') @@ -682,13 +682,25 @@ class Target(HoldableObject): # set, use the value of 'install' if it's enabled. self.build_by_default = True - option_overrides = self.parse_overrides(kwargs) + self.set_option_overrides(self.parse_overrides(kwargs)) + def set_option_overrides(self, option_overrides: T.Dict[OptionKey, str]) -> None: + self.options.overrides = {} for k, v in option_overrides.items(): if k.lang: - self.option_overrides[k.evolve(machine=self.for_machine)] = v - continue - self.option_overrides[k] = v + self.options.overrides[k.evolve(machine=self.for_machine)] = v + else: + self.options.overrides[k] = v + + def get_options(self) -> OptionOverrideProxy: + return self.options + + def get_option(self, key: 'OptionKey') -> T.Union[str, int, bool, 'WrapMode']: + # We don't actually have wrapmode here to do an assert, so just do a + # cast, we know what's in coredata anyway. + # TODO: if it's possible to annotate get_option or validate_option_value + # in the future we might be able to remove the cast here + return T.cast('T.Union[str, int, bool, WrapMode]', self.options[key].value) @staticmethod def parse_overrides(kwargs: T.Dict[str, T.Any]) -> T.Dict[OptionKey, str]: @@ -959,10 +971,8 @@ class BuildTarget(Target): self.compilers['c'] = self.all_compilers['c'] if 'cython' in self.compilers: key = OptionKey('language', machine=self.for_machine, lang='cython') - if key in self.option_overrides: - value = self.option_overrides[key] - else: - value = self.environment.coredata.options[key].value + value = self.get_option(key) + try: self.compilers[value] = self.all_compilers[value] except KeyError: @@ -2450,12 +2460,7 @@ class CustomTarget(Target, CommandBase): self.install_tag = _install_tag self.name = name if name else self.outputs[0] - if override_options: - for k, v in override_options.items(): - if k.lang: - self.option_overrides_compiler[k.evolve(machine=self.for_machine)] = v - else: - self.option_overrides_base[k] = v + self.set_option_overrides(override_options or {}) # Whether to use absolute paths for all files on the commandline self.absolute_paths = absolute_paths |