diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md index b7b8a6408a55..c666f4f9648c 100644 --- a/docs/markdown/Builtin-options.md +++ b/docs/markdown/Builtin-options.md @@ -223,7 +223,7 @@ available on all platforms or with all compilers: | b_staticpic | true | true, false | Build static libraries as position independent | | b_pie | false | true, false | Build position-independent executables (since 0.49.0) | | b_vscrt | from_buildtype | none, md, mdd, mt, mtd, from_buildtype, static_from_buildtype | VS runtime library to use (since 0.48.0) (static_from_buildtype since 0.56.0) | -| b_tasking_mil_link | false | true, false | Use MIL linking for the TASKING VX-tools compiler family (since 1.?.?) | +| b_tasking_mil_link | false | true, false | Use MIL linking for the TASKING VX-tools compiler family (since 1.4.0) | The value of `b_sanitize` can be one of: `none`, `address`, `thread`, `undefined`, `memory`, `leak`, `address,undefined`, but note that some diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md index 4d9cbc1befe1..20ebc17d21f5 100644 --- a/docs/markdown/Reference-tables.md +++ b/docs/markdown/Reference-tables.md @@ -52,7 +52,7 @@ These are return values of the `get_id` (Compiler family) and | cctc | TASKING VX-toolset for TriCore compiler | | | ccarm | TASKING VX-toolset for ARM compiler | | | cc51 | TASKING VX-toolset for 8051 compiler | | -| ccmsc | TASKING VX-toolset for MCS compiler | | +| ccmcs | TASKING VX-toolset for MCS compiler | | | ccpcp | TASKING VX-toolset for PCP compiler | | ## Linker ids diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 1eeda96a8ce8..a3f9d8e4e71a 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -245,7 +245,7 @@ def _quoter(x: NinjaCommandArg, qf: T.Callable[[str], str] = quote_func) -> str: def write(self, outfile: T.TextIO) -> None: rspfile_args = self.args rspfile_quote_func: T.Callable[[str], str] - if self.rspfile_quote_style is RSPFileSyntax.MSVC: + if self.rspfile_quote_style in {RSPFileSyntax.MSVC, RSPFileSyntax.TASKING}: rspfile_quote_func = cmd_quote rspfile_args = [NinjaCommandArg('$in_newline', arg.quoting) if arg.s == '$in' else arg for arg in rspfile_args] else: @@ -260,7 +260,10 @@ def rule_iter() -> T.Iterable[str]: for rsp in rule_iter(): outfile.write(f'rule {self.name}{rsp}\n') if rsp == '_RSP': - outfile.write(' command = {} @$out.rsp\n'.format(' '.join([self._quoter(x) for x in self.command]))) + if self.rspfile_quote_style is RSPFileSyntax.TASKING: + outfile.write(' command = {} --option-file=$out.rsp\n'.format(' '.join([self._quoter(x) for x in self.command]))) + else: + outfile.write(' command = {} @$out.rsp\n'.format(' '.join([self._quoter(x) for x in self.command]))) outfile.write(' rspfile = $out.rsp\n') outfile.write(' rspfile_content = {}\n'.format(' '.join([self._quoter(x, rspfile_quote_func) for x in rspfile_args]))) else: @@ -412,7 +415,7 @@ def write(self, outfile: T.TextIO) -> None: outfile.write(line) if use_rspfile: - if self.rule.rspfile_quote_style is RSPFileSyntax.MSVC: + if self.rule.rspfile_quote_style in {RSPFileSyntax.MSVC, RSPFileSyntax.TASKING}: qf = cmd_quote else: qf = gcc_rsp_quote @@ -726,6 +729,12 @@ def generate_compdb(self) -> None: for ext in ['', '_RSP']] rules += [f"{rule}{ext}" for rule in [self.compiler_to_pch_rule_name(compiler)] for ext in ['', '_RSP']] + # Add custom MIL link rules to get the files compiled by the TASKING compiler family to MIL files included in the database + key = OptionKey('b_tasking_mil_link') + if key in compiler.base_options: + rule = self.get_compiler_rule_name('tasking_mil_compile', compiler.for_machine) + rules.append(rule) + rules.append(f'{rule}_RSP') compdb_options = ['-x'] if mesonlib.version_compare(self.ninja_version, '>=1.9') else [] ninja_compdb = self.ninja_command + ['-t', 'compdb'] + compdb_options + rules builddir = self.environment.get_build_dir() @@ -1071,8 +1080,19 @@ def generate_target(self, target) -> None: # Skip the link stage for this special type of target return linker, stdlib_args = self.determine_linker_and_stdlib_args(target) - if isinstance(target, build.StaticLibrary) and target.prelink: + # For prelinking and TASKING mil linking there needs to be an additional link target and the object list is modified + if not isinstance(target, build.StaticLibrary): + final_obj_list = obj_list + elif target.prelink: final_obj_list = self.generate_prelink(target, obj_list) + elif 'c' in target.compilers: + key = OptionKey('b_tasking_mil_link') + if key not in target.get_options() or key not in target.compilers['c'].base_options: + final_obj_list = obj_list + elif target.get_option(key): + final_obj_list = self.generate_mil_link(target, obj_list) + else: + final_obj_list = obj_list else: final_obj_list = obj_list elem = self.generate_link(target, outname, final_obj_list, linker, pch_objects, stdlib_args=stdlib_args) @@ -2476,6 +2496,33 @@ def generate_llvm_ir_compile_rule(self, compiler) -> None: self.add_rule(NinjaRule(rule, command, args, description, **options)) self.created_llvm_ir_rule[compiler.for_machine] = True + def generate_tasking_mil_compile_rules(self, compiler: Compiler) -> None: + rule = self.get_compiler_rule_name('tasking_mil_compile', compiler.for_machine) + depargs = NinjaCommandArg.list(compiler.get_dependency_gen_args('$out', '$DEPFILE'), Quoting.none) + command = compiler.get_exelist() + args = ['$ARGS'] + depargs + NinjaCommandArg.list(compiler.get_output_args('$out'), Quoting.none) + ['-cm', '$in'] + description = 'Compiling to C object $in' + if compiler.get_argument_syntax() == 'msvc': + deps = 'msvc' + depfile = None + else: + deps = 'gcc' + depfile = '$DEPFILE' + + options = self._rsp_options(compiler) + + self.add_rule(NinjaRule(rule, command, args, description, **options, deps=deps, depfile=depfile)) + + def generate_tasking_mil_link_rules(self, compiler: Compiler) -> None: + rule = self.get_compiler_rule_name('tasking_mil_link', compiler.for_machine) + command = compiler.get_exelist() + args = ['$ARGS', '--mil-link'] + NinjaCommandArg.list(compiler.get_output_args('$out'), Quoting.none) + ['-c', '$in'] + description = 'MIL linking object $out' + + options = self._rsp_options(compiler) + + self.add_rule(NinjaRule(rule, command, args, description, **options)) + def generate_compile_rule_for(self, langname: str, compiler: Compiler) -> None: if langname == 'java': self.generate_java_compile_rule(compiler) @@ -2566,6 +2613,9 @@ def generate_compile_rules(self) -> None: for langname, compiler in clist.items(): if compiler.get_id() == 'clang': self.generate_llvm_ir_compile_rule(compiler) + if OptionKey('b_tasking_mil_link') in compiler.base_options: + self.generate_tasking_mil_compile_rules(compiler) + self.generate_tasking_mil_link_rules(compiler) self.generate_compile_rule_for(langname, compiler) self.generate_pch_rule_for(langname, compiler) for mode in compiler.get_modes(): @@ -3008,6 +3058,11 @@ def generate_single_compile(self, target: build.BuildTarget, src, else: raise InvalidArguments(f'Invalid source type: {src!r}') obj_basename = self.object_filename_from_source(target, src) + # If mil linking is enabled for the target, then compilation output has to be MIL files instead of object files + if compiler.get_language() == 'c': + key = OptionKey('b_tasking_mil_link') + if key in compiler.base_options and target.get_option(key) and src.rsplit('.', 1)[1] in compilers.lang_suffixes['c']: + obj_basename = f'{os.path.splitext(obj_basename)[0]}.mil' rel_obj = os.path.join(self.get_target_private_dir(target), obj_basename) dep_file = compiler.depfile_for_object(rel_obj) @@ -3028,8 +3083,14 @@ def generate_single_compile(self, target: build.BuildTarget, src, i = os.path.join(self.get_target_private_dir(target), compiler.get_pch_name(pchlist[0])) arr.append(i) pch_dep = arr - - compiler_name = self.compiler_to_rule_name(compiler) + # If TASKING compiler family is used and MIL linking is enabled for the target, + # then compilation rule name is a special one to output MIL files + # instead of object files for .c files + key = OptionKey('b_tasking_mil_link') + if key in compiler.base_options and target.get_option(key) and src.rsplit('.', 1)[1] in compilers.lang_suffixes['c']: + compiler_name = self.get_compiler_rule_name('tasking_mil_compile', compiler.for_machine) + else: + compiler_name = self.compiler_to_rule_name(compiler) extra_deps = [] if compiler.get_language() == 'fortran': # Can't read source file to scan for deps if it's generated later @@ -3414,6 +3475,29 @@ def generate_prelink(self, target, obj_list): self.add_build(elem) return [prelink_name] + def generate_mil_link(self, target: build.StaticLibrary, obj_list: T.List[str]) -> T.List[str]: + assert isinstance(target, build.StaticLibrary) + + mil_linked_name = os.path.join(self.get_target_private_dir(target), target.name + '-mil_link.o') + mil_link_list = [] + obj_file_list = [] + for obj in obj_list: + if obj.endswith('.mil'): + mil_link_list.append(obj) + else: + obj_file_list.append(obj) + obj_file_list.append(mil_linked_name) + compiler = get_compiler_for_source(target.compilers.values(), mil_link_list[0][:-3] + '.c') + commands = self._generate_single_compile_base_args(target, compiler) + commands += self._generate_single_compile_target_args(target, compiler) + commands = commands.compiler.compiler_args(commands) + + elem = NinjaBuildElement(self.all_outputs, [mil_linked_name], self.get_compiler_rule_name('tasking_mil_link', compiler.for_machine), mil_link_list) + elem.add_item('ARGS', commands) + self.add_build(elem) + + return obj_file_list + def generate_link(self, target: build.BuildTarget, outname, obj_list, linker: T.Union['Compiler', 'StaticLinker'], extra_args=None, stdlib_args=None): extra_args = extra_args if extra_args is not None else [] stdlib_args = stdlib_args if stdlib_args is not None else [] @@ -3445,6 +3529,9 @@ def generate_link(self, target: build.BuildTarget, outname, obj_list, linker: T. linker, isinstance(target, build.SharedModule), self.environment.get_build_dir()) + # Add --mil-link if the option is enabled + if isinstance(target, build.Executable) and 'c' in target.compilers and OptionKey('b_tasking_mil_link') in target.get_options(): + commands += target.compilers['c'].get_tasking_mil_link_args(target.get_option(OptionKey('b_tasking_mil_link'))) # Add -nostdlib if needed; can't be overridden commands += self.get_no_stdlib_link_args(target, linker) # Add things like /NOLOGO; usually can't be overridden diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 5eff0ed805c5..6dacd206ba44 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -2008,6 +2008,8 @@ def post_init(self) -> None: elif ('c' in self.compilers and self.compilers['c'].get_id() in {'mwccarm', 'mwcceppc'} or 'cpp' in self.compilers and self.compilers['cpp'].get_id() in {'mwccarm', 'mwcceppc'}): self.suffix = 'nef' + elif ('c' in self.compilers and self.compilers['c'].get_id() in {'cctc', 'ccarm', 'cc51', 'ccmcs', 'ccpcp'}): + self.suffix = 'elf' else: self.suffix = machine.get_exe_suffix() self.filename = self.name diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 819ef8bb8628..bd917dcf952d 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -27,6 +27,7 @@ from .mixins.emscripten import EmscriptenMixin from .mixins.metrowerks import MetrowerksCompiler from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args +from .mixins.tasking import TaskingCompiler from .compilers import ( gnu_winlibs, msvc_winlibs, @@ -822,3 +823,27 @@ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str] if std != 'none': args.append('-lang ' + std) return args + +class _TaskingCCompiler(TaskingCompiler, CCompiler): + def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): + CCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, + info, linker=linker, full_version=full_version) + TaskingCompiler.__init__(self) + +class TaskingTricoreCCompiler(_TaskingCCompiler): + id = 'cctc' + +class TaskingArmCCompiler(_TaskingCCompiler): + id = 'ccarm' + +class Tasking8051CCompiler(_TaskingCCompiler): + id = 'cc51' + +class TaskingMCSCCompiler(_TaskingCCompiler): + id = 'ccmcs' + +class TaskingPCPCCompiler(_TaskingCCompiler): + id = 'ccpcp' diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index b9605ccaedcb..39d1ee7054aa 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -247,6 +247,7 @@ def init_option(self, name: OptionKey) -> options._U: OptionKey('b_bitcode'): BaseOption(options.UserBooleanOption, 'Generate and embed bitcode (only macOS/iOS/tvOS)', False), OptionKey('b_vscrt'): BaseOption(options.UserComboOption, 'VS run-time library type to use.', 'from_buildtype', choices=MSCRT_VALS + ['from_buildtype', 'static_from_buildtype']), + OptionKey('b_tasking_mil_link'): BaseOption(options.UserBooleanOption, 'Use TASKING compiler families MIL linking feature', False), } base_options = {key: base_opt.init_option(key) for key, base_opt in BASE_OPTIONS.items()} @@ -1350,6 +1351,13 @@ def get_preprocessor(self) -> Compiler: def form_compileropt_key(self, basename: str) -> OptionKey: return OptionKey(f'{self.language}_{basename}', machine=self.for_machine) + def get_tasking_mil_link_args(self, option_enabled: bool) -> T.List[str]: + """ + Argument for enabling TASKING's MIL link feature, + for most compilers, this will return nothing. + """ + return [] + def get_global_options(lang: str, comp: T.Type[Compiler], for_machine: MachineChoice, diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py index 22c5cb5aa17d..c840c3c5aea6 100644 --- a/mesonbuild/compilers/detect.py +++ b/mesonbuild/compilers/detect.py @@ -240,6 +240,17 @@ def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker return linkers.MetrowerksStaticLinkerARM(linker) else: return linkers.MetrowerksStaticLinkerEmbeddedPowerPC(linker) + if 'TASKING VX-toolset' in err: + if 'TriCore' in err: + return linkers.TaskingTricoreStaticLinker(linker) + if 'ARM' in err: + return linkers.TaskingARMStaticLinker(linker) + if '8051' in err: + return linkers.Tasking8051StaticLinker(linker) + if 'PCP' in err: + return linkers.TaskingPCPStaticLinker(linker) + else: + return linkers.TaskingMCSStaticLinker(linker) if p.returncode == 0: return linkers.ArLinker(compiler.for_machine, linker) if p.returncode == 1 and err.startswith('usage'): # OSX @@ -605,6 +616,38 @@ def sanitize(p: T.Optional[str]) -> T.Optional[str]: return cls( ccache, compiler, compiler_version, for_machine, is_cross, info, full_version=full_version, linker=linker) + if 'TASKING VX-toolset' in err: + if 'TriCore' in err or 'AURIX Development Studio' in err: + cls = c.TaskingTricoreCCompiler + lnk = linkers.TaskingTricoreLinker + elif 'ARM' in err: + cls = c.TaskingArmCCompiler + lnk = linkers.TaskingARMLinker + elif '8051' in err: + cls = c.Tasking8051CCompiler + lnk = linkers.Tasking8051Linker + elif 'PCP' in err: + cls = c.TaskingPCPCCompiler + lnk = linkers.TaskingPCPLinker + elif 'MCS' in err: + cls = c.TaskingMCSCCompiler + lnk = linkers.TaskingMCSLinker + else: + raise EnvironmentException('Failed to detect linker for TASKING VX-toolset compiler. Please update your cross file(s).') + + tasking_ver_match = re.search(r'v([0-9]+)\.([0-9]+)r([0-9]+) Build ([0-9]+)', err) + assert tasking_ver_match is not None, 'for mypy' + tasking_version = '.'.join(x for x in tasking_ver_match.groups() if x is not None) + + env.coredata.add_lang_args(cls.language, cls, for_machine, env) + ld = env.lookup_binary_entry(for_machine, cls.language + '_ld') + if ld is None: + raise MesonException(f'{cls.language}_ld was not properly defined in your cross file') + + linker = lnk(ld, for_machine, version=tasking_version) + return cls( + ccache, compiler, tasking_version, for_machine, is_cross, info, + full_version=full_version, linker=linker) _handle_exceptions(popen_exceptions, compilers) raise EnvironmentException(f'Unknown compiler {compilers}') diff --git a/mesonbuild/compilers/mixins/tasking.py b/mesonbuild/compilers/mixins/tasking.py new file mode 100644 index 000000000000..7675dbc75329 --- /dev/null +++ b/mesonbuild/compilers/mixins/tasking.py @@ -0,0 +1,126 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2012-2023 The Meson development team +from __future__ import annotations + +"""Representations specific to the TASKING embedded C/C++ compiler family.""" + +import os +import typing as T + +from ...mesonlib import EnvironmentException +from ...options import OptionKey + +if T.TYPE_CHECKING: + from ...compilers.compilers import Compiler +else: + # This is a bit clever, for mypy we pretend that these mixins descend from + # Compiler, so we get all of the methods and attributes defined for us, but + # for runtime we make them descend from object (which all classes normally + # do). This gives us DRYer type checking, with no runtime impact + Compiler = object + +tasking_buildtype_args: T.Mapping[str, T.List[str]] = { + 'plain': [], + 'debug': [], + 'debugoptimized': [], + 'release': [], + 'minsize': [], + 'custom': [] +} + +tasking_optimization_args: T.Mapping[str, T.List[str]] = { + 'plain': [], + '0': ['-O0'], + 'g': ['-O1'], # There is no debug specific level, O1 is recommended by the compiler + '1': ['-O1'], + '2': ['-O2'], + '3': ['-O3'], + 's': ['-Os'] +} + +tasking_debug_args: T.Mapping[bool, T.List[str]] = { + False: [], + True: ['-g3'] +} + +class TaskingCompiler(Compiler): + ''' + Functionality that is common to all TASKING family compilers. + ''' + + LINKER_PREFIX = '-Wl' + + def __init__(self) -> None: + if not self.is_cross: + raise EnvironmentException(f'{id} supports only cross-compilation.') + + self.base_options = { + OptionKey(o) for o in [ + 'b_tasking_mil_link', + 'b_staticpic', + 'b_ndebug' + ] + } + + default_warn_args = [] # type: T.List[str] + self.warn_args = {'0': [], + '1': default_warn_args, + '2': default_warn_args + [], + '3': default_warn_args + [], + 'everything': default_warn_args + []} # type: T.Dict[str, T.List[str]] + # TODO: add additional compilable files so that meson can detect it + self.can_compile_suffixes.add('asm') + + def get_pic_args(self) -> T.List[str]: + return ['--pic'] + + def get_buildtype_args(self, buildtype: str) -> T.List[str]: + return tasking_buildtype_args[buildtype] + + def get_debug_args(self, is_debug: bool) -> T.List[str]: + return tasking_debug_args[is_debug] + + def get_compile_only_args(self) -> T.List[str]: + return ['-c'] + + def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: + return [f'--dep-file={outfile}'] + + def get_depfile_suffix(self) -> str: + return 'dep' + + def get_no_stdinc_args(self) -> T.List[str]: + return ['--no-stdinc'] + + def get_werror_args(self) -> T.List[str]: + return ['--warnings-as-errors'] + + def get_no_stdlib_link_args(self) -> T.List[str]: + return ['--no-default-libraries'] + + def get_output_args(self, outputname: str) -> T.List[str]: + return ['-o', outputname] + + def get_include_args(self, path: str, is_system: bool) -> T.List[str]: + if path == '': + path = '.' + return ['-I' + path] + + def get_optimization_args(self, optimization_level: str) -> T.List[str]: + return tasking_optimization_args[optimization_level] + + def get_no_optimization_args(self) -> T.List[str]: + return ['-O0'] + + def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], build_dir: str) -> T.List[str]: + for idx, i in enumerate(parameter_list): + if i[:2] == '-I' or i[:2] == '-L': + parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) + + return parameter_list + + def get_tasking_mil_link_args(self, option_enabled: bool) -> T.List[str]: + return ['--mil-link'] if option_enabled else [] + + def get_preprocess_only_args(self) -> T.List[str]: + return ['-E'] diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index 86bad9be23ee..1ecdf2a71c6e 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -64,6 +64,7 @@ 'wasm64', 'x86', 'x86_64', + 'tricore' ) # It would feel more natural to call this "64_BIT_CPU_FAMILIES", but diff --git a/mesonbuild/linkers/base.py b/mesonbuild/linkers/base.py index c8efc9d6d82c..68fdb2ea3a70 100644 --- a/mesonbuild/linkers/base.py +++ b/mesonbuild/linkers/base.py @@ -18,6 +18,7 @@ class RSPFileSyntax(enum.Enum): MSVC = enum.auto() GCC = enum.auto() + TASKING = enum.auto() class ArLikeLinker: diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index d011e67b9c54..588b66369878 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -523,6 +523,38 @@ class MetrowerksStaticLinkerARM(MetrowerksStaticLinker): class MetrowerksStaticLinkerEmbeddedPowerPC(MetrowerksStaticLinker): id = 'mwldeppc' +class TaskingStaticLinker(StaticLinker): + + def __init__(self, exelist: T.List[str]): + super().__init__(exelist) + + def can_linker_accept_rsp(self) -> bool: + return True + + def rsp_file_syntax(self) -> RSPFileSyntax: + return RSPFileSyntax.TASKING + + def get_output_args(self, target: str) -> T.List[str]: + return ['-n', target] + + def get_linker_always_args(self) -> T.List[str]: + return ['-r'] + +class TaskingTricoreStaticLinker(TaskingStaticLinker): + id = 'artc' + +class TaskingARMStaticLinker(TaskingStaticLinker): + id = 'ararm' + +class Tasking8051StaticLinker(TaskingStaticLinker): + id = 'ar51' + +class TaskingMCSStaticLinker(TaskingStaticLinker): + id = 'armcs' + +class TaskingPCPStaticLinker(TaskingStaticLinker): + id = 'arpcp' + def prepare_rpaths(raw_rpaths: T.Tuple[str, ...], build_dir: str, from_dir: str) -> T.List[str]: # The rpaths we write must be relative if they point to the build dir, # because otherwise they have different length depending on the build @@ -1653,3 +1685,67 @@ class MetrowerksLinkerARM(MetrowerksLinker): class MetrowerksLinkerEmbeddedPowerPC(MetrowerksLinker): id = 'mwldeppc' + +class TaskingLinker(DynamicLinker): + + _OPTIMIZATION_ARGS: T.Dict[str, T.List[str]] = { + 'plain': [], + '0': ['-O0'], + 'g': ['-O1'], # There is no debug specific level, O1 is recommended by the compiler + '1': ['-O1'], + '2': ['-O2'], + '3': ['-O2'], # There is no 3rd level optimization for the linker + 's': ['-Os'], + } + + def __init__(self, exelist: T.List[str], for_machine: mesonlib.MachineChoice, + *, version: str = 'unknown version'): + super().__init__(exelist, for_machine, '', [], + version=version) + + def get_accepts_rsp(self) -> bool: + return True + + def get_lib_prefix(self) -> str: + return "" + + def get_allow_undefined_args(self) -> T.List[str]: + return [] + + def invoked_by_compiler(self) -> bool: + return True + + def get_search_args(self, dirname: str) -> T.List[str]: + return self._apply_prefix('-L' + dirname) + + def get_output_args(self, outputname: str) -> T.List[str]: + return ['-o', outputname] + + def rsp_file_syntax(self) -> RSPFileSyntax: + return RSPFileSyntax.TASKING + + def fatal_warnings(self) -> T.List[str]: + """Arguments to make all warnings errors.""" + return self._apply_prefix('--warnings-as-errors') + + def get_link_whole_for(self, args: T.List[str]) -> T.List[str]: + args = mesonlib.listify(args) + l: T.List[str] = [] + for a in args: + l.extend(self._apply_prefix('-Wl--whole-archive=' + a)) + return l + +class TaskingTricoreLinker(TaskingLinker): + id = 'ltc' + +class TaskingARMLinker(TaskingLinker): + id = 'lkarm' + +class Tasking8051Linker(TaskingLinker): + id = 'lk51' + +class TaskingMCSLinker(TaskingLinker): + id = 'lmsc' + +class TaskingPCPLinker(TaskingLinker): + id = 'lpcp'