aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2015-07-26 23:50:04 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2015-07-27 00:55:28 +0300
commit30d0c2292fee831d74f080e62c1c74990ea76abb (patch)
tree7f704fc6be20119e95ccf083066d00f619993bc0
parent37b2a195bd24d71044474129cdf4af3540770618 (diff)
downloadmeson-30d0c2292fee831d74f080e62c1c74990ea76abb.zip
meson-30d0c2292fee831d74f080e62c1c74990ea76abb.tar.gz
meson-30d0c2292fee831d74f080e62c1c74990ea76abb.tar.bz2
Support target-only cross compilation properly.
-rw-r--r--backends.py2
-rw-r--r--cross/ubuntu-faketarget.txt12
-rw-r--r--environment.py13
-rw-r--r--interpreter.py26
-rwxr-xr-xmeson.py4
-rw-r--r--ninjabackend.py25
6 files changed, 61 insertions, 21 deletions
diff --git a/backends.py b/backends.py
index 3338c7e..e554488 100644
--- a/backends.py
+++ b/backends.py
@@ -246,7 +246,7 @@ class Backend():
fname = exe.fullpath
else:
fname = [os.path.join(self.environment.get_build_dir(), self.get_target_filename(t.get_exe()))]
- is_cross = self.environment.is_cross_build()
+ is_cross = self.environment.is_cross_build() and self.environment.cross_info.need_cross_compiler()
if is_cross:
exe_wrapper = self.environment.cross_info.config['binaries'].get('exe_wrapper', None)
else:
diff --git a/cross/ubuntu-faketarget.txt b/cross/ubuntu-faketarget.txt
new file mode 100644
index 0000000..5d7ba0d
--- /dev/null
+++ b/cross/ubuntu-faketarget.txt
@@ -0,0 +1,12 @@
+# This is a setup for compiling a program that runs natively
+# but produces output that runs on a different platform.
+# That is either a cross compiler or something like binutils.
+
+# We don't need to specify any properties or compilers,
+# for we use the native ones and can run the resulting
+# binaries directly.
+
+[target_machine]
+name='linux'
+cpu='mips'
+endian='little'
diff --git a/environment.py b/environment.py
index 82c909e..c594776 100644
--- a/environment.py
+++ b/environment.py
@@ -590,10 +590,14 @@ class CrossBuildInfo():
def __init__(self, filename):
self.config = {}
self.parse_datafile(filename)
+ if 'target_machine' in self.config:
+ return
+ if not 'host_machine' in self.config:
+ raise coredata.MesonException('Cross info file must have either host or a target machine.')
if not 'properties' in self.config:
- raise EnvironmentError('Cross file is missing "properties".')
+ raise coredata.MesonException('Cross file is missing "properties".')
if not 'binaries' in self.config:
- raise EnvironmentError('Cross file is missing "binaries".')
+ raise coredata.MesonException('Cross file is missing "binaries".')
def ok_type(self, i):
return isinstance(i, str) or isinstance(i, int) or isinstance(i, bool)
@@ -627,3 +631,8 @@ class CrossBuildInfo():
def has_target(self):
return 'target_machine' in self.config
+
+ # 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):
+ return 'host_machine' in self.config
diff --git a/interpreter.py b/interpreter.py
index acee7ba..eb56b91 100644
--- a/interpreter.py
+++ b/interpreter.py
@@ -756,7 +756,7 @@ class MesonMain(InterpreterObject):
return self.interpreter.environment.build_dir
def has_exe_wrapper_method(self, args, kwargs):
- if self.is_cross_build_method(None, None):
+ if self.is_cross_build_method(None, None) and 'binaries' in self.build.environment.cross_info.config:
return 'exe_wrap' in self.build.environment.cross_info.config['binaries']
return True # This is semantically confusing.
@@ -1241,7 +1241,7 @@ class Interpreter():
raise InterpreterException('Error encountered: ' + args[0])
def add_languages(self, node, args):
- is_cross = self.environment.is_cross_build()
+ need_cross_compiler = self.environment.is_cross_build() and self.environment.cross_info.need_cross_compiler()
for lang in args:
lang = lang.lower()
if lang in self.coredata.compilers:
@@ -1251,39 +1251,39 @@ class Interpreter():
cross_comp = None
if lang == 'c':
comp = self.environment.detect_c_compiler(False)
- if is_cross:
+ if need_cross_compiler:
cross_comp = self.environment.detect_c_compiler(True)
elif lang == 'cpp':
comp = self.environment.detect_cpp_compiler(False)
- if is_cross:
+ if need_cross_compiler:
cross_comp = self.environment.detect_cpp_compiler(True)
elif lang == 'objc':
comp = self.environment.detect_objc_compiler(False)
- if is_cross:
+ if need_cross_compiler:
cross_comp = self.environment.detect_objc_compiler(True)
elif lang == 'objcpp':
comp = self.environment.detect_objcpp_compiler(False)
- if is_cross:
+ if need_cross_compiler:
cross_comp = self.environment.detect_objcpp_compiler(True)
elif lang == 'java':
comp = self.environment.detect_java_compiler()
- if is_cross:
+ if need_cross_compiler:
cross_comp = comp # Java is platform independent.
elif lang == 'cs':
comp = self.environment.detect_cs_compiler()
- if is_cross:
+ if need_cross_compiler:
cross_comp = comp # C# is platform independent.
elif lang == 'vala':
comp = self.environment.detect_vala_compiler()
- if is_cross:
+ if need_cross_compiler:
cross_comp = comp # Vala is too (I think).
elif lang == 'rust':
comp = self.environment.detect_rust_compiler()
- if is_cross:
+ if need_cross_compiler:
cross_comp = comp # FIXME, probably not correct.
elif lang == 'fortran':
comp = self.environment.detect_fortran_compiler(False)
- if is_cross:
+ if need_cross_compiler:
cross_comp = self.environment.detect_fortran_compiler(True)
else:
raise InvalidCode('Tried to use unknown language "%s".' % lang)
@@ -1297,9 +1297,11 @@ class Interpreter():
self.coredata.external_args[comp.get_language()] = ext_compile_args
self.coredata.external_link_args[comp.get_language()] = ext_link_args
self.build.add_compiler(comp)
- if is_cross:
+ if need_cross_compiler:
mlog.log('Cross %s compiler: ' % lang, mlog.bold(' '.join(cross_comp.get_exelist())), ' (%s %s)' % (cross_comp.id, cross_comp.version), sep='')
self.build.add_cross_compiler(cross_comp)
+ if self.environment.is_cross_build() and not need_cross_compiler:
+ self.build.add_cross_compiler(comp)
def func_find_program(self, node, args, kwargs):
self.validate_arguments(args, 1, [str])
diff --git a/meson.py b/meson.py
index 6d37c68..b2e8f3a 100755
--- a/meson.py
+++ b/meson.py
@@ -128,8 +128,8 @@ itself as required.'''
intr = interpreter.Interpreter(b)
mlog.log('Build machine cpu:', mlog.bold(intr.builtin['build_machine'].cpu_method([], {})))
if env.is_cross_build():
- mlog.log('Host machine cpu:', mlog.bold(intr.builtin['host_machine'].info['cpu']))
- mlog.log('Target machine cpu:', mlog.bold(intr.builtin['target_machine'].info['cpu']))
+ mlog.log('Host machine cpu:', mlog.bold(intr.builtin['host_machine'].cpu_method([], {})))
+ mlog.log('Target machine cpu:', mlog.bold(intr.builtin['target_machine'].cpu_method([], {})))
intr.run()
if self.options.backend == 'ninja':
import ninjabackend
diff --git a/ninjabackend.py b/ninjabackend.py
index ecdecb9..9781990 100644
--- a/ninjabackend.py
+++ b/ninjabackend.py
@@ -773,7 +773,10 @@ class NinjaBackend(backends.Backend):
if not is_cross:
self.generate_java_link(outfile)
if is_cross:
- static_linker = self.build.static_cross_linker
+ if self.environment.cross_info.need_cross_compiler():
+ static_linker = self.build.static_cross_linker
+ else:
+ static_linker = self.build.static_linker
crstr = '_CROSS'
else:
static_linker = self.build.static_linker
@@ -790,7 +793,15 @@ class NinjaBackend(backends.Backend):
outfile.write(description)
def generate_dynamic_link_rules(self, outfile):
- ctypes = [(self.build.compilers, False), (self.build.cross_compilers, True)]
+ ctypes = [(self.build.compilers, False)]
+ if self.environment.is_cross_build():
+ if self.environment.cross_info.need_cross_compiler():
+ ctypes.append((self.build.cross_compilers, True))
+ else:
+ # Native compiler masquerades as the cross compiler.
+ ctypes.append((self.build.compilers, True))
+ else:
+ ctypes.append((self.build.cross_compilers, True))
for (complist, is_cross) in ctypes:
for compiler in complist:
langname = compiler.get_language()
@@ -982,7 +993,13 @@ rule FORTRAN_DEP_HACK
self.generate_compile_rule_for(langname, compiler, qstr, False, outfile)
self.generate_pch_rule_for(langname, compiler, qstr, False, outfile)
if self.environment.is_cross_build():
- for compiler in self.build.cross_compilers:
+ # In case we are going a target-only build, make the native compilers
+ # masquerade as cross compilers.
+ if self.environment.cross_info.need_cross_compiler():
+ cclist = self.build.cross_compilers
+ else:
+ cclist = self.build.compilers
+ for compiler in cclist:
langname = compiler.get_language()
self.generate_compile_rule_for(langname, compiler, qstr, True, outfile)
self.generate_pch_rule_for(langname, compiler, qstr, True, outfile)
@@ -1267,7 +1284,7 @@ rule FORTRAN_DEP_HACK
targetdir = self.get_target_private_dir(target)
symname = os.path.join(targetdir, target_name + '.symbols')
elem = NinjaBuildElement(symname, 'SHSYM', target_name)
- if self.environment.is_cross_build():
+ if self.environment.is_cross_build() and self.environment.cross_info.need_cross_compiler():
elem.add_item('CROSS', '--cross-host=' + self.environment.cross_info.config['host_machine']['name'])
elem.write(outfile)