aboutsummaryrefslogtreecommitdiff
path: root/interpreter.py
diff options
context:
space:
mode:
Diffstat (limited to 'interpreter.py')
-rw-r--r--interpreter.py108
1 files changed, 72 insertions, 36 deletions
diff --git a/interpreter.py b/interpreter.py
index de3b199..60dd4d6 100644
--- a/interpreter.py
+++ b/interpreter.py
@@ -302,32 +302,54 @@ class GeneratedListHolder(InterpreterObject):
def add_file(self, a):
self.held_object.add_file(a)
-class Build(InterpreterObject):
+class BuildMachine(InterpreterObject):
def __init__(self):
InterpreterObject.__init__(self)
- self.methods.update({'name' : self.get_name_method,
+ self.methods.update({'name' : self.name_method,
+ 'endian' : self.endian_method,
})
- def get_name_method(self, args, kwargs):
+ # Python is inconsistent in its platform module.
+ # It returns different values for the same cpu.
+ # For x86 it might return 'x86', 'i686' or somesuch.
+ # Do some canonicalization.
+ def cpu_method(self, args, kwargs):
+ trial = platform.machine().lower()
+ if trial.startswith('i') and trial.endswith('86'):
+ return 'x86'
+ # This might be wrong. Maybe we should return the more
+ # specific string such as 'armv7l'. Need to get user
+ # feedback first.
+ if trial.startswith('arm'):
+ return 'arm'
+ # Add fixes here as bugs are reported.
+ return trial
+
+ def name_method(self, args, kwargs):
return platform.system().lower()
-# This currently returns data for the current environment.
-# It should return info for the target host.
-class Host(InterpreterObject):
- def __init__(self, envir):
+ def endian_method(self, args, kwargs):
+ return sys.byteorder
+
+# This class will provide both host_machine and
+# target_machine
+class CrossMachineInfo(InterpreterObject):
+ def __init__(self, cross_info):
InterpreterObject.__init__(self)
- self.environment = envir
- self.methods.update({'name' : self.get_name_method,
- 'is_big_endian' : self.is_big_endian_method,
+ self.info = cross_info
+ self.methods.update({'name' : self.name_method,
+ 'cpu' : self.cpu_method,
+ 'endian' : self.endian_method,
})
- def get_name_method(self, args, kwargs):
- if self.environment.is_cross_build():
- return self.environment.cross_info.get('name')
- return platform.system().lower()
+ def name_method(self, args, kwargs):
+ return self.info['name']
- def is_big_endian_method(self, args, kwargs):
- return sys.byteorder != 'little'
+ def cpu_method(self, args, kwargs):
+ return self.info['cpu']
+
+ def endian_method(self, args, kwargs):
+ return self.info['endian']
class IncludeDirsHolder(InterpreterObject):
def __init__(self, curdir, dirs):
@@ -734,9 +756,9 @@ 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):
- return 'exe_wrap' in self.build.environment.cross_info
- return True # This is semantically confusing.
+ 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.
def is_cross_build_method(self, args, kwargs):
return self.build.environment.is_cross_build()
@@ -778,7 +800,7 @@ class Interpreter():
self.subproject_dir = subproject_dir
option_file = os.path.join(self.source_root, self.subdir, 'meson_options.txt')
if os.path.exists(option_file):
- oi = optinterpreter.OptionInterpreter(self.subproject,\
+ oi = optinterpreter.OptionInterpreter(self.subproject, \
self.build.environment.cmd_line_options)
oi.process(option_file)
self.build.environment.merge_options(oi.options)
@@ -797,8 +819,20 @@ class Interpreter():
self.sanity_check_ast()
self.variables = {}
self.builtin = {}
- self.builtin['build'] = Build()
- self.builtin['host'] = Host(build.environment)
+ self.builtin['build_machine'] = BuildMachine()
+ if not self.build.environment.is_cross_build():
+ self.builtin['host_machine'] = self.builtin['build_machine']
+ self.builtin['target_machine'] = self.builtin['build_machine']
+ else:
+ cross_info = self.build.environment.cross_info
+ if cross_info.has_host():
+ self.builtin['host_machine'] = CrossMachineInfo(cross_info.config['host_machine'])
+ else:
+ self.builtin['host_machine'] = self.builtin['build_machine']
+ if cross_info.has_target():
+ self.builtin['target_machine'] = CrossMachineInfo(cross_info.config['target_machine'])
+ else:
+ self.builtin['target_machine'] = self.builtin['host_machine']
self.builtin['meson'] = MesonMain(build, self)
self.environment = build.environment
self.build_func_dict()
@@ -1155,7 +1189,7 @@ class Interpreter():
@stringArgs
def func_project(self, node, args, kwargs):
- if len(args)< 2:
+ if len(args) < 2:
raise InvalidArguments('Not enough arguments to project(). Needs at least the project name and one language')
if list(kwargs.keys()) != ['subproject_dir'] and len(kwargs) != 0:
raise InvalidArguments('project() only accepts the keyword argument "subproject_dir"')
@@ -1189,7 +1223,7 @@ class Interpreter():
arg = posargs[0]
if isinstance(arg, list):
- argstr = stringifyUserArguments(arg)
+ argstr = stringifyUserArguments(arg)
elif isinstance(arg, str):
argstr = arg
elif isinstance(arg, int):
@@ -1207,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:
@@ -1217,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)
@@ -1263,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])
@@ -1504,7 +1540,7 @@ class Interpreter():
@stringArgs
def func_install_subdir(self, node, args, kwargs):
- if len(args ) != 1:
+ if len(args) != 1:
raise InvalidArguments('Install_subdir requires exactly one argument.')
if not 'install_dir' in kwargs:
raise InvalidArguments('Missing keyword argument install_dir')