aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/backends.py2
-rw-r--r--mesonbuild/build.py59
-rw-r--r--mesonbuild/compilers.py11
3 files changed, 63 insertions, 9 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 49b6008..91c5b0f 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -178,6 +178,8 @@ class Backend():
o = os.path.join(proj_dir_to_build_root,
self.build_to_src, target.get_subdir(), obj)
obj_list.append(o)
+ elif isinstance(obj, mesonlib.File):
+ obj_list.append(obj.rel_to_builddir(self.build_to_src))
elif isinstance(obj, build.ExtractedObjects):
obj_list += self.determine_ext_objs(obj, proj_dir_to_build_root)
else:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 50436d4..cc34d57 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -19,6 +19,7 @@ from . import mlog
import copy, os, re
from .mesonlib import File, flatten, MesonException, stringlistify, classify_unity_sources
from .environment import for_windows, for_darwin
+from .compilers import is_object, clike_langs, lang_suffixes
known_basic_kwargs = {'install' : True,
'c_pch' : True,
@@ -283,7 +284,14 @@ class BuildTarget():
self.extra_args = {}
self.generated = []
self.extra_files = []
+ # Sources can be:
+ # 1. Pre-existing source files in the source tree
+ # 2. Pre-existing sources generated by configure_file in the build tree
+ # 3. Sources files generated by another target or a Generator
self.process_sourcelist(sources)
+ # Objects can be:
+ # 1. Pre-existing objects provided by the user with the `objects:` kwarg
+ # 2. Compiled objects created by and extracted from another target
self.process_objectlist(objects)
self.process_kwargs(kwargs, environment)
self.check_unknown_kwargs(kwargs)
@@ -373,19 +381,56 @@ class BuildTarget():
return removed
def process_compilers(self):
- if len(self.sources) + len(self.generated) == 0:
+ '''
+ Populate self.compilers, which is the list of compilers that this
+ target will use for compiling all its sources.
+ We also add compilers that were used by extracted objects to simplify
+ dynamic linker determination.
+ '''
+ if len(self.sources) + len(self.generated) + len(self.objects) == 0:
return
- sources = list(self.sources)
- for gensrc in self.generated:
- sources += gensrc.get_outputs()
# Populate list of compilers
if self.is_cross:
compilers = self.environment.coredata.cross_compilers
else:
compilers = self.environment.coredata.compilers
- for lang, compiler in compilers.items():
- if self.can_compile_sources(compiler, sources):
- self.compilers[lang] = compiler
+ # Pre-existing sources
+ sources = list(self.sources)
+ # All generated sources
+ for gensrc in self.generated:
+ for s in gensrc.get_outputs():
+ # Generated objects can't be compiled, so don't use them for
+ # compiler detection. If our target only has generated objects,
+ # we will fall back to using the first c-like compiler we find,
+ # which is what we need.
+ if not is_object(s):
+ sources.append(s)
+ # Sources that were used to create our extracted objects
+ for o in self.objects:
+ if not isinstance(o, ExtractedObjects):
+ continue
+ for s in o.srclist:
+ # Don't add Vala sources since that will pull in the Vala
+ # compiler even though we will never use it since we are
+ # dealing with compiled C code.
+ 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
+ else:
+ # No source files, target consists of only object files of unknown
+ # origin. Just add the first clike compiler that we have and hope
+ # that it can link these objects
+ for lang in clike_langs:
+ if lang in compilers:
+ self.compilers[lang] = compilers[lang]
+ break
# If all our sources are Vala, our target also needs the C compiler but
# it won't get added above.
if 'vala' in self.compilers and 'c' not in self.compilers:
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index aa53444..a1dbbb3 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -45,8 +45,15 @@ lang_suffixes = {
}
cpp_suffixes = lang_suffixes['cpp'] + ('h',)
c_suffixes = lang_suffixes['c'] + ('h',)
-clike_suffixes = lang_suffixes['c'] + lang_suffixes['cpp'] + ('h',)
-
+# List of languages that can be linked with C code directly by the linker
+# used in build.py:process_compilers() and build.py:get_dynamic_linker()
+clike_langs = ('objcpp', 'objc', 'd', 'cpp', 'c', 'fortran',)
+clike_suffixes = ()
+for l in clike_langs:
+ clike_suffixes += lang_suffixes[l]
+clike_suffixes += ('h',)
+
+# These are used in backend/backends.py:generated_target()
def is_header(fname):
if hasattr(fname, 'fname'):
fname = fname.fname