Also use objects to populate target compilers
This avoids us having no compilers at all for targets that are composed entirely of objects with no sources. Now we will always have a compiler for a target even if it is composed entirely of objects generated with custom targets unless it has completely unknown sources.
This commit is contained in:
parent
7b3d00fee4
commit
0fc4ad2a0b
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue