Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Ericson2314 committed Mar 6, 2020
1 parent 7476961 commit 9ebede7
Show file tree
Hide file tree
Showing 20 changed files with 231 additions and 159 deletions.
23 changes: 10 additions & 13 deletions docs/markdown/howtox.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,16 @@ When first running Meson, set it in an environment variable.
$ CC=mycc meson <options>
```

Note that environment variables like `CC` _always_ refer to the native
compiler. That is, the compiler used to compile programs that run on
the current machine. The compiler used in cross compilation is set
with the cross file.

This behaviour is different from e.g. Autotools, where cross
compilation is done by setting `CC` to point to the cross compiler
(such as `/usr/bin/arm-linux-gnueabihf-gcc`). The reason for this is
that Meson supports natively the case where you compile helper tools
(such as code generators) and use the results during the
build. Because of this Meson needs to know both the native and the
cross compiler. The former is set via the environment variables or
native-files and the latter via the cross file only.
Note that environment variables like `CC` only refer to the host platform in
cross builds. That is, the `CC` refers compiler used to compile programs that
run on the machine we will eventually install the project on. The compiler used
to build things that run on the machine we do the building can be specified
with `CC_FOR_BUILD`. You can always used `CC_FOR_BUILD`, but for native builds
it is less well known because Meson (and Autotools) will default `CC_FOR_BUILD`
with `CC`.

Note that environment variables are never the idiomatic way to do anything with
Meson, however. It is better to use the native and cross files.

## Set dynamic linker

Expand Down
12 changes: 12 additions & 0 deletions docs/markdown/snippets/env_vars_and_cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Environment Variables with Cross Builds

Previously in Meson, variables like `CC` effected both the host and build
platforms for native builds, but the just the build platform for cross builds.
Now `CC` always effects the host platform, and `CC_FOR_BUILD` always affects
the build platform, with `CC` also effecting the build platform for native
builds only when `CC_FOR_BUILD` is not defined.

This old behavior is inconsistent with the way Autotools works, which
undermines the purpose of distro-integration that is the only reason
environment variables are supported at all in Meson. The new behavior is
consistent.
2 changes: 1 addition & 1 deletion mesonbuild/backend/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ def run_postconf_scripts(self):
subprocess.check_call(cmd, env=child_env)

def create_install_data(self):
strip_bin = self.environment.binaries.host.lookup_entry('strip')
strip_bin = self.environment.lookup_binary_entry(MachineChoice.HOST, 'strip')
if strip_bin is None:
if self.environment.is_cross_build():
mlog.warning('Cross file does not specify strip binary, result will not be stripped.')
Expand Down
2 changes: 1 addition & 1 deletion mesonbuild/cmake/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def find_cmake_binary(self, environment: Environment, silent: bool = False) -> T
# Create an iterator of options
def search():
# Lookup in cross or machine file.
potential_cmakepath = environment.binaries[self.for_machine].lookup_entry('cmake')
potential_cmakepath = environment.lookup_binary_entry(self.for_machine, 'cmake')
if potential_cmakepath is not None:
mlog.debug('CMake binary for %s specified from cross file, native file, or env var as %s.', self.for_machine, potential_cmakepath)
yield ExternalProgram.from_entry('cmake', potential_cmakepath)
Expand Down
3 changes: 2 additions & 1 deletion mesonbuild/compilers/c.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from .. import coredata
from ..mesonlib import MachineChoice, MesonException, mlog, version_compare
from ..linkers import LinkerEnvVarsMixin
from .c_function_attributes import C_FUNC_ATTRIBUTES
from .mixins.clike import CLikeCompiler
from .mixins.ccrx import CcrxCompiler
Expand All @@ -27,7 +28,7 @@
from .mixins.clang import ClangCompiler
from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from .mixins.islinker import BasicLinkerIsCompilerMixin, LinkerEnvVarsMixin
from .mixins.islinker import BasicLinkerIsCompilerMixin
from .mixins.emscripten import EmscriptenMixin
from .compilers import (
gnu_winlibs,
Expand Down
62 changes: 30 additions & 32 deletions mesonbuild/compilers/compilers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
import typing as T
from functools import lru_cache

from ..linkers import StaticLinker, GnuLikeDynamicLinkerMixin, SolarisDynamicLinker
from ..linkers import (
GnuLikeDynamicLinkerMixin, LinkerEnvVarsMixin, SolarisDynamicLinker,
StaticLinker,
)
from .. import coredata
from .. import mlog
from .. import mesonlib
Expand All @@ -26,7 +29,7 @@
Popen_safe, split_args
)
from ..envconfig import (
Properties,
Properties, get_env_var
)

if T.TYPE_CHECKING:
Expand Down Expand Up @@ -75,7 +78,9 @@
clink_suffixes += ('h', 'll', 's')

# Languages that should use LDFLAGS arguments when linking.
languages_using_ldflags = ('objcpp', 'cpp', 'objc', 'c', 'fortran', 'd', 'cuda')
languages_using_ldflags = {'objcpp', 'cpp', 'objc', 'c', 'fortran', 'd', 'cuda'}
# Languages that should use CPPFLAGS arguments when linking.
languages_using_cppflags = {'c', 'cpp', 'objc', 'objcpp'}
soregex = re.compile(r'.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$')

# Environment variables that each lang uses.
Expand Down Expand Up @@ -825,8 +830,10 @@ def gen_import_library_args(self, implibname):
"""
return []

def get_linker_args_from_envvars(self) -> T.List[str]:
return self.linker.get_args_from_envvars()
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) -> T.Dict[str, coredata.UserOption]:
return {}
Expand Down Expand Up @@ -1178,37 +1185,27 @@ def get_largefile_args(compiler):
return []


def get_args_from_envvars(lang: str, use_linker_args: bool) -> T.Tuple[T.List[str], T.List[str]]:
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
"""
def log_var(var, val: T.Optional[str]):
if val:
mlog.log('Appending {} from environment: {!r}'.format(var, val))
else:
mlog.debug('No {} in the environment, not changing global flags.'.format(var))

if lang not in cflags_mapping:
return [], []

compile_flags = [] # type: T.List[str]
link_flags = [] # type: T.List[str]

env_compile_flags = os.environ.get(cflags_mapping[lang])
log_var(cflags_mapping[lang], env_compile_flags)
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:
# This is duplicated between the linkers, but I'm not sure how else
# to handle this
env_link_flags = split_args(os.environ.get('LDFLAGS', ''))
else:
env_link_flags = []
log_var('LDFLAGS', env_link_flags)
link_flags += env_link_flags
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
Expand All @@ -1217,16 +1214,18 @@ def log_var(var, val: T.Optional[str]):
link_flags = compile_flags + link_flags

# Pre-processor flags for certain languages
if lang in {'c', 'cpp', 'objc', 'objcpp'}:
env_preproc_flags = os.environ.get('CPPFLAGS')
log_var('CPPFLAGS', env_preproc_flags)
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],
def get_global_options(lang: str,
comp: T.Type[Compiler],
for_machine: MachineChoice,
is_cross: bool,
properties: Properties) -> T.Dict[str, coredata.UserOption]:
"""Retreive options that apply to all compilers for a given language."""
description = 'Extra arguments passed to the {}'.format(lang)
Expand All @@ -1239,13 +1238,12 @@ def get_global_options(lang: str, comp: T.Type[Compiler],
[], split_args=True, user_input=True, allow_dups=True),
}

if properties.fallback:
# Get from env vars.
# XXX: True here is a hack
compile_args, link_args = get_args_from_envvars(lang, comp.INVOKES_LINKER)
else:
compile_args = []
link_args = []
# Get from env vars.
compile_args, link_args = get_args_from_envvars(
lang,
for_machine,
is_cross,
comp.INVOKES_LINKER)

for k, o in opts.items():
if k in properties:
Expand Down
3 changes: 2 additions & 1 deletion mesonbuild/compilers/cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from .. import mlog
from ..mesonlib import MesonException, MachineChoice, version_compare

from ..linkers import LinkerEnvVarsMixin
from .compilers import (
gnu_winlibs,
msvc_winlibs,
Expand All @@ -36,7 +37,7 @@
from .mixins.clang import ClangCompiler
from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from .mixins.islinker import BasicLinkerIsCompilerMixin, LinkerEnvVarsMixin
from .mixins.islinker import BasicLinkerIsCompilerMixin
from .mixins.emscripten import EmscriptenMixin

if T.TYPE_CHECKING:
Expand Down
3 changes: 2 additions & 1 deletion mesonbuild/compilers/d.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
EnvironmentException, MachineChoice, version_compare,
)

from ..linkers import LinkerEnvVarsMixin
from .compilers import (
d_dmd_buildtype_args,
d_gdc_buildtype_args,
Expand All @@ -28,7 +29,7 @@
CompilerArgs,
)
from .mixins.gnu import GnuCompiler
from .mixins.islinker import LinkerEnvVarsMixin, BasicLinkerIsCompilerMixin
from .mixins.islinker import BasicLinkerIsCompilerMixin

if T.TYPE_CHECKING:
from ..envconfig import MachineInfo
Expand Down
12 changes: 0 additions & 12 deletions mesonbuild/compilers/mixins/islinker.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
classes for those cases.
"""

import os
import typing as T

from ... import mesonlib
Expand All @@ -30,17 +29,6 @@
from ...environment import Environment


class LinkerEnvVarsMixin:

"""Mixin reading LDFLAGS from the environment."""

def get_linker_args_from_envvars(self) -> T.List[str]:
flags = os.environ.get('LDFLAGS')
if not flags:
return []
return mesonlib.split_args(flags)


class BasicLinkerIsCompilerMixin:

"""Provides a baseline of methods that a linker would implement.
Expand Down
47 changes: 31 additions & 16 deletions mesonbuild/coredata.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2012-2019 The Meson development team
# Copyrighs 2012-2019 The Meson development team

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -22,6 +22,7 @@
MesonException, MachineChoice, PerMachine, OrderedSet,
default_libdir, default_libexecdir, default_prefix, split_args
)
from .envconfig import get_env_var_pair
from .wrap import WrapMode
import ast
import argparse
Expand Down Expand Up @@ -746,20 +747,29 @@ def set_default_options(self, default_options, subproject, env):
# Some options default to environment variables if they are
# unset, set those now. These will either be overwritten
# below, or they won't. These should only be set on the first run.
p_env = os.environ.get('PKG_CONFIG_PATH')
if p_env:
# PKG_CONFIG_PATH may contain duplicates, which must be
# removed, else a duplicates-in-array-option warning arises.
p_list = list(OrderedSet(p_env.split(':')))
if env.first_invocation:
options['pkg_config_path'] = p_list
elif options.get('pkg_config_path', []) != p_list:
mlog.warning(
'PKG_CONFIG_PATH environment variable has changed '
'between configurations, meson ignores this. '
'Use -Dpkg_config_path to change pkg-config search '
'path instead.'
)
for for_machine in MachineChoice:
p_env_pair = get_env_var_pair(for_machine, self.is_cross_build(), 'PKG_CONFIG_PATH')
if p_env_pair is not None:
p_env_var, p_env = p_env_pair

# PKG_CONFIG_PATH may contain duplicates, which must be
# removed, else a duplicates-in-array-option warning arises.
p_list = list(OrderedSet(p_env.split(':')))

key = 'pkg_config_path'
if for_machine == MachineChoice.BUILD:
key = 'build.' + key

if env.first_invocation:
options[key] = p_list
elif options.get(key, []) != p_list:
mlog.warning(
p_env_var +
' environment variable has changed '
'between configurations, meson ignores this. '
'Use -Dpkg_config_path to change pkg-config search '
'path instead.'
)

for k, v in env.cmd_line_options.items():
if subproject:
Expand All @@ -782,7 +792,12 @@ def add_lang_args(self, lang: str, comp: T.Type['Compiler'],
from .compilers import compilers

optprefix = lang + '_'
for k, o in compilers.get_global_options(lang, comp, env.properties[for_machine]).items():
for k, o in compilers.get_global_options(
lang,
comp,
for_machine,
env.is_cross_build(),
env.properties[for_machine]).items():
if not k.startswith(optprefix):
raise MesonException('Internal error, %s has incorrect prefix.' % k)
# prefixed compiler options affect just this machine
Expand Down
Loading

0 comments on commit 9ebede7

Please sign in to comment.