diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2018-04-25 22:25:55 +0300 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2018-05-02 22:50:15 +0300 |
commit | 1918c0d231f0c04b1a57c2fdf057b50c8aa7312b (patch) | |
tree | 074fd9ede2fe8ee8c3e63822b1c89de39cd967ff /mesonbuild | |
parent | 77b72e8573bbd8d6d04cb11aacdba604b8649f4d (diff) | |
download | meson-1918c0d231f0c04b1a57c2fdf057b50c8aa7312b.zip meson-1918c0d231f0c04b1a57c2fdf057b50c8aa7312b.tar.gz meson-1918c0d231f0c04b1a57c2fdf057b50c8aa7312b.tar.bz2 |
Can combine D and C++ in a single target. Closes #3125.
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/backend/backends.py | 13 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 8 | ||||
-rw-r--r-- | mesonbuild/build.py | 16 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 6 | ||||
-rw-r--r-- | mesonbuild/compilers/cpp.py | 6 |
5 files changed, 34 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): |