aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2017-03-12 22:13:26 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2017-04-02 00:07:23 +0300
commit319398f0749890a57a661ddb4524e93f86a0d41e (patch)
tree526d876fe6bc78f6411ea31dcb188bbe925202ce
parentcf97c7af813ef39a7edf0693a4b127d30ad9cc55 (diff)
downloadmeson-319398f0749890a57a661ddb4524e93f86a0d41e.zip
meson-319398f0749890a57a661ddb4524e93f86a0d41e.tar.gz
meson-319398f0749890a57a661ddb4524e93f86a0d41e.tar.bz2
Proxy object for overriding options transparently.
-rw-r--r--mesonbuild/backend/backends.py22
-rw-r--r--mesonbuild/backend/ninjabackend.py11
-rw-r--r--mesonbuild/coredata.py1
-rwxr-xr-xrun_unittests.py19
-rw-r--r--test cases/unit/6 std override/meson.build8
-rw-r--r--test cases/unit/6 std override/prog03.cpp6
-rw-r--r--test cases/unit/6 std override/prog11.cpp6
-rw-r--r--test cases/unit/6 std override/progp.cpp6
8 files changed, 77 insertions, 2 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 93a75ec..e8cbe5d 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -76,6 +76,24 @@ class TestSerialisation:
self.workdir = workdir
self.extra_paths = extra_paths
+class OptionProxy:
+ def __init__(self, name, value):
+ self.name = name
+ self.value = value
+
+class OptionOverrideProxy:
+ '''Mimic an option list but transparently override
+selected option values.'''
+ def __init__(self, overrides, options):
+ self.overrides = overrides
+ self.options = options
+
+ def __getitem__(self, option_name):
+ base_opt = self.options[option_name]
+ if option_name in self.overrides:
+ return OptionProxy(base_opt.name, base_opt.validate_value(self.overrides[option_name]))
+ return base_opt
+
# This class contains the basic functionality that is needed by all backends.
# Feel free to move stuff in and out of it as you see fit.
class Backend:
@@ -348,6 +366,8 @@ class Backend:
# various sources in the order in which they must override each other
# starting from hard-coded defaults followed by build options and so on.
commands = CompilerArgs(compiler)
+
+ copt_proxy = OptionOverrideProxy(target.option_overrides, self.environment.coredata.compiler_options)
# First, the trivial ones that are impossible to override.
#
# Add -nostdinc/-nostdinc++ if needed; can't be overriden
@@ -368,7 +388,7 @@ class Backend:
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(self.environment.coredata.compiler_options)
+ commands += compiler.get_option_compile_args(copt_proxy)
# Add buildtype args: optimization level, debugging, etc.
commands += compiler.get_buildtype_args(self.get_option_for_target('buildtype', target))
# Add compile args added using add_project_arguments()
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index e1e239f..d54cacf 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1810,13 +1810,15 @@ rule FORTRAN_DEP_HACK
return incs
def _generate_single_compile(self, target, compiler, is_generated=False):
+ base_proxy = backends.OptionOverrideProxy(target.option_overrides,
+ self.environment.coredata.base_options)
# Create an empty commands list, and start adding arguments from
# various sources in the order in which they must override each other
commands = CompilerArgs(compiler)
# Add compiler args for compiling this target derived from 'base' build
# options passed on the command-line, in default_options, etc.
# These have the lowest priority.
- commands += compilers.get_base_compile_args(self.environment.coredata.base_options,
+ commands += compilers.get_base_compile_args(base_proxy,
compiler)
# The code generated by valac is usually crap and has tons of unused
# variables and such, so disable warnings for Vala C sources.
@@ -1888,6 +1890,13 @@ rule FORTRAN_DEP_HACK
raise AssertionError('BUG: sources should not contain headers {!r}'.format(src))
if isinstance(src, RawFilename) and src.fname.endswith('.h'):
raise AssertionError('BUG: sources should not contain headers {!r}'.format(src.fname))
+ extra_orderdeps = []
+ compiler = get_compiler_for_source(target.compilers.values(), src)
+
+ if isinstance(src, str) and src.endswith('.h'):
+ raise AssertionError('BUG: sources should not contain headers {!r}'.format(src))
+ if isinstance(src, RawFilename) and src.fname.endswith('.h'):
+ raise AssertionError('BUG: sources should not contain headers {!r}'.format(src.fname))
compiler = get_compiler_for_source(target.compilers.values(), src)
key = (target, compiler, is_generated)
if key in self.target_arg_cache:
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 1d770e0..dce1d1d 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -102,6 +102,7 @@ class UserComboOption(UserOption):
def validate_value(self, value):
if value not in self.choices:
raise MesonException('Value %s not one of accepted values.' % value)
+ return value
class UserStringArrayOption(UserOption):
def __init__(self, name, description, value, **kwargs):
diff --git a/run_unittests.py b/run_unittests.py
index 66f8205..4d38b61 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1262,6 +1262,25 @@ class LinuxlikeTests(BasePlatformTests):
self.assertEqual(0, statf.st_uid)
+ def test_cpp_std_override(self):
+ testdir = os.path.join(self.unit_test_dir, '6 std override')
+ self.init(testdir)
+ compdb = self.get_compdb()
+ for i in compdb:
+ if 'prog03' in i['file']:
+ c03_comp = i['command']
+ if 'prog11' in i['file']:
+ c11_comp = i['command']
+ if 'progp' in i['file']:
+ plain_comp = i['command']
+ self.assertNotEqual(len(plain_comp), 0)
+ self.assertIn('-std=c++03', c03_comp)
+ self.assertNotIn('-std=c++11', c03_comp)
+ self.assertIn('-std=c++11', c11_comp)
+ self.assertNotIn('-std=c++03', c11_comp)
+ self.assertNotIn('-std=c++03', plain_comp)
+ self.assertNotIn('-std=c++11', plain_comp)
+
class RewriterTests(unittest.TestCase):
def setUp(self):
diff --git a/test cases/unit/6 std override/meson.build b/test cases/unit/6 std override/meson.build
new file mode 100644
index 0000000..35af1e8
--- /dev/null
+++ b/test cases/unit/6 std override/meson.build
@@ -0,0 +1,8 @@
+project('cpp std override', 'cpp',
+ default_options : 'cpp_std=c++03')
+
+executable('plain', 'progp.cpp',
+ override_options : 'cpp_std=none')
+executable('v03', 'prog03.cpp')
+executable('v11', 'prog11.cpp',
+ override_options : 'cpp_std=c++11')
diff --git a/test cases/unit/6 std override/prog03.cpp b/test cases/unit/6 std override/prog03.cpp
new file mode 100644
index 0000000..d30abc9
--- /dev/null
+++ b/test cases/unit/6 std override/prog03.cpp
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(int argc, char **argv) {
+ std::cout << "I am a c++03 test program.\n";
+ return 0;
+}
diff --git a/test cases/unit/6 std override/prog11.cpp b/test cases/unit/6 std override/prog11.cpp
new file mode 100644
index 0000000..dde1fc0
--- /dev/null
+++ b/test cases/unit/6 std override/prog11.cpp
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(int argc, char **argv) {
+ std::cout << "I am a C++11 test program.\n";
+ return 0;
+}
diff --git a/test cases/unit/6 std override/progp.cpp b/test cases/unit/6 std override/progp.cpp
new file mode 100644
index 0000000..b9bd97f
--- /dev/null
+++ b/test cases/unit/6 std override/progp.cpp
@@ -0,0 +1,6 @@
+#include<iostream>
+
+int main(int argc, char **argv) {
+ std::cout << "I am a test program of undefined C++ standard.\n";
+ return 0;
+}