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.
pull/1171/head
Nirbheek Chauhan 8 years ago
parent 7b3d00fee4
commit 0fc4ad2a0b
  1. 2
      mesonbuild/backend/backends.py
  2. 59
      mesonbuild/build.py
  3. 11
      mesonbuild/compilers.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:

@ -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…
Cancel
Save