From c9ea06700e54bf8b304c7dde88d76fd3e27d826f Mon Sep 17 00:00:00 2001 From: Maxandre Ogeret Date: Thu, 9 Jul 2026 02:44:07 +0300 Subject: [PATCH 1/2] backends: apply per-subproject language args to targets Compile and link args were collected via CoreData.get_external_args() and get_external_link_args(), which build an OptionKey without a subproject. Per-subproject values such as -Dsub:c_args=-DFOO or c_args in the default_options of a subproject() call were stored as augments in the option store but never consulted, so they silently never reached the compile or link command. Resolve the value per target with the existing augment- and override-aware CoreData.get_option_for_target() at the three target-context call sites. As a side effect, _args and _link_args entries in a target's override_options now take effect as well. Fixes #13260. --- docs/markdown/snippets/subproject_lang_args.md | 15 +++++++++++++++ mesonbuild/backend/backends.py | 7 +++++-- mesonbuild/build.py | 4 +++- mesonbuild/compilers/compilers.py | 6 +++++- .../.meson-subproject-wrap-hash.txt | 1 + .../subprojects/subsubsub-1.0/meson.build | 3 +++ .../subprojects/subsubsub.wrap | 2 ++ .../unit/139 subproject lang args/meson.build | 6 ++++++ test cases/unit/139 subproject lang args/over.c | 7 +++++++ .../subprojects/sub/meson.build | 3 +++ .../subprojects/sub/sub.c | 7 +++++++ test cases/unit/139 subproject lang args/top.c | 7 +++++++ unittests/allplatformstests.py | 17 +++++++++++++++++ 13 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 docs/markdown/snippets/subproject_lang_args.md create mode 100644 test cases/common/98 subproject subdir/subprojects/subsubsub-1.0/.meson-subproject-wrap-hash.txt create mode 100644 test cases/common/98 subproject subdir/subprojects/subsubsub-1.0/meson.build create mode 100644 test cases/common/98 subproject subdir/subprojects/subsubsub.wrap create mode 100644 test cases/unit/139 subproject lang args/meson.build create mode 100644 test cases/unit/139 subproject lang args/over.c create mode 100644 test cases/unit/139 subproject lang args/subprojects/sub/meson.build create mode 100644 test cases/unit/139 subproject lang args/subprojects/sub/sub.c create mode 100644 test cases/unit/139 subproject lang args/top.c diff --git a/docs/markdown/snippets/subproject_lang_args.md b/docs/markdown/snippets/subproject_lang_args.md new file mode 100644 index 000000000000..1410ceccbe14 --- /dev/null +++ b/docs/markdown/snippets/subproject_lang_args.md @@ -0,0 +1,15 @@ +## Per-subproject language arguments are now applied + +Compiler and linker arguments set for a specific subproject, for example +`-Dsub:c_args=-DFOO` on the command line or `c_args` in the +`default_options` of a `subproject()` call, are now added to the compile +and link commands of that subproject's targets. Previously such values +were accepted and stored but silently ignored. + +Similarly, `_args` and `_link_args` entries in a target's +`override_options` now take effect. + +In all cases the per-subproject or per-target value replaces the global +value (including flags coming from environment variables such as +`CFLAGS`), it is not appended to it. This matches what +`get_option('c_args')` already returned inside a subproject. diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 21cc8bb0a65d..f161fdb6b7d3 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -973,8 +973,11 @@ def generate_basic_compiler_args(self, target: build.BuildTarget, compiler: 'Com commands += self.build.get_global_args(compiler, target.for_machine) # Compile args added from the env: CFLAGS/CXXFLAGS, etc, or the cross # file. We want these to override all the defaults, but not the - # per-target compile args. - commands += self.environment.coredata.get_external_args(target.for_machine, compiler.get_language()) + # per-target compile args. Resolved per target so that per-subproject + # values (-Dsub:c_args=...) are honoured. + ext_args = self.environment.coredata.get_option_for_target(target, f'{compiler.get_language()}_args') + assert isinstance(ext_args, list), 'for mypy' + commands += ext_args # Using both /Z7 or /ZI and /Zi at the same times produces a compiler warning. # We do not add /Z7 or /ZI by default. If it is being used it is because the user has explicitly enabled it. # /Zi needs to be removed in that case to avoid cl's warning to that effect (D9025 : overriding '/Zi' with '/ZI') diff --git a/mesonbuild/build.py b/mesonbuild/build.py index d9fa10414f6d..9092e51151b5 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1917,7 +1917,9 @@ def get_external_rpath_dirs(self) -> T.Set[str]: args: T.List[str] = [] for lang in LANGUAGES_USING_LDFLAGS: try: - args += self.environment.coredata.get_external_link_args(self.for_machine, lang) + largs = self.environment.coredata.get_option_for_target(self, f'{lang}_link_args') + assert isinstance(largs, list), 'for mypy' + args += largs except KeyError: pass return self.get_rpath_dirs_from_link_args(args) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 1ba9d91d67a8..b11d996a0848 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1195,9 +1195,13 @@ def get_build_link_args(self, target: BuildTarget, build: build.Build) -> T.List # Link args added using add_global_link_arguments() override # per-project link arguments. Link args added from the env (LDFLAGS) # override all the defaults but not the per-target link args. + # Resolved per target so that per-subproject values + # (-Dsub:c_link_args=...) are honoured. + ext_link_args = self.environment.coredata.get_option_for_target(target, f'{self.get_language()}_link_args') + assert isinstance(ext_link_args, list), 'for mypy' return build.get_project_link_args(self, target) \ + build.get_global_link_args(self, self.for_machine) \ - + self.environment.coredata.get_external_link_args(self.for_machine, self.get_language()) + + ext_link_args def get_target_link_args(self, target: 'BuildTarget') -> T.List[str]: return target.link_args diff --git a/test cases/common/98 subproject subdir/subprojects/subsubsub-1.0/.meson-subproject-wrap-hash.txt b/test cases/common/98 subproject subdir/subprojects/subsubsub-1.0/.meson-subproject-wrap-hash.txt new file mode 100644 index 000000000000..40138659fd02 --- /dev/null +++ b/test cases/common/98 subproject subdir/subprojects/subsubsub-1.0/.meson-subproject-wrap-hash.txt @@ -0,0 +1 @@ +0fd8007dd44a1a5eb5c01af4c138f0993c6cb44da194b36db04484212eff591b diff --git a/test cases/common/98 subproject subdir/subprojects/subsubsub-1.0/meson.build b/test cases/common/98 subproject subdir/subprojects/subsubsub-1.0/meson.build new file mode 100644 index 000000000000..530852c0d3cc --- /dev/null +++ b/test cases/common/98 subproject subdir/subprojects/subsubsub-1.0/meson.build @@ -0,0 +1,3 @@ +project('subsubsub') + +meson.override_dependency('subsubsub', declare_dependency()) diff --git a/test cases/common/98 subproject subdir/subprojects/subsubsub.wrap b/test cases/common/98 subproject subdir/subprojects/subsubsub.wrap new file mode 100644 index 000000000000..5fa019a72cc8 --- /dev/null +++ b/test cases/common/98 subproject subdir/subprojects/subsubsub.wrap @@ -0,0 +1,2 @@ +[wrap-redirect] +filename = sub_implicit/subprojects/subsub/subprojects/subsubsub.wrap diff --git a/test cases/unit/139 subproject lang args/meson.build b/test cases/unit/139 subproject lang args/meson.build new file mode 100644 index 000000000000..50a37b9b8c7e --- /dev/null +++ b/test cases/unit/139 subproject lang args/meson.build @@ -0,0 +1,6 @@ +project('top', 'c') + +subproject('sub') + +static_library('top', 'top.c') +static_library('over', 'over.c', override_options: ['c_args=-DOVERRIDE_FLAG']) diff --git a/test cases/unit/139 subproject lang args/over.c b/test cases/unit/139 subproject lang args/over.c new file mode 100644 index 000000000000..68f0a6ffb2b2 --- /dev/null +++ b/test cases/unit/139 subproject lang args/over.c @@ -0,0 +1,7 @@ +#ifndef OVERRIDE_FLAG +#error "OVERRIDE_FLAG not set" +#endif + +int over(void) { + return 0; +} diff --git a/test cases/unit/139 subproject lang args/subprojects/sub/meson.build b/test cases/unit/139 subproject lang args/subprojects/sub/meson.build new file mode 100644 index 000000000000..ef921e2b14a2 --- /dev/null +++ b/test cases/unit/139 subproject lang args/subprojects/sub/meson.build @@ -0,0 +1,3 @@ +project('sub', 'c') + +static_library('sub', 'sub.c') diff --git a/test cases/unit/139 subproject lang args/subprojects/sub/sub.c b/test cases/unit/139 subproject lang args/subprojects/sub/sub.c new file mode 100644 index 000000000000..4afe3c100e07 --- /dev/null +++ b/test cases/unit/139 subproject lang args/subprojects/sub/sub.c @@ -0,0 +1,7 @@ +#ifndef SUB_FLAG +#error "SUB_FLAG not set" +#endif + +int sub(void) { + return 0; +} diff --git a/test cases/unit/139 subproject lang args/top.c b/test cases/unit/139 subproject lang args/top.c new file mode 100644 index 000000000000..6f005944cdae --- /dev/null +++ b/test cases/unit/139 subproject lang args/top.c @@ -0,0 +1,7 @@ +#ifndef TOP_FLAG +#error "TOP_FLAG not set" +#endif + +int top(void) { + return 0; +} diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index 7c558243d58a..e0785c4b037e 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -3360,6 +3360,23 @@ def test_reconfigure(self): self.build() self.run_tests() + def test_subproject_lang_args(self): + testdir = os.path.join(self.unit_test_dir, '139 subproject lang args') + self.init(testdir, extra_args=['-Dc_args=-DTOP_FLAG', '-Dsub:c_args=-DSUB_FLAG']) + # The source files #error out if their expected flag is missing. + self.build() + # A per-subproject or per-target value replaces the global one. + for cmd in self.get_compdb(): + if cmd['file'].endswith('top.c'): + self.assertIn('-DTOP_FLAG', cmd['command']) + self.assertNotIn('-DSUB_FLAG', cmd['command']) + elif cmd['file'].endswith('sub.c'): + self.assertIn('-DSUB_FLAG', cmd['command']) + self.assertNotIn('-DTOP_FLAG', cmd['command']) + elif cmd['file'].endswith('over.c'): + self.assertIn('-DOVERRIDE_FLAG', cmd['command']) + self.assertNotIn('-DTOP_FLAG', cmd['command']) + def test_wipe_from_builddir(self): testdir = os.path.join(self.common_test_dir, '157 custom target subdir depend files') self.init(testdir) From e0d0048701528bf56594e7a842c10311e6a3f102 Mon Sep 17 00:00:00 2001 From: Maxandre Ogeret Date: Thu, 9 Jul 2026 22:43:35 +0300 Subject: [PATCH 2/2] coredata: remove get_external_args and get_external_link_args These wrappers built the OptionKey without a subproject, so any caller in a subproject context silently got the top-level value and per-subproject augments (-Dsub:c_args=...) were ignored. Replace them with explicit optstore.get_value_for() calls that state their subproject at the call site. Module callers (gnome, external_project) now pass the current subproject, so g-ir-scanner, gtkdoc and external project env vars pick up per-subproject language args. Compiler sanity checks, linker detection, the MSVC dep prefix probe and cargo cfg parsing keep the top-level value, but that choice is now visible at the call site. The lru_cache on get_external_link_args is dropped; the lookup is a few dict accesses. gnome's gir scanner appended env flags to the returned list, mutating the cached (now stored) value; it copies the list now. --- mesonbuild/backend/ninjabackend.py | 4 ++-- mesonbuild/cargo/interpreter.py | 4 +++- mesonbuild/compilers/compilers.py | 13 +++++++++---- mesonbuild/compilers/fortran.py | 7 +++++-- mesonbuild/compilers/mixins/clike.py | 10 +++++++--- mesonbuild/compilers/swift.py | 3 ++- mesonbuild/compilers/vala.py | 9 ++++++--- mesonbuild/coredata.py | 12 ------------ mesonbuild/linkers/detect.py | 8 +++++--- mesonbuild/modules/external_project.py | 4 ++-- mesonbuild/modules/gnome.py | 11 ++++++----- unittests/allplatformstests.py | 4 ++-- 12 files changed, 49 insertions(+), 40 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index d0ff82375062..d34ad658a625 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -642,8 +642,8 @@ def detect_vs_dep_prefix(self, tempfilename: str) -> T.TextIO: # cpp_args in a native file) so that cl.exe can locate system headers # even when the INCLUDE environment variable is not set — for example, # when using a bundled MSVC toolchain outside a VS Developer Shell. - extra_args = self.environment.coredata.get_external_args( - MachineChoice.HOST, compiler.language) + extra_args = T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + OptionKey(f'{compiler.language}_args', machine=MachineChoice.HOST))) pc = subprocess.Popen(compiler.get_exelist() + ['/showIncludes', '/c', filebase] + extra_args, cwd=self.environment.get_scratch_dir(), diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py index 62bc71e4ce0b..1aa1f59b40f8 100644 --- a/mesonbuild/cargo/interpreter.py +++ b/mesonbuild/cargo/interpreter.py @@ -32,6 +32,7 @@ PerMachine, unique_list, SubProject, ) from .. import coredata, mlog +from ..options import OptionKey from ..wrap.wrap import PackageDefinition if T.TYPE_CHECKING: @@ -712,7 +713,8 @@ def _get_cfgs(self, machine: MachineChoice) -> T.Dict[str, str]: machine = MachineChoice.HOST rustc = T.cast('RustCompiler', self.environment.coredata.compilers[machine]['rust']) cfgs = rustc.get_cfgs().copy() - rustflags = self.environment.coredata.get_external_args(machine, 'rust') + rustflags = T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + OptionKey('rust_args', machine=machine))) rustflags_i = iter(rustflags) for i in rustflags_i: if i == '--cfg': diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index b11d996a0848..c0423e45f87d 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1444,8 +1444,11 @@ def _sanity_check_compile_args(self, sourcename: str, binname: str :return: a tuple of arguments, the first is the executable and compiler arguments, the second is linker arguments """ - cargs = list(self.environment.coredata.get_external_args(self.for_machine, self.language)) - largs = list(self.environment.coredata.get_external_link_args(self.for_machine, self.language)) + optstore = self.environment.coredata.optstore + cargs = list(T.cast('T.List[str]', optstore.get_value_for( + OptionKey(f'{self.language}_args', machine=self.for_machine)))) + largs = list(T.cast('T.List[str]', optstore.get_value_for( + OptionKey(f'{self.language}_link_args', machine=self.for_machine)))) return self.exelist_no_ccache + self.get_always_args() + self.get_output_args(binname) + [sourcename] + cargs, largs @abc.abstractmethod @@ -1591,10 +1594,12 @@ def build_wrapper_args(self, if mode is CompileCheckMode.COMPILE: # Add DFLAGS from the env - args += self.environment.coredata.get_external_args(self.for_machine, self.language) + args += T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + OptionKey(f'{self.language}_args', machine=self.for_machine))) elif mode is CompileCheckMode.LINK: # Add LDFLAGS from the env - args += self.environment.coredata.get_external_link_args(self.for_machine, self.language) + args += T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + OptionKey(f'{self.language}_link_args', machine=self.for_machine))) # extra_args must override all other arguments, so we add them last args += extra_args return args diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 6ad4a6b59bcd..618aa46e6f98 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -57,8 +57,11 @@ def has_function(self, funcname: str, prefix: str, *, 'that example is to see if the compiler has Fortran 2008 Block element.') def _get_basic_compiler_args(self, mode: CompileCheckMode) -> T.Tuple[T.List[str], T.List[str]]: - cargs = self.environment.coredata.get_external_args(self.for_machine, self.language) - largs = self.environment.coredata.get_external_link_args(self.for_machine, self.language) + optstore = self.environment.coredata.optstore + cargs = list(T.cast('T.List[str]', optstore.get_value_for( + options.OptionKey(f'{self.language}_args', machine=self.for_machine)))) + largs = list(T.cast('T.List[str]', optstore.get_value_for( + options.OptionKey(f'{self.language}_link_args', machine=self.for_machine)))) return cargs, largs def _sanity_check_source_code(self) -> str: diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index db440c30b4fb..0513a8fa807c 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -25,6 +25,7 @@ from ... import arglist from ... import mesonlib from ... import mlog +from ...options import OptionKey from ...linkers.linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker, CompCertDynamicLinker from ...mesonlib import LibType from .. import compilers @@ -339,7 +340,8 @@ def _get_basic_compiler_args(self, mode: CompileCheckMode) -> T.Tuple[T.List[str pass # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env - sys_args = self.environment.coredata.get_external_args(self.for_machine, self.language) + sys_args = T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + OptionKey(f'{self.language}_args', machine=self.for_machine))) if isinstance(sys_args, str): sys_args = [sys_args] # Apparently it is a thing to inject linker flags both @@ -355,7 +357,8 @@ def _get_basic_compiler_args(self, mode: CompileCheckMode) -> T.Tuple[T.List[str cargs += self.use_linker_args(ld_value[0], self.version) # Add LDFLAGS from the env - sys_ld_args = self.environment.coredata.get_external_link_args(self.for_machine, self.language) + sys_ld_args = T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + OptionKey(f'{self.language}_link_args', machine=self.for_machine))) # CFLAGS and CXXFLAGS go to both linking and compiling, but we want them # to only appear on the command line once. Remove dupes. largs += [x for x in sys_ld_args if x not in cleaned_sys_args] @@ -1202,7 +1205,8 @@ def find_framework_paths(self) -> T.List[str]: commands = self.get_exelist(ccache=False) + ['-v', '-E', '-'] commands += self.get_always_args() # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS from the env - commands += self.environment.coredata.get_external_args(self.for_machine, self.language) + commands += T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + OptionKey(f'{self.language}_args', machine=self.for_machine))) mlog.debug('Finding framework path by running: ', ' '.join(commands), '\n') os_env = os.environ.copy() os_env['LC_ALL'] = 'C' diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py index 105258027e30..2fab033cbe8e 100644 --- a/mesonbuild/compilers/swift.py +++ b/mesonbuild/compilers/swift.py @@ -184,7 +184,8 @@ def _sanity_check_compile_args(self, sourcename: str, binname: str if self.is_cross: args.extend(self.get_compile_only_args()) else: - largs.extend(self.environment.coredata.get_external_link_args(self.for_machine, self.language)) + largs.extend(T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + options.OptionKey(f'{self.language}_link_args', machine=self.for_machine)))) args.extend(self.get_output_args(binname)) args.append(sourcename) diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py index be5c1b0b44a5..d69fdc7a3e68 100644 --- a/mesonbuild/compilers/vala.py +++ b/mesonbuild/compilers/vala.py @@ -153,7 +153,8 @@ def find_library(self, libname: str, extra_dirs: T.List[str], libtype: LibType = if not extra_dirs: code = 'class MesonFindLibrary : Object { }' args: T.List[str] = [] - args += self.environment.coredata.get_external_args(self.for_machine, self.language) + args += T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + OptionKey(f'{self.language}_args', machine=self.for_machine))) vapi_args = ['--pkg', libname] args += vapi_args with self.cached_compile(code, extra_args=args, mode=CompileCheckMode.COMPILE) as p: @@ -212,10 +213,12 @@ def build_wrapper_args(self, if mode is CompileCheckMode.COMPILE: # Add DFLAGS from the env - args += self.environment.coredata.get_external_args(self.for_machine, self.language) + args += T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + OptionKey(f'{self.language}_args', machine=self.for_machine))) elif mode is CompileCheckMode.LINK: # Add LDFLAGS from the env - args += self.environment.coredata.get_external_link_args(self.for_machine, self.language) + args += T.cast('T.List[str]', self.environment.coredata.optstore.get_value_for( + OptionKey(f'{self.language}_link_args', machine=self.for_machine))) # extra_args must override all other arguments, so we add them last args += extra_args return args diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index ce3e4d7a3527..f0e24effc06d 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -9,7 +9,6 @@ from . import mlog, options import pickle, os, uuid import sys -from functools import lru_cache from collections import OrderedDict import textwrap @@ -401,17 +400,6 @@ def get_nondefault_buildtype_args(self) -> T.List[T.Union[T.Tuple[str, str, str] result.append(('debug', actual_debug, debug)) return result - def get_external_args(self, for_machine: MachineChoice, lang: str) -> T.List[str]: - # mypy cannot analyze type of OptionKey - key = OptionKey(f'{lang}_args', machine=for_machine) - return T.cast('T.List[str]', self.optstore.get_value_for(key)) - - @lru_cache(maxsize=None) - def get_external_link_args(self, for_machine: MachineChoice, lang: str) -> T.List[str]: - # mypy cannot analyze type of OptionKey - linkkey = OptionKey(f'{lang}_link_args', machine=for_machine) - return T.cast('T.List[str]', self.optstore.get_value_for(linkkey)) - def is_cross_build(self, when_building_for: MachineChoice = MachineChoice.HOST) -> bool: if when_building_for == MachineChoice.BUILD: return False diff --git a/mesonbuild/linkers/detect.py b/mesonbuild/linkers/detect.py index 10ccda159b93..f31b2c829316 100644 --- a/mesonbuild/linkers/detect.py +++ b/mesonbuild/linkers/detect.py @@ -9,6 +9,7 @@ EnvironmentException, Popen_safe, Popen_safe_logged, join_args, search_version ) +from ..options import OptionKey import re import shlex @@ -53,7 +54,8 @@ def guess_win_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty else: check_args = comp_class.LINKER_OPTION_STYLE.wrap(['/logo', '--version']) - check_args += env.coredata.get_external_link_args(for_machine, comp_class.language) + check_args += T.cast('T.List[str]', env.coredata.optstore.get_value_for( + OptionKey(f'{comp_class.language}_link_args', machine=for_machine))) override: T.List[str] = [] value = env.lookup_binary_entry(for_machine, comp_class.language + '_ld') @@ -123,12 +125,12 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty :extra_args: Any additional arguments required (such as a source file) """ from . import linkers - from ..options import OptionKey env.add_lang_args(comp_class.language, comp_class, for_machine) extra_args = extra_args or [] system = env.machines[for_machine].system - ldflags = env.coredata.get_external_link_args(for_machine, comp_class.language) + ldflags = T.cast('T.List[str]', env.coredata.optstore.get_value_for( + OptionKey(f'{comp_class.language}_link_args', machine=for_machine))) extra_args += comp_class._unix_args_to_native(ldflags, env.machines[for_machine]) check_args = comp_class.LINKER_OPTION_STYLE.wrap(['--version']) + extra_args diff --git a/mesonbuild/modules/external_project.py b/mesonbuild/modules/external_project.py index a800f961d57d..078dc7ba8112 100644 --- a/mesonbuild/modules/external_project.py +++ b/mesonbuild/modules/external_project.py @@ -156,13 +156,13 @@ def _configure(self, state: 'ModuleState') -> None: for lang, compiler in self.env.coredata.compilers[MachineChoice.HOST].items(): if any(lang not in i for i in (ENV_VAR_PROG_MAP, CFLAGS_MAPPING)): continue - cargs = self.env.coredata.get_external_args(MachineChoice.HOST, lang) + cargs = self.env.coredata.optstore.get_value_for(OptionKey(f'{lang}_args', self.subproject, MachineChoice.HOST)) assert isinstance(cargs, list), 'for mypy' self.run_env[ENV_VAR_PROG_MAP[lang][0]] = self._quote_and_join(compiler.get_exelist()) self.run_env[CFLAGS_MAPPING[lang]] = self._quote_and_join(cargs) if not link_exelist: link_exelist = compiler.get_linker_exelist() - _l = self.env.coredata.get_external_link_args(MachineChoice.HOST, lang) + _l = self.env.coredata.optstore.get_value_for(OptionKey(f'{lang}_link_args', self.subproject, MachineChoice.HOST)) assert isinstance(_l, list), 'for mypy' link_args = _l if link_exelist: diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 3776d3927f30..291ad79874c5 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -856,7 +856,7 @@ def _scan_langs(state: 'ModuleState', langs: T.Iterable[str]) -> T.List[str]: ret: T.List[str] = [] for lang in langs: - link_args = state.environment.coredata.get_external_link_args(MachineChoice.HOST, lang) + link_args = T.cast('T.List[str]', state.get_option(f'{lang}_link_args', state.subproject)) for link_arg in link_args: if link_arg.startswith('-L'): ret.append(link_arg) @@ -1113,7 +1113,7 @@ def _gather_typelib_includes_and_update_depends( def _get_external_args_for_langs(state: 'ModuleState', langs: T.List[str]) -> T.List[str]: ret: T.List[str] = [] for lang in langs: - ret += mesonlib.listify(state.environment.coredata.get_external_args(MachineChoice.HOST, lang)) + ret += mesonlib.listify(state.get_option(f'{lang}_args', state.subproject)) return ret @staticmethod @@ -1204,7 +1204,8 @@ def generate_gir(self, state: 'ModuleState', args: T.Tuple[T.List[T.Union[Execut scan_cflags += list(self._get_scanner_cflags(self._get_external_args_for_langs(state, [lc[0] for lc in langs_compilers]))) scan_internal_ldflags = [] scan_external_ldflags = [] - scan_env_ldflags = state.environment.coredata.get_external_link_args(MachineChoice.HOST, 'c') + # Copy: the returned list is the stored option value and gets appended to below. + scan_env_ldflags = list(T.cast('T.List[str]', state.get_option('c_link_args', state.subproject))) for cli_flags, env_flags in (self._get_scanner_ldflags(internal_ldflags), self._get_scanner_ldflags(dep_internal_ldflags)): scan_internal_ldflags += cli_flags scan_env_ldflags += env_flags @@ -1618,8 +1619,8 @@ def _get_build_args(self, c_args: T.List[str], inc_dirs: T.List[T.Union[str, bui ldflags.extend(internal_ldflags) ldflags.extend(external_ldflags) - cflags.extend(state.environment.coredata.get_external_args(MachineChoice.HOST, 'c')) - ldflags.extend(state.environment.coredata.get_external_link_args(MachineChoice.HOST, 'c')) + cflags.extend(T.cast('T.List[str]', state.get_option('c_args', state.subproject))) + ldflags.extend(T.cast('T.List[str]', state.get_option('c_link_args', state.subproject))) compiler = state.environment.coredata.compilers[MachineChoice.HOST]['c'] compiler_flags = self._get_langs_compilers_flags(state, [('c', compiler)]) diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index e0785c4b037e..cf37ef2e901c 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -4944,11 +4944,11 @@ def test_env_flags_to_linker(self) -> None: # C does have a separate linking step. It can be done through the compiler # driver or not; act accordingly. + link_args = env.coredata.optstore.get_value_for(OptionKey(f'{cc.language}_link_args', machine=cc.for_machine)) + assert isinstance(link_args, list), 'for mypy' if cc.USED_FOR_SEPARATE_LINKING_STEP: - link_args = env.coredata.get_external_link_args(cc.for_machine, cc.language) self.assertEqual(sorted(link_args), sorted(['-DCFLAG', '-flto'])) else: - link_args = env.coredata.get_external_link_args(cc.for_machine, cc.language) self.assertEqual(sorted(link_args), sorted(['-flto'])) def test_install_tag(self) -> None: