aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2021-02-16 10:48:20 -0800
committerNirbheek Chauhan <nirbheek@centricular.com>2021-02-20 15:38:08 +0530
commit849b84f65a6b786b3daadd12d69edac0e20c3296 (patch)
treefb6b95705382789d96a44bde81c2b9564ba17e8f
parent8c29249157a35f0209ab76ddf2970bed04c92d43 (diff)
downloadmeson-849b84f65a6b786b3daadd12d69edac0e20c3296.zip
meson-849b84f65a6b786b3daadd12d69edac0e20c3296.tar.gz
meson-849b84f65a6b786b3daadd12d69edac0e20c3296.tar.bz2
Environment: Fix passing envrionment variables CPPFLAGS and CFLAGS
Or other language flags that use CPPFLAGS (like CXXFLAGS). The problem here is actually rather simple, `dict.setdefault()` doesn't work like I thought it did, I thought it created a weak entry, but it actually is equivalent to: ```python if k not in dict: dict[k] = v ``` Instead we'll use an intermediate dictionary (a default dictionary actually, since that makes things a little cleaner) and then add the keys from that dict to self.options as applicable. Test case written by Jussi, Fix by Dylan Co-authored-by: Jussi Pakkanen Fixes: #8361 Fixes: #8345
-rw-r--r--mesonbuild/environment.py19
-rw-r--r--mesonbuild/mesonlib/universal.py1
-rwxr-xr-xrun_unittests.py8
-rw-r--r--test cases/unit/90 multiple envvars/meson.build4
-rw-r--r--test cases/unit/90 multiple envvars/prog.c18
-rw-r--r--test cases/unit/90 multiple envvars/prog.cpp18
6 files changed, 60 insertions, 8 deletions
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index b12728b..7e9118e 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -788,6 +788,8 @@ class Environment:
]
)
+ env_opts: T.DefaultDict[OptionKey, T.List[str]] = collections.defaultdict(list)
+
for (evar, keyname), for_machine in itertools.product(opts, MachineChoice):
p_env = _get_env_var(for_machine, self.is_cross_build(), evar)
if p_env is not None:
@@ -805,7 +807,7 @@ class Environment:
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
+ p_list = [e for e in p_list if e] # filter out any empty elements
# Take env vars only on first invocation, if the env changes when
# reconfiguring it gets ignored.
@@ -816,18 +818,21 @@ class Environment:
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)
+ env_opts[key].extend(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)
+ env_opts[key].extend(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)
+ env_opts[key].extend(p_list)
+
+ # Only store options that are not already in self.options,
+ # otherwise we'd override the machine files
+ for k, v in env_opts.items():
+ if k not in self.options:
+ self.options[k] = v
def _set_default_binaries_from_env(self) -> None:
"""Set default binaries from the environment.
diff --git a/mesonbuild/mesonlib/universal.py b/mesonbuild/mesonlib/universal.py
index 7deb24a..19e329d 100644
--- a/mesonbuild/mesonlib/universal.py
+++ b/mesonbuild/mesonlib/universal.py
@@ -2023,7 +2023,6 @@ class OptionKey:
This takes strings like `mysubproject:build.myoption` and Creates an
OptionKey out of them.
"""
-
try:
subproject, raw2 = raw.split(':')
except ValueError:
diff --git a/run_unittests.py b/run_unittests.py
index 0bd6d4b..3aa1cb3 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -5476,6 +5476,14 @@ class AllPlatformTests(BasePlatformTests):
projinfo = self.introspect('--projectinfo')
self.assertEqual(projinfo['version'], '1.0.0')
+ def test_cflags_cppflags(self):
+ envs = {'CPPFLAGS': '-DCPPFLAG',
+ 'CFLAGS': '-DCFLAG',
+ 'CXXFLAGS': '-DCXXFLAG'}
+ srcdir = os.path.join(self.unit_test_dir, '90 multiple envvars')
+ self.init(srcdir, override_envvars=envs)
+ self.build()
+
class FailureTests(BasePlatformTests):
'''
diff --git a/test cases/unit/90 multiple envvars/meson.build b/test cases/unit/90 multiple envvars/meson.build
new file mode 100644
index 0000000..ac57611
--- /dev/null
+++ b/test cases/unit/90 multiple envvars/meson.build
@@ -0,0 +1,4 @@
+project('multienv', 'c', 'cpp')
+
+executable('cexe', 'prog.c')
+executable('cppexe', 'prog.cpp')
diff --git a/test cases/unit/90 multiple envvars/prog.c b/test cases/unit/90 multiple envvars/prog.c
new file mode 100644
index 0000000..38d3c12
--- /dev/null
+++ b/test cases/unit/90 multiple envvars/prog.c
@@ -0,0 +1,18 @@
+#include<stdio.h>
+
+#ifndef CPPFLAG
+#error CPPFLAG not set
+#endif
+
+#ifndef CFLAG
+#error CFLAGS not set
+#endif
+
+#ifdef CXXFLAG
+#error CXXFLAG is set
+#endif
+
+int main(int argc, char **argv) {
+ printf("%d %s\n", argc, argv[0]);
+ return 0;
+}
diff --git a/test cases/unit/90 multiple envvars/prog.cpp b/test cases/unit/90 multiple envvars/prog.cpp
new file mode 100644
index 0000000..61ccf3a
--- /dev/null
+++ b/test cases/unit/90 multiple envvars/prog.cpp
@@ -0,0 +1,18 @@
+#include<cstdio>
+
+#ifndef CPPFLAG
+#error CPPFLAG not set
+#endif
+
+#ifdef CFLAG
+#error CFLAG is set
+#endif
+
+#ifndef CXXFLAG
+#error CXXFLAG not set
+#endif
+
+int main(int argc, char **argv) {
+ printf("%d %s\n", argc, argv[0]);
+ return 0;
+}