Can specify a stdlib subproject that is used implicitly on all targets with said language.

pull/542/head
Jussi Pakkanen 9 years ago
parent 695aa0b8c2
commit afe7252476
  1. 12
      manual tests/9 nostdlib/meson.build
  2. 5
      manual tests/9 nostdlib/subprojects/mylibc/meson.build
  3. 1
      mesonbuild/backend/backends.py
  4. 15
      mesonbuild/backend/ninjabackend.py
  5. 1
      mesonbuild/build.py
  6. 6
      mesonbuild/compilers.py
  7. 6
      mesonbuild/environment.py
  8. 35
      mesonbuild/interpreter.py

@ -2,13 +2,9 @@ project('own libc', 'c')
# A simple project that uses its own libc.
libc_proj = subproject('mylibc')
libc_dep = libc_proj.get_variable('mylibc_dep')
exe = executable('selfcontained', 'prog.c',
c_args : '-nostdlib',
link_args : '-nostdlib',
dependencies : libc_dep,
)
# Note that we don't need to specify anything, the flags to use
# stdlib come from the cross file.
exe = executable('selfcontained', 'prog.c')
test('standalone test', exe)

@ -2,10 +2,9 @@ project('own libc', 'c')
# A very simple libc implementation
# Start with manual flags to compile, then add platform support.
# Do not specify -nostdlib & co. They come from cross specifications.
libc = static_library('c', 'libc.c', 'stubstart.s',
)
libc = static_library('c', 'libc.c', 'stubstart.s')
mylibc_dep = declare_dependency(link_with : libc,
include_directories : include_directories('.')

@ -244,6 +244,7 @@ class Backend():
def generate_basic_compiler_args(self, target, compiler):
commands = []
commands += self.get_cross_stdlib_args(target, compiler)
commands += compiler.get_always_args()
commands += compiler.get_warn_args(self.environment.coredata.get_builtin_option('warning_level'))
commands += compiler.get_option_compile_args(self.environment.coredata.compiler_options)

@ -1427,6 +1427,13 @@ rule FORTRAN_DEP_HACK
mod_files.append(os.path.join(dirname, mod_name))
return mod_files
def get_cross_stdlib_args(self, target, compiler):
if not target.is_cross:
return []
if self.environment.cross_info.has_stdlib(compiler.language):
return []
return compiler.get_no_stdinc_args()
def generate_single_compile(self, target, outfile, src, is_generated=False, header_deps=[], order_deps=[]):
if(isinstance(src, str) and src.endswith('.h')):
raise RuntimeError('Fug')
@ -1632,6 +1639,13 @@ rule FORTRAN_DEP_HACK
elem.add_item('CROSS', '--cross-host=' + self.environment.cross_info.config['host_machine']['system'])
elem.write(outfile)
def get_cross_stdlib_link_args(self, target, linker):
if isinstance(target, build.StaticLibrary) or not target.is_cross:
return []
if not self.environment.cross_info.has_stdlib(linker.language):
return []
return linker.get_no_stdlib_link_args()
def generate_link(self, target, outfile, outname, obj_list, linker, extra_args=[]):
if isinstance(target, build.StaticLibrary):
linker_base = 'STATIC'
@ -1645,6 +1659,7 @@ rule FORTRAN_DEP_HACK
linker_rule = linker_base + crstr + '_LINKER'
abspath = os.path.join(self.environment.get_build_dir(), target.subdir)
commands = []
commands += self.get_cross_stdlib_link_args(target, linker)
commands += linker.get_linker_always_args()
if not isinstance(target, build.StaticLibrary):
commands += compilers.get_base_link_args(self.environment.coredata.base_options,

@ -102,6 +102,7 @@ class Build:
self.install_dirs = []
self.dep_manifest_name = None
self.dep_manifest = {}
self.cross_stdlibs = {}
def has_language(self, language):
for i in self.compilers:

@ -311,6 +311,12 @@ class CCompiler(Compiler):
def get_always_args(self):
return []
def get_no_stdinc_args(self):
return ['-nostdinc']
def get_no_stdlib_link_args(self):
return ['-nostdlib']
def get_warn_args(self, level):
return self.warn_args[level]

@ -716,6 +716,12 @@ class CrossBuildInfo():
def has_target(self):
return 'target_machine' in self.config
def has_stdlib(self, language):
return language + '_stdlib' in self.config['properties']
def get_stdlib(self, language):
return self.config['properties'][language + '_stdlib']
# Wehn compiling a cross compiler we use the native compiler for everything.
# But not when cross compiling a cross compiler.
def need_cross_compiler(self):

@ -1080,6 +1080,22 @@ class Interpreter():
if not isinstance(first, mparser.FunctionNode) or first.func_name != 'project':
raise InvalidCode('First statement must be a call to project')
def check_cross_stdlibs(self):
if self.build.environment.is_cross_build():
cross_info = self.build.environment.cross_info
for c in self.build.cross_compilers:
l = c.language
try:
di = mesonlib.stringlistify(cross_info.get_stdlib(l))
if len(di) != 2:
raise InterpreterException('Stdlib definition for %s should have exactly two elements.' \
% l)
projname, depname = di
subproj = self.do_subproject(projname, {})
self.build.cross_stdlibs[l] = subproj.get_variable_method([depname], {})
except KeyError as e:
pass
def run(self):
self.evaluate_codeblock(self.ast)
mlog.log('Build targets in project:', mlog.bold(str(len(self.build.targets))))
@ -1422,6 +1438,8 @@ class Interpreter():
if 'vala' in langs:
if not 'c' in langs:
raise InterpreterException('Compiling Vala requires C. Add C to your project languages and rerun Meson.')
if not self.is_subproject():
self.check_cross_stdlibs()
@stringArgs
def func_add_languages(self, node, args, kwargs):
@ -1991,11 +2009,28 @@ class Interpreter():
mlog.debug('Unknown target type:', str(targetholder))
raise RuntimeError('Unreachable code')
target = targetclass(name, self.subdir, self.subproject, is_cross, sources, objs, self.environment, kwargs)
if is_cross:
self.add_cross_stdlib_info(target)
l = targetholder(target, self)
self.add_target(name, l.held_object)
self.global_args_frozen = True
return l
def get_used_languages(self, target):
result = {}
for i in target.sources:
for c in self.build.compilers:
if c.can_compile(i):
result[c.language] = True
break
return result
def add_cross_stdlib_info(self, target):
for l in self.get_used_languages(target):
if self.environment.cross_info.has_stdlib(l) and \
self.subproject != self.environment.cross_info.get_stdlib(l)[0]:
target.add_external_deps(self.build.cross_stdlibs[l])
def check_sources_exist(self, subdir, sources):
for s in sources:
if not isinstance(s, str):

Loading…
Cancel
Save