aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2022-03-22 21:20:15 -0400
committerXavier Claessens <xclaesse@gmail.com>2022-03-29 16:10:28 -0400
commit90310116ab683f8b7869836b5ae9b6504f87bcf4 (patch)
tree3032c1385aa2865b6e8b53182da13ded444215e5
parente33ec88ac714b1d41cbfec28e80ee6bc046200eb (diff)
downloadmeson-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.py35
-rw-r--r--mesonbuild/backend/ninjabackend.py38
-rw-r--r--mesonbuild/backend/vs2010backend.py6
-rw-r--r--mesonbuild/backend/xcodebackend.py8
-rw-r--r--mesonbuild/build.py37
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