aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/backends.py13
-rw-r--r--mesonbuild/backend/ninjabackend.py8
-rw-r--r--mesonbuild/build.py16
-rw-r--r--mesonbuild/compilers/compilers.py6
-rw-r--r--mesonbuild/compilers/cpp.py6
-rw-r--r--test cases/d/10 d cpp/cppmain.cpp6
-rw-r--r--test cases/d/10 d cpp/dmain.d5
-rw-r--r--test cases/d/10 d cpp/libfile.cpp5
-rw-r--r--test cases/d/10 d cpp/libfile.d5
-rw-r--r--test cases/d/10 d cpp/meson.build13
10 files changed, 68 insertions, 15 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index ed7c118..6499105 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -318,21 +318,18 @@ class Backend:
self.write_benchmark_file(datafile)
return test_data, benchmark_data
- def determine_linker(self, target):
+ def determine_linker_and_stdlib_args(self, target):
'''
If we're building a static library, there is only one static linker.
Otherwise, we query the target for the dynamic linker.
'''
if isinstance(target, build.StaticLibrary):
if target.is_cross:
- return self.build.static_cross_linker
+ return self.build.static_cross_linker, []
else:
- return self.build.static_linker
- l = target.get_clike_dynamic_linker()
- if not l:
- m = "Couldn't determine linker for target {!r}"
- raise MesonException(m.format(target.name))
- return l
+ return self.build.static_linker, []
+ l, stdlib_args = target.get_clike_dynamic_linker_and_stdlibs()
+ return l, stdlib_args
def rpaths_for_bundled_shared_libraries(self, target):
paths = []
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 6dd04da..1d8d011 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -470,8 +470,8 @@ int dummy;
if is_unity:
for src in self.generate_unity_files(target, unity_src):
obj_list.append(self.generate_single_compile(target, outfile, src, True, unity_deps + header_deps))
- linker = self.determine_linker(target)
- elem = self.generate_link(target, outfile, outname, obj_list, linker, pch_objects)
+ linker, stdlib_args = self.determine_linker_and_stdlib_args(target)
+ elem = self.generate_link(target, outfile, outname, obj_list, linker, pch_objects, stdlib_args=stdlib_args)
self.generate_shlib_aliases(target, self.get_target_dir(target))
elem.write(outfile)
@@ -2485,7 +2485,7 @@ rule FORTRAN_DEP_HACK%s
return guessed_dependencies + absolute_libs
- def generate_link(self, target, outfile, outname, obj_list, linker, extra_args=[]):
+ def generate_link(self, target, outfile, outname, obj_list, linker, extra_args=[], stdlib_args=[]):
if isinstance(target, build.StaticLibrary):
linker_base = 'STATIC'
else:
@@ -2496,7 +2496,6 @@ rule FORTRAN_DEP_HACK%s
if target.is_cross:
crstr = '_CROSS'
linker_rule = linker_base + crstr + '_LINKER'
-
# Create an empty commands list, and start adding link arguments from
# various sources in the order in which they must override each other
# starting from hard-coded defaults followed by build options and so on.
@@ -2602,6 +2601,7 @@ rule FORTRAN_DEP_HACK%s
custom_target_libraries = self.get_custom_target_provided_libraries(target)
commands += extra_args
commands += custom_target_libraries
+ commands += stdlib_args # Standard library arguments go last, because they never depend on anything.
# Convert from GCC-style link argument naming to the naming used by the
# current compiler.
commands = commands.to_native()
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index a2d024a..5d1163b 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -989,6 +989,8 @@ You probably should put it in link_with instead.''')
langs = []
# Check if any of the external libraries were written in this language
for dep in self.external_deps:
+ if dep.language is None:
+ continue
if dep.language not in langs:
langs.append(dep.language)
# Check if any of the internal libraries this target links to were
@@ -999,7 +1001,7 @@ You probably should put it in link_with instead.''')
langs.append(language)
return langs
- def get_clike_dynamic_linker(self):
+ def get_clike_dynamic_linker_and_stdlibs(self):
'''
We use the order of languages in `clike_langs` to determine which
linker to use in case the target has sources compiled with multiple
@@ -1021,12 +1023,19 @@ You probably should put it in link_with instead.''')
for l in clike_langs:
if l in self.compilers or l in dep_langs:
try:
- return all_compilers[l]
+ linker = all_compilers[l]
except KeyError:
raise MesonException(
'Could not get a dynamic linker for build target {!r}. '
'Requires a linker for language "{}", but that is not '
'a project language.'.format(self.name, l))
+ stdlib_args = []
+ added_languages = set()
+ for dl in itertools.chain(self.compilers, dep_langs):
+ if dl != linker.language:
+ stdlib_args += all_compilers[dl].language_stdlib_only_link_flags()
+ added_languages.add(dl)
+ return linker, stdlib_args
m = 'Could not get a dynamic linker for build target {!r}'
raise AssertionError(m.format(self.name))
@@ -1049,7 +1058,8 @@ You probably should put it in link_with instead.''')
2. If the target contains only objects, process_compilers guesses and
picks the first compiler that smells right.
'''
- linker = self.get_clike_dynamic_linker()
+ linker, _ = self.get_clike_dynamic_linker_and_stdlibs()
+ # Mixing many languages with MSVC is not supported yet so ignore stdlibs.
if linker and linker.get_id() == 'msvc':
return True
return False
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index a2c6668..02faed2 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -938,6 +938,12 @@ class Compiler:
def openmp_flags(self):
raise EnvironmentException('Language %s does not support OpenMP flags.' % self.get_display_language())
+ def language_stdlib_only_link_flags(self):
+ # The linker flags needed to link the standard library of the current
+ # language in. This is needed in cases where you e.g. combine D and C++
+ # and both of which need to link their runtime library in or otherwise
+ # building fails with undefined symbols.
+ return []
GCC_STANDARD = 0
GCC_OSX = 1
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 4c48052..051f922 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -93,6 +93,9 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler):
def get_option_link_args(self, options):
return []
+ def language_stdlib_only_link_flags(self):
+ return ['-lstdc++']
+
class GnuCPPCompiler(GnuCompiler, CPPCompiler):
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrap, defines, **kwargs):
@@ -134,6 +137,9 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
def get_pch_use_args(self, pch_dir, header):
return ['-fpch-preprocess', '-include', os.path.basename(header)]
+ def language_stdlib_only_link_flags(self):
+ return ['-lstdc++']
+
class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler):
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None, **kwargs):
diff --git a/test cases/d/10 d cpp/cppmain.cpp b/test cases/d/10 d cpp/cppmain.cpp
new file mode 100644
index 0000000..aeddf56
--- /dev/null
+++ b/test cases/d/10 d cpp/cppmain.cpp
@@ -0,0 +1,6 @@
+extern void print_hello(int i);
+
+int main(int, char**) {
+ print_hello(1);
+ return 0;
+}
diff --git a/test cases/d/10 d cpp/dmain.d b/test cases/d/10 d cpp/dmain.d
new file mode 100644
index 0000000..bece25f
--- /dev/null
+++ b/test cases/d/10 d cpp/dmain.d
@@ -0,0 +1,5 @@
+extern (C++) void print_hello(int i);
+
+void main() {
+ print_hello(1);
+}
diff --git a/test cases/d/10 d cpp/libfile.cpp b/test cases/d/10 d cpp/libfile.cpp
new file mode 100644
index 0000000..2ea67fc
--- /dev/null
+++ b/test cases/d/10 d cpp/libfile.cpp
@@ -0,0 +1,5 @@
+#include<iostream>
+
+void print_hello(int i) {
+ std::cout << "Hello. Here is a number printed with C++: " << i << ".\n";
+}
diff --git a/test cases/d/10 d cpp/libfile.d b/test cases/d/10 d cpp/libfile.d
new file mode 100644
index 0000000..88cb53e
--- /dev/null
+++ b/test cases/d/10 d cpp/libfile.d
@@ -0,0 +1,5 @@
+import std.stdio;
+
+extern (C++) void print_hello(int i) {
+ writefln("Hello. Here is a number printed with D: %d", i);
+}
diff --git a/test cases/d/10 d cpp/meson.build b/test cases/d/10 d cpp/meson.build
new file mode 100644
index 0000000..eecb151
--- /dev/null
+++ b/test cases/d/10 d cpp/meson.build
@@ -0,0 +1,13 @@
+project('d and c++', 'd', 'cpp')
+
+cpp = meson.get_compiler('cpp')
+
+if cpp.get_id() == 'clang'
+ error('MESON_SKIP_TEST combining Clang C++ with GDC produces broken executables.')
+endif
+
+e1 = executable('dcpp', 'dmain.d', 'libfile.cpp')
+test('dcpp', e1)
+
+e2 = executable('cppd', 'cppmain.cpp', 'libfile.d')
+test('cppd', e2)