aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--manual tests/9 nostdlib/meson.build12
-rw-r--r--manual tests/9 nostdlib/subprojects/mylibc/meson.build5
-rw-r--r--mesonbuild/backend/backends.py1
-rw-r--r--mesonbuild/backend/ninjabackend.py15
-rw-r--r--mesonbuild/build.py1
-rw-r--r--mesonbuild/compilers.py6
-rw-r--r--mesonbuild/environment.py6
-rw-r--r--mesonbuild/interpreter.py35
8 files changed, 70 insertions, 11 deletions
diff --git a/manual tests/9 nostdlib/meson.build b/manual tests/9 nostdlib/meson.build
index ad5b7b9..3ef743e 100644
--- a/manual tests/9 nostdlib/meson.build
+++ b/manual tests/9 nostdlib/meson.build
@@ -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)
diff --git a/manual tests/9 nostdlib/subprojects/mylibc/meson.build b/manual tests/9 nostdlib/subprojects/mylibc/meson.build
index 9d1fed8..aa0184e 100644
--- a/manual tests/9 nostdlib/subprojects/mylibc/meson.build
+++ b/manual tests/9 nostdlib/subprojects/mylibc/meson.build
@@ -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('.')
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index ceb466b..29966b9 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -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)
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 201b2d1..ec07395 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -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,
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 63cdcf3..60b5ec0 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -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:
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index 8dee468..c4e8f0d 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -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]
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index c4591b4..19594c8 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -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):
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index d6a3a3e..b83f4a3 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -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):