diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 28063316f..c28a8a4a6 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -390,13 +390,6 @@ class BuildTarget(Target): msg = 'Bad source of type {!r} in target {!r}.'.format(type(s).__name__, self.name) raise InvalidArguments(msg) - @staticmethod - def can_compile_sources(compiler, sources): - for s in sources: - if compiler.can_compile(s): - return True - return False - @staticmethod def can_compile_remove_sources(compiler, sources): removed = False @@ -442,13 +435,15 @@ class BuildTarget(Target): if not s.endswith(lang_suffixes['vala']): sources.append(s) if sources: - # Add compilers based on the above sources - for lang, compiler in compilers.items(): - # We try to be conservative because sometimes people add files - # in the list of sources that we can't determine the type based - # just on the suffix. - if self.can_compile_sources(compiler, sources): - self.compilers[lang] = compiler + # For each source, try to add one compiler that can compile it. + # It's ok if no compilers can do so, because users are expected to + # be able to add arbitrary non-source files to the sources list. + for s in sources: + for lang, compiler in compilers.items(): + if compiler.can_compile(s): + if lang not in self.compilers: + self.compilers[lang] = compiler + break else: # No source files, target consists of only object files of unknown # origin. Just add the first clike compiler that we have and hope diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 956221122..51eeafffe 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -14,6 +14,7 @@ import pickle, os, uuid from pathlib import PurePath +from collections import OrderedDict from .mesonlib import MesonException, commonpath from .mesonlib import default_libdir, default_libexecdir, default_prefix @@ -128,8 +129,8 @@ class CoreData: else: self.cross_file = None self.wrap_mode = options.wrap_mode - self.compilers = {} - self.cross_compilers = {} + self.compilers = OrderedDict() + self.cross_compilers = OrderedDict() self.deps = {} self.modules = {} # Only to print a warning if it changes between Meson invocations. diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 5d3c0956c..56e5b8f7a 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1752,10 +1752,22 @@ class Interpreter(InterpreterBase): self.coredata.compiler_options = new_options return comp, cross_comp + @staticmethod + def sort_clike(lang): + ''' + Sorting function to sort the list of languages according to + reversed(compilers.clike_langs) and append the unknown langs in the end. + The purpose is to prefer C over C++ for files that can be compiled by + both such as assembly, C, etc. Also applies to ObjC, ObjC++, etc. + ''' + if lang not in compilers.clike_langs: + return 1 + return -compilers.clike_langs.index(lang) + def add_languages(self, args, required): success = True need_cross_compiler = self.environment.is_cross_build() and self.environment.cross_info.need_cross_compiler() - for lang in args: + for lang in sorted(args, key=self.sort_clike): lang = lang.lower() if lang in self.coredata.compilers: comp = self.coredata.compilers[lang]