aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Builtin-options.md6
-rw-r--r--docs/markdown/snippets/per-project-compiler-options.md9
-rw-r--r--mesonbuild/ast/introspection.py11
-rw-r--r--mesonbuild/interpreter/interpreter.py10
-rw-r--r--test cases/common/223 persubproject options/main.cpp3
-rw-r--r--test cases/common/223 persubproject options/meson.build12
-rw-r--r--test cases/common/223 persubproject options/subprojects/sub1/meson.build3
-rw-r--r--test cases/common/223 persubproject options/subprojects/sub2/foo.cpp10
-rw-r--r--test cases/common/223 persubproject options/subprojects/sub2/meson.build10
9 files changed, 67 insertions, 7 deletions
diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md
index c8e98dd..a7a6a89 100644
--- a/docs/markdown/Builtin-options.md
+++ b/docs/markdown/Builtin-options.md
@@ -220,6 +220,12 @@ Since *0.54.0* The `<lang>_thread_count` option can be used to control
the value passed to `-s PTHREAD_POOL_SIZE` when using emcc. No other
c/c++ compiler supports this option.
+Since *0.63.0* all compiler options can be set per subproject, see
+[here](#specifying-options-per-subproject) for details on how the default value
+is inherited from main project. This is useful for example when the main project
+requires C++11 but a subproject requires C++14. The `cpp_std` value from
+subproject's `default_options` is now respected.
+
## Specifying options per machine
Since *0.51.0*, some options are specified per machine rather than
diff --git a/docs/markdown/snippets/per-project-compiler-options.md b/docs/markdown/snippets/per-project-compiler-options.md
new file mode 100644
index 0000000..1ccd9b8
--- /dev/null
+++ b/docs/markdown/snippets/per-project-compiler-options.md
@@ -0,0 +1,9 @@
+## Compiler options can be set per subproject
+
+All compiler options can now be set per subproject. See
+[here](Build-options.md#specifying-options-per-subproject) for details on how
+the default value is inherited from main project.
+
+This is useful for example when the main project requires C++11 but a subproject
+requires C++14. The `cpp_std` value from subproject's `default_options` is now
+respected.
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py
index af29542..55c3bcc 100644
--- a/mesonbuild/ast/introspection.py
+++ b/mesonbuild/ast/introspection.py
@@ -27,6 +27,7 @@ from ..compilers import detect_compiler_for
import typing as T
import os
import argparse
+import copy
build_target_functions = ['executable', 'jar', 'library', 'shared_library', 'shared_module', 'static_library', 'both_libraries']
@@ -163,7 +164,15 @@ class IntrospectionInterpreter(AstInterpreter):
for lang in sorted(langs, key=compilers.sort_clink):
lang = lang.lower()
if lang not in self.coredata.compilers[for_machine]:
- detect_compiler_for(self.environment, lang, for_machine)
+ comp = detect_compiler_for(self.environment, lang, for_machine)
+ if self.subproject:
+ options = {}
+ for k in comp.get_options():
+ v = copy.copy(self.coredata.options[k])
+ k = k.evolve(subproject=self.subproject)
+ options[k] = v
+ self.coredata.add_compiler_options(options, lang, for_machine, self.environment)
+
def func_dependency(self, node: BaseNode, args: T.List[TYPE_nvar], kwargs: T.Dict[str, TYPE_nvar]) -> None:
args = self.flatten_args(args)
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index ecbfd7a..15d7d32 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -88,6 +88,7 @@ import collections
import typing as T
import textwrap
import importlib
+import copy
if T.TYPE_CHECKING:
import argparse
@@ -1382,6 +1383,15 @@ external dependencies (including libraries) must go to "dependencies".''')
else:
raise
+ # Add per-subproject compiler options. They inherit value from main project.
+ if self.subproject:
+ options = {}
+ for k in comp.get_options():
+ v = copy.copy(self.coredata.options[k])
+ k = k.evolve(subproject=self.subproject)
+ options[k] = v
+ self.coredata.add_compiler_options(options, lang, for_machine, self.environment)
+
if for_machine == MachineChoice.HOST or self.environment.is_cross_build():
logger_fun = mlog.log
else:
diff --git a/test cases/common/223 persubproject options/main.cpp b/test cases/common/223 persubproject options/main.cpp
new file mode 100644
index 0000000..214f02b
--- /dev/null
+++ b/test cases/common/223 persubproject options/main.cpp
@@ -0,0 +1,3 @@
+int foo();
+
+int main(void) { return foo(); }
diff --git a/test cases/common/223 persubproject options/meson.build b/test cases/common/223 persubproject options/meson.build
index b9cbfe2..25a0100 100644
--- a/test cases/common/223 persubproject options/meson.build
+++ b/test cases/common/223 persubproject options/meson.build
@@ -1,14 +1,20 @@
-project('persubproject options', 'c',
+project('persubproject options', 'c', 'cpp',
default_options : ['werror=true',
- 'warning_level=3'])
+ 'warning_level=3',
+ 'cpp_std=c++11'])
assert(get_option('default_library') == 'both', 'Parent default_library should be "both"')
assert(get_option('werror'))
assert(get_option('warning_level') == '3')
+assert(get_option('cpp_std') == 'c++11')
+
# Check it build both by calling a method only both_libraries target implement
lib = library('lib1', 'foo.c')
lib.get_static_lib()
subproject('sub1')
-subproject('sub2', default_options : ['default_library=static'])
+
+libcpp14_dep = dependency('libcpp14', fallback: 'sub2', default_options : ['default_library=static'])
+exe = executable('test1', 'main.cpp', dependencies : libcpp14_dep)
+test('mixing-cpp-version', exe)
diff --git a/test cases/common/223 persubproject options/subprojects/sub1/meson.build b/test cases/common/223 persubproject options/subprojects/sub1/meson.build
index 4e4bc1b..fb72837 100644
--- a/test cases/common/223 persubproject options/subprojects/sub1/meson.build
+++ b/test cases/common/223 persubproject options/subprojects/sub1/meson.build
@@ -1,8 +1,9 @@
-project('sub1', 'c',
+project('sub1', 'c', 'cpp',
default_options : ['warning_level=0'])
assert(get_option('default_library') == 'both', 'Should inherit parent project default_library')
assert(get_option('warning_level') == '0')
+assert(get_option('cpp_std') == 'c++11')
# Check it build both by calling a method only both_libraries target implement
lib = library('lib1', 'foo.c')
diff --git a/test cases/common/223 persubproject options/subprojects/sub2/foo.cpp b/test cases/common/223 persubproject options/subprojects/sub2/foo.cpp
new file mode 100644
index 0000000..27d1720
--- /dev/null
+++ b/test cases/common/223 persubproject options/subprojects/sub2/foo.cpp
@@ -0,0 +1,10 @@
+#include <memory>
+
+class Dummy {
+ int x;
+};
+
+int foo() {
+ auto obj = std::make_unique<Dummy>();
+ return 0;
+}
diff --git a/test cases/common/223 persubproject options/subprojects/sub2/meson.build b/test cases/common/223 persubproject options/subprojects/sub2/meson.build
index f1226b8..cf1435a 100644
--- a/test cases/common/223 persubproject options/subprojects/sub2/meson.build
+++ b/test cases/common/223 persubproject options/subprojects/sub2/meson.build
@@ -1,10 +1,16 @@
-project('sub2', 'c',
+project('sub2', 'c', 'cpp',
default_options : ['default_library=shared',
- 'werror=false'])
+ 'werror=false',
+ 'cpp_std=c++14'])
assert(get_option('default_library') == 'static', 'Parent should override default_library')
assert(not get_option('werror'))
+assert(get_option('cpp_std') == 'c++14')
# If it doesn't build only a static library, it would make target name clash.
library('lib1', 'foo.c')
shared_library('lib1', 'foo.c')
+
+# Parent project is c++11 but this one uses c++14 to build.
+libcpp14 = library('lib2', 'foo.cpp')
+meson.override_dependency('libcpp14', declare_dependency(link_with: libcpp14))