diff options
Diffstat (limited to 'interpreter.py')
-rw-r--r-- | interpreter.py | 108 |
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') |