Skip to content

Commit

Permalink
Support target-only cross compilation properly.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpakkane committed Jul 26, 2015
1 parent 37b2a19 commit 30d0c22
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 21 deletions.
2 changes: 1 addition & 1 deletion backends.py
Expand Up @@ -246,7 +246,7 @@ def write_test_file(self, datafile):
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:
Expand Down
12 changes: 12 additions & 0 deletions 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'
13 changes: 11 additions & 2 deletions environment.py
Expand Up @@ -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)
Expand Down Expand Up @@ -627,3 +631,8 @@ def has_host(self):

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
26 changes: 14 additions & 12 deletions interpreter.py
Expand Up @@ -756,7 +756,7 @@ def build_root_method(self, args, kwargs):
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.

Expand Down Expand Up @@ -1241,7 +1241,7 @@ def func_error(self, node, args, kwargs):
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:
Expand All @@ -1251,39 +1251,39 @@ def add_languages(self, node, args):
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)
Expand All @@ -1297,9 +1297,11 @@ def add_languages(self, node, args):
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])
Expand Down
4 changes: 2 additions & 2 deletions meson.py
Expand Up @@ -128,8 +128,8 @@ def generate(self):
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
Expand Down
25 changes: 21 additions & 4 deletions ninjabackend.py
Expand Up @@ -773,7 +773,10 @@ def generate_static_link_rules(self, is_cross, outfile):
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
Expand All @@ -790,7 +793,15 @@ def generate_static_link_rules(self, is_cross, outfile):
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()
Expand Down Expand Up @@ -982,7 +993,13 @@ def generate_compile_rules(self, outfile):
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)
Expand Down Expand Up @@ -1267,7 +1284,7 @@ def generate_shsym(self, outfile, target):
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)

Expand Down

0 comments on commit 30d0c22

Please sign in to comment.