aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2020-12-08 11:08:37 -0800
committerDylan Baker <dylan@pnwbakers.com>2021-01-11 11:15:06 -0800
commit4b0b44aface1cd9ed073733dd80b040b5aaf4c99 (patch)
tree3150d4f22c7f179edc276b3f9a707c7b74dd9ab4 /mesonbuild
parentf202da0689795ba4330581e69a879f089e169f6c (diff)
downloadmeson-4b0b44aface1cd9ed073733dd80b040b5aaf4c99.zip
meson-4b0b44aface1cd9ed073733dd80b040b5aaf4c99.tar.gz
meson-4b0b44aface1cd9ed073733dd80b040b5aaf4c99.tar.bz2
move handling of CFLAGS and friends to environment
This has a bunch of nice features. It obviously centralizes everything, which is nice. It also means that env is only re-read at `meson --wipe`, not `meson --reconfigure`. And it's going to allow more cleanups.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/compilers/c.py3
-rw-r--r--mesonbuild/compilers/compilers.py75
-rw-r--r--mesonbuild/compilers/cpp.py3
-rw-r--r--mesonbuild/coredata.py2
-rw-r--r--mesonbuild/environment.py83
-rw-r--r--mesonbuild/linkers.py17
6 files changed, 72 insertions, 111 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 311e65a..4a55b46 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -17,7 +17,6 @@ import typing as T
from .. import coredata
from ..mesonlib import MachineChoice, MesonException, mlog, version_compare, OptionKey
-from ..linkers import LinkerEnvVarsMixin
from .c_function_attributes import C_FUNC_ATTRIBUTES
from .mixins.clike import CLikeCompiler
from .mixins.ccrx import CcrxCompiler
@@ -195,7 +194,7 @@ class AppleClangCCompiler(ClangCCompiler):
_C2X_VERSION = '>=11.0.0'
-class EmscriptenCCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCCompiler):
+class EmscriptenCCompiler(EmscriptenMixin, ClangCCompiler):
def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool,
info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None,
linker: T.Optional['DynamicLinker'] = None,
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 23a3bc5..cf9f35b 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -22,13 +22,9 @@ from functools import lru_cache
from .. import coredata
from .. import mlog
from .. import mesonlib
-from ..linkers import LinkerEnvVarsMixin
from ..mesonlib import (
EnvironmentException, MachineChoice, MesonException,
- Popen_safe, split_args, LibType, TemporaryDirectoryWinProof, OptionKey,
-)
-from ..envconfig import (
- get_env_var
+ Popen_safe, LibType, TemporaryDirectoryWinProof, OptionKey,
)
from ..arglist import CompilerArgs
@@ -105,7 +101,7 @@ CFLAGS_MAPPING: T.Mapping[str, str] = {
CEXE_MAPPING: T.Mapping = {
'c': 'CC',
- 'cpp': 'CXX',
+ 'cpp': 'CXX',
}
# All these are only for C-linkable languages; see `clink_langs` above.
@@ -591,11 +587,6 @@ class Compiler(metaclass=abc.ABCMeta):
"""
return []
- def get_linker_args_from_envvars(self,
- for_machine: MachineChoice,
- is_cross: bool) -> T.List[str]:
- return self.linker.get_args_from_envvars(for_machine, is_cross)
-
def get_options(self) -> 'KeyedOptionDictType':
return {}
@@ -1203,68 +1194,32 @@ class Compiler(metaclass=abc.ABCMeta):
def get_prelink_args(self, prelink_name: str, obj_list: T.List[str]) -> T.List[str]:
raise EnvironmentException('{} does not know how to do prelinking.'.format(self.id))
-def get_args_from_envvars(lang: str,
- for_machine: MachineChoice,
- is_cross: bool,
- use_linker_args: bool) -> T.Tuple[T.List[str], T.List[str]]:
- """
- Returns a tuple of (compile_flags, link_flags) for the specified language
- from the inherited environment
- """
- if lang not in CFLAGS_MAPPING:
- return [], []
-
- compile_flags = [] # type: T.List[str]
- link_flags = [] # type: T.List[str]
-
- env_compile_flags = get_env_var(for_machine, is_cross, CFLAGS_MAPPING[lang])
- if env_compile_flags is not None:
- compile_flags += split_args(env_compile_flags)
-
- # Link flags (same for all languages)
- if lang in LANGUAGES_USING_LDFLAGS:
- link_flags += LinkerEnvVarsMixin.get_args_from_envvars(for_machine, is_cross)
- if use_linker_args:
- # When the compiler is used as a wrapper around the linker (such as
- # with GCC and Clang), the compile flags can be needed while linking
- # too. This is also what Autotools does. However, we don't want to do
- # this when the linker is stand-alone such as with MSVC C/C++, etc.
- link_flags = compile_flags + link_flags
-
- # Pre-processor flags for certain languages
- if lang in LANGUAGES_USING_CPPFLAGS:
- env_preproc_flags = get_env_var(for_machine, is_cross, 'CPPFLAGS')
- if env_preproc_flags is not None:
- compile_flags += split_args(env_preproc_flags)
-
- return compile_flags, link_flags
-
def get_global_options(lang: str,
comp: T.Type[Compiler],
for_machine: MachineChoice,
- is_cross: bool) -> 'KeyedOptionDictType':
+ env: 'Environment') -> 'KeyedOptionDictType':
"""Retreive options that apply to all compilers for a given language."""
description = 'Extra arguments passed to the {}'.format(lang)
argkey = OptionKey('args', lang=lang, machine=for_machine)
largkey = argkey.evolve('link_args')
+
+ # We shouldn't need listify here, but until we have a separate
+ # linker-driver representation and can have that do the combine we have to
+ # do it htis way.
+ compile_args = mesonlib.listify(env.options.get(argkey, []))
+ link_args = mesonlib.listify(env.options.get(largkey, []))
+
+ if comp.INVOKES_LINKER:
+ link_args = compile_args + link_args
+
opts: 'KeyedOptionDictType' = {
argkey: coredata.UserArrayOption(
description + ' compiler',
- [], split_args=True, user_input=True, allow_dups=True),
+ compile_args, split_args=True, user_input=True, allow_dups=True),
largkey: coredata.UserArrayOption(
description + ' linker',
- [], split_args=True, user_input=True, allow_dups=True),
+ link_args, split_args=True, user_input=True, allow_dups=True),
}
- # Get from env vars.
- compile_args, link_args = get_args_from_envvars(
- lang,
- for_machine,
- is_cross,
- comp.INVOKES_LINKER)
-
- opts[argkey].set_value(compile_args)
- opts[largkey].set_value(link_args)
-
return opts
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 2e94e48..ebe3a4f 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -21,7 +21,6 @@ from .. import coredata
from .. import mlog
from ..mesonlib import MesonException, MachineChoice, version_compare, OptionKey
-from ..linkers import LinkerEnvVarsMixin
from .compilers import (
gnu_winlibs,
msvc_winlibs,
@@ -256,7 +255,7 @@ class AppleClangCPPCompiler(ClangCPPCompiler):
return ['-lc++']
-class EmscriptenCPPCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCPPCompiler):
+class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler):
def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool,
info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None,
linker: T.Optional['DynamicLinker'] = None,
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index cda0566..f2aba80 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -759,7 +759,7 @@ class CoreData:
for_machine: MachineChoice, env: 'Environment') -> None:
"""Add global language arguments that are needed before compiler/linker detection."""
from .compilers import compilers
- options = compilers.get_global_options(lang, comp, for_machine, env.is_cross_build())
+ options = compilers.get_global_options(lang, comp, for_machine, env)
self.add_compiler_options(options, lang, for_machine, env)
def process_new_compiler(self, lang: str, comp: 'Compiler', env: 'Environment') -> None:
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 7555be5..12b9dbb 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import itertools
import os, platform, re, sys, shutil, subprocess
import tempfile
import shlex
@@ -605,7 +606,7 @@ class Environment:
#
# Note that order matters because of 'buildtype', if it is after
# 'optimization' and 'debug' keys, it override them.
- self.options: T.MutableMapping[OptionKey, str] = collections.OrderedDict()
+ self.options: T.MutableMapping[OptionKey, T.Union[str, T.List[str]]] = collections.OrderedDict()
## Read in native file(s) to override build machine configuration
@@ -750,36 +751,58 @@ class Environment:
self.options[key] = v
def set_default_options_from_env(self) -> None:
- for for_machine in MachineChoice:
- for evar, keyname in [('PKG_CONFIG_PATH', 'pkg_config_path'),
- ('CMAKE_PREFIX_PATH', 'cmake_prefix_path')]:
- p_env_pair = get_env_var_pair(for_machine, self.is_cross_build(), evar)
- if p_env_pair is not None:
- _, p_env = p_env_pair
-
- # these may contain duplicates, which must be removed, else
- # a duplicates-in-array-option warning arises.
- if keyname == 'cmake_prefix_path':
- if self.machines[for_machine].is_windows():
- # Cannot split on ':' on Windows because its in the drive letter
- _p_env = p_env.split(os.pathsep)
- else:
- # https://github.com/mesonbuild/meson/issues/7294
- _p_env = re.split(r':|;', p_env)
- p_list = list(mesonlib.OrderedSet(_p_env))
- elif keyname == 'pkg_config_path':
- p_list = list(mesonlib.OrderedSet(p_env.split(':')))
+ opts: T.List[T.Tuple[str, str]] = (
+ [(v, f'{k}_args') for k, v in compilers.compilers.CFLAGS_MAPPING.items()] +
+ [
+ ('PKG_CONFIG_PATH', 'pkg_config_path'),
+ ('CMAKE_PREFIX_PATH', 'cmake_prefix_path'),
+ ('LDFLAGS', 'ldflags'),
+ ('CPPFLAGS', 'cppflags'),
+ ]
+ )
+
+ for (evar, keyname), for_machine in itertools.product(opts, MachineChoice):
+ p_env_pair = get_env_var_pair(for_machine, self.is_cross_build(), evar)
+ if p_env_pair is not None:
+ _, p_env = p_env_pair
+
+ # these may contain duplicates, which must be removed, else
+ # a duplicates-in-array-option warning arises.
+ if keyname == 'cmake_prefix_path':
+ if self.machines[for_machine].is_windows():
+ # Cannot split on ':' on Windows because its in the drive letter
+ _p_env = p_env.split(os.pathsep)
else:
- raise RuntimeError('Should be unreachable')
- p_list = [e for e in p_list if e] # filter out any empty eelemnts
-
- # Take env vars only on first invocation, if the env changes when
- # reconfiguring it gets ignored.
- # FIXME: We should remember if we took the value from env to warn
- # if it changes on future invocations.
- if self.first_invocation:
- key = OptionKey(keyname, machine=for_machine)
- self.options.setdefault(key, p_list)
+ # https://github.com/mesonbuild/meson/issues/7294
+ _p_env = re.split(r':|;', p_env)
+ p_list = list(mesonlib.OrderedSet(_p_env))
+ elif keyname == 'pkg_config_path':
+ p_list = list(mesonlib.OrderedSet(p_env.split(':')))
+ else:
+ p_list = split_args(p_env)
+ p_list = [e for e in p_list if e] # filter out any empty eelemnts
+
+ # Take env vars only on first invocation, if the env changes when
+ # reconfiguring it gets ignored.
+ # FIXME: We should remember if we took the value from env to warn
+ # if it changes on future invocations.
+ if self.first_invocation:
+ if keyname == 'ldflags':
+ key = OptionKey('link_args', machine=for_machine, lang='c') # needs a language to initialize properly
+ for lang in compilers.compilers.LANGUAGES_USING_LDFLAGS:
+ key = key.evolve(lang=lang)
+ v = mesonlib.listify(self.options.get(key, []))
+ self.options.setdefault(key, v + p_list)
+ elif keyname == 'cppflags':
+ key = OptionKey('args', machine=for_machine, lang='c')
+ for lang in compilers.compilers.LANGUAGES_USING_CPPFLAGS:
+ key = key.evolve(lang=lang)
+ v = mesonlib.listify(self.options.get(key, []))
+ self.options.setdefault(key, v + p_list)
+ else:
+ key = OptionKey.from_string(keyname).evolve(machine=for_machine)
+ v = mesonlib.listify(self.options.get(key, []))
+ self.options.setdefault(key, v + p_list)
def create_new_coredata(self, options: 'argparse.Namespace') -> None:
# WARNING: Don't use any values from coredata in __init__. It gets
diff --git a/mesonbuild/linkers.py b/mesonbuild/linkers.py
index 8dae94c..86e6aac 100644
--- a/mesonbuild/linkers.py
+++ b/mesonbuild/linkers.py
@@ -18,7 +18,6 @@ import typing as T
from . import mesonlib
from .arglist import CompilerArgs
-from .envconfig import get_env_var
if T.TYPE_CHECKING:
from .coredata import KeyedOptionDictType
@@ -301,21 +300,7 @@ def evaluate_rpath(p: str, build_dir: str, from_dir: str) -> str:
else:
return os.path.relpath(os.path.join(build_dir, p), os.path.join(build_dir, from_dir))
-
-class LinkerEnvVarsMixin(metaclass=abc.ABCMeta):
-
- """Mixin reading LDFLAGS from the environment."""
-
- @staticmethod
- def get_args_from_envvars(for_machine: mesonlib.MachineChoice,
- is_cross: bool) -> T.List[str]:
- raw_value = get_env_var(for_machine, is_cross, 'LDFLAGS')
- if raw_value is not None:
- return mesonlib.split_args(raw_value)
- else:
- return []
-
-class DynamicLinker(LinkerEnvVarsMixin, metaclass=abc.ABCMeta):
+class DynamicLinker(metaclass=abc.ABCMeta):
"""Base class for dynamic linkers."""