Initial support for Metrowerks C/C++ compiler

pull/11709/head
Nomura 2 years ago committed by Eli Schwartz
parent bda799dff2
commit 18cfa545f0
  1. 28
      cross/metrowerks-arm.txt
  2. 28
      cross/metrowerks-eppc.txt
  3. 18
      cross/metrowerks.lcf
  4. 4
      docs/markdown/Reference-tables.md
  5. 5
      docs/markdown/snippets/add_metrowerks_compiler.md
  6. 18
      mesonbuild/backend/ninjabackend.py
  7. 3
      mesonbuild/build.py
  8. 59
      mesonbuild/compilers/c.py
  9. 59
      mesonbuild/compilers/cpp.py
  10. 41
      mesonbuild/compilers/detect.py
  11. 232
      mesonbuild/compilers/mixins/metrowerks.py
  12. 12
      mesonbuild/linkers/__init__.py
  13. 65
      mesonbuild/linkers/linkers.py
  14. 4
      run_project_tests.py

@ -0,0 +1,28 @@
# This file assumes that the path to your Metrowerks Embedded ARM
# toolchain is added to the environment(PATH) variable, so that
# Meson can find the binaries while building.
# You should also do one of the following to ensure Meson can
# locate the .lcf linker script:
# - Add the cross directory to PATH as well
# - Edit c_link_args and cpp_link_args with the full
# path to the .lcf file on your machine
[binaries]
c = 'mwccarm'
c_ld = 'mwldarm'
cpp = 'mwccarm'
cpp_ld = 'mwldarm'
ar = 'mwldarm'
as = 'mwasmarm'
[built-in options]
c_args = ['-lang', 'c99', '-D_NITRO', '-nosyspath']
c_link_args = 'metrowerks.lcf'
cpp_args = ['-lang', 'c++', '-D_NITRO', '-nosyspath']
cpp_link_args = 'metrowerks.lcf'
[host_machine]
system = 'bare metal'
cpu_family = 'arm'
endian = 'little'

@ -0,0 +1,28 @@
# This file assumes that the path to your Metrowerks toolchain
# of choice is added to the environment(PATH) variable, so that
# Meson can find the binaries while building.
# You should also do one of the following to ensure Meson can
# locate the .lcf linker script:
# - Add the cross directory to PATH as well
# - Edit c_link_args and cpp_link_args with the full
# path to the lcf file on your machine
[binaries]
c = 'mwcceppc'
c_ld = 'mwldeppc'
cpp = 'mwcceppc'
cpp_ld = 'mwldeppc'
ar = 'mwldeppc'
as = 'mwasmeppc'
[built-in options]
c_args = ['-lang', 'c99', '-nosyspath']
c_link_args = 'metrowerks.lcf'
cpp_args = ['-lang', 'c++', '-nosyspath']
cpp_link_args = 'metrowerks.lcf'
[host_machine]
system = 'bare metal'
cpu_family = 'ppc'
endian = 'little'

@ -0,0 +1,18 @@
# General-purpose linker script for Metrowerks toolchains.
# This script will link a blank application. Its only purpose
# is to allow the toolchains to run Meson tests. To link an
# actual application, you need to write your own fine-tuned lcf.
MEMORY {
TEST (RWX) : ORIGIN=0, LENGTH=0
}
SECTIONS {
.TEST:{
* (.text)
* (.data)
* (.rodata)
* (.bss)
__startup=.;
} > TEST
}

@ -25,6 +25,8 @@ These are return values of the `get_id` (Compiler family) and
| lcc | Elbrus C/C++/Fortran Compiler | |
| llvm | LLVM-based compiler (Swift, D) | |
| mono | Xamarin C# compiler | |
| mwccarm | Metrowerks C/C++ compiler for Embedded ARM | |
| mwcceppc | Metrowerks C/C++ compiler for Embedded PowerPC | |
| msvc | Microsoft Visual Studio | msvc |
| nagfor | The NAG Fortran compiler | |
| nvidia_hpc| NVidia HPC SDK compilers | |
@ -69,6 +71,8 @@ These are return values of the `get_linker_id` method in a compiler object.
| pgi | Portland/Nvidia PGI |
| nvlink | Nvidia Linker used with cuda |
| ccomp | CompCert used as the linker driver |
| mwldarm | The Metrowerks Linker with the ARM interface, used with mwccarm only |
| mwldeppc | The Metrowerks Linker with the PowerPC interface, used with mwcceppc only |
For languages that don't have separate dynamic linkers such as C# and Java, the
`get_linker_id` will return the compiler name.

@ -0,0 +1,5 @@
## Added Metrowerks C/C++ toolchains
Added support for the Metrowerks Embedded ARM and Metrowerks Embedded PowerPC toolchains (https://www.nxp.com/docs/en/reference-manual/CWMCUKINCMPREF.pdf).
The implementation is somewhat experimental. It has been tested on a few projects and works fairly well, but may have issues.

@ -2446,7 +2446,12 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
output = []
else:
output = NinjaCommandArg.list(compiler.get_output_args('$out'), Quoting.none)
command = compiler.get_exelist() + ['$ARGS'] + depargs + output + compiler.get_compile_only_args() + ['$in']
if 'mwcc' in compiler.id:
output[0].s = '-precompile'
command = compiler.get_exelist() + ['$ARGS'] + depargs + output + ['$in'] # '-c' must be removed
else:
command = compiler.get_exelist() + ['$ARGS'] + depargs + output + compiler.get_compile_only_args() + ['$in']
description = 'Precompiling header $in'
if compiler.get_argument_syntax() == 'msvc':
deps = 'msvc'
@ -3024,6 +3029,13 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
dep = dst + '.' + compiler.get_depfile_suffix()
return commands, dep, dst, [] # Gcc does not create an object file during pch generation.
def generate_mwcc_pch_command(self, target, compiler, pch):
commands = self._generate_single_compile(target, compiler)
dst = os.path.join(self.get_target_private_dir(target),
os.path.basename(pch) + '.' + compiler.get_pch_suffix())
dep = os.path.splitext(dst)[0] + '.' + compiler.get_depfile_suffix()
return commands, dep, dst, [] # mwcc compilers do not create an object file during pch generation.
def generate_pch(self, target, header_deps=None):
header_deps = header_deps if header_deps is not None else []
pch_objects = []
@ -3042,6 +3054,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
elif compiler.id == 'intel':
# Intel generates on target generation
continue
elif 'mwcc' in compiler.id:
src = os.path.join(self.build_to_src, target.get_source_subdir(), pch[0])
(commands, dep, dst, objs) = self.generate_mwcc_pch_command(target, compiler, pch[0])
extradep = None
else:
src = os.path.join(self.build_to_src, target.get_source_subdir(), pch[0])
(commands, dep, dst, objs) = self.generate_gcc_pch_command(target, compiler, pch[0])

@ -1875,6 +1875,9 @@ class Executable(BuildTarget):
elif ('c' in self.compilers and self.compilers['c'].get_id() in {'ti', 'c2000'} or
'cpp' in self.compilers and self.compilers['cpp'].get_id() in {'ti', 'c2000'}):
self.suffix = 'out'
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'
else:
self.suffix = machine.get_exe_suffix()
self.filename = self.name

@ -34,6 +34,8 @@ from .mixins.clang import ClangCompiler
from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from .mixins.emscripten import EmscriptenMixin
from .mixins.metrowerks import MetrowerksCompiler
from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args
from .compilers import (
gnu_winlibs,
msvc_winlibs,
@ -738,3 +740,60 @@ class TICCompiler(TICompiler, CCompiler):
class C2000CCompiler(TICCompiler):
# Required for backwards compat with projects created before ti-cgt support existed
id = 'c2000'
class MetrowerksCCompilerARM(MetrowerksCompiler, CCompiler):
id = 'mwccarm'
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo',
exe_wrapper: T.Optional['ExternalProgram'] = None,
linker: T.Optional['DynamicLinker'] = None,
full_version: T.Optional[str] = None):
CCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross,
info, exe_wrapper, linker=linker, full_version=full_version)
MetrowerksCompiler.__init__(self)
def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[str]]:
return mwccarm_instruction_set_args.get(instruction_set, None)
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
c_stds = ['c99']
opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + c_stds
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
if std.value != 'none':
args.append('-lang')
args.append(std.value)
return args
class MetrowerksCCompilerEmbeddedPowerPC(MetrowerksCompiler, CCompiler):
id = 'mwcceppc'
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo',
exe_wrapper: T.Optional['ExternalProgram'] = None,
linker: T.Optional['DynamicLinker'] = None,
full_version: T.Optional[str] = None):
CCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross,
info, exe_wrapper, linker=linker, full_version=full_version)
MetrowerksCompiler.__init__(self)
def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[str]]:
return mwcceppc_instruction_set_args.get(instruction_set, None)
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CCompiler.get_options(self)
c_stds = ['c99']
opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + c_stds
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
if std.value != 'none':
args.append('-lang ' + std.value)
return args

@ -39,6 +39,8 @@ from .mixins.clang import ClangCompiler
from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from .mixins.emscripten import EmscriptenMixin
from .mixins.metrowerks import MetrowerksCompiler
from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args
if T.TYPE_CHECKING:
from .compilers import CompileCheckMode
@ -893,3 +895,60 @@ class TICPPCompiler(TICompiler, CPPCompiler):
class C2000CPPCompiler(TICPPCompiler):
# Required for backwards compat with projects created before ti-cgt support existed
id = 'c2000'
class MetrowerksCPPCompilerARM(MetrowerksCompiler, CPPCompiler):
id = 'mwccarm'
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo',
exe_wrapper: T.Optional['ExternalProgram'] = None,
linker: T.Optional['DynamicLinker'] = None,
full_version: T.Optional[str] = None):
CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross,
info, exe_wrapper, linker=linker, full_version=full_version)
MetrowerksCompiler.__init__(self)
def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[str]]:
return mwccarm_instruction_set_args.get(instruction_set, None)
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CPPCompiler.get_options(self)
key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts[key].choices = ['none']
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
if std.value != 'none':
args.append('-lang')
args.append(std.value)
return args
class MetrowerksCPPCompilerEmbeddedPowerPC(MetrowerksCompiler, CPPCompiler):
id = 'mwcceppc'
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo',
exe_wrapper: T.Optional['ExternalProgram'] = None,
linker: T.Optional['DynamicLinker'] = None,
full_version: T.Optional[str] = None):
CPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross,
info, exe_wrapper, linker=linker, full_version=full_version)
MetrowerksCompiler.__init__(self)
def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[str]]:
return mwcceppc_instruction_set_args.get(instruction_set, None)
def get_options(self) -> 'MutableKeyedOptionDictType':
opts = CPPCompiler.get_options(self)
key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts[key].choices = ['none']
return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
if std.value != 'none':
args.append('-lang ' + std.value)
return args

@ -36,7 +36,7 @@ if T.TYPE_CHECKING:
from .cpp import CPPCompiler
from .fortran import FortranCompiler
from .rust import RustCompiler
from ..linkers import StaticLinker
from ..linkers import StaticLinker, DynamicLinker
from ..environment import Environment
from ..programs import ExternalProgram
@ -237,6 +237,11 @@ def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker
return linkers.TILinker(linker)
if out.startswith('The CompCert'):
return linkers.CompCertLinker(linker)
if out.strip().startswith('Metrowerks') or out.strip().startswith('Freescale'):
if 'ARM' in out:
return linkers.MetrowerksStaticLinkerARM(linker)
else:
return linkers.MetrowerksStaticLinkerEmbeddedPowerPC(linker)
if p.returncode == 0:
return linkers.ArLinker(compiler.for_machine, linker)
if p.returncode == 1 and err.startswith('usage'): # OSX
@ -269,6 +274,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
is_cross = env.is_cross_build(for_machine)
info = env.machines[for_machine]
cls: T.Union[T.Type[CCompiler], T.Type[CPPCompiler]]
lnk: T.Union[T.Type[StaticLinker], T.Type[DynamicLinker]]
for compiler in compilers:
if isinstance(compiler, str):
@ -529,7 +535,6 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
ccache, compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=l)
if 'TMS320C2000 C/C++' in out or 'MSP430 C/C++' in out or 'TI ARM C/C++ Compiler' in out:
lnk: T.Union[T.Type[linkers.C2000DynamicLinker], T.Type[linkers.TIDynamicLinker]]
if 'TMS320C2000 C/C++' in out:
cls = c.C2000CCompiler if lang == 'c' else cpp.C2000CPPCompiler
lnk = linkers.C2000DynamicLinker
@ -542,7 +547,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
return cls(
ccache, compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)
if 'ARM' in out:
if 'ARM' in out and not ('Metrowerks' in out or 'Freescale' in out):
cls = c.ArmCCompiler if lang == 'c' else cpp.ArmCPPCompiler
env.coredata.add_lang_args(cls.language, cls, for_machine, env)
linker = linkers.ArmDynamicLinker(for_machine, version=version)
@ -573,6 +578,36 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
ccache, compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)
if 'Metrowerks C/C++' in out or 'Freescale C/C++' in out:
if 'ARM' in out:
cls = c.MetrowerksCCompilerARM if lang == 'c' else cpp.MetrowerksCPPCompilerARM
lnk = linkers.MetrowerksLinkerARM
else:
cls = c.MetrowerksCCompilerEmbeddedPowerPC if lang == 'c' else cpp.MetrowerksCPPCompilerEmbeddedPowerPC
lnk = linkers.MetrowerksLinkerEmbeddedPowerPC
mwcc_ver_match = re.search(r'Version (\d+)\.(\d+)\.?(\d+)? build (\d+)', out)
assert mwcc_ver_match is not None, 'for mypy' # because mypy *should* be complaning that this could be None
compiler_version = '.'.join(x for x in mwcc_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 not None:
_, o_ld, _ = Popen_safe(ld + ['--version'])
mwld_ver_match = re.search(r'Version (\d+)\.(\d+)\.?(\d+)? build (\d+)', o_ld)
assert mwld_ver_match is not None, 'for mypy' # because mypy *should* be complaning that this could be None
linker_version = '.'.join(x for x in mwld_ver_match.groups() if x is not None)
linker = lnk(ld, for_machine, version=linker_version)
else:
raise EnvironmentException(f'Failed to detect linker for {cls.id!r} compiler. Please update your cross file(s).')
return cls(
ccache, compiler, compiler_version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)
_handle_exceptions(popen_exceptions, compilers)
raise EnvironmentException(f'Unknown compiler {compilers}')

@ -0,0 +1,232 @@
# Copyright 2012-2019 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
"""Representations specific to the Metrowerks/Freescale Embedded C/C++ compiler family."""
import os
import typing as T
from ...mesonlib import EnvironmentException, OptionKey
if T.TYPE_CHECKING:
from ...envconfig import MachineInfo
from ...compilers.compilers import Compiler, CompileCheckMode
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 up DRYer type checking, with no runtime impact
Compiler = object
mwcc_buildtype_args = {
'plain': [],
'debug': ['-g'],
'debugoptimized': ['-g', '-O4'],
'release': ['-O4,p'],
'minsize': ['-Os'],
'custom': [],
} # type: T.Dict[str, T.List[str]]
mwccarm_instruction_set_args = {
'generic': ['-proc', 'generic'],
'v4': ['-proc', 'v4'],
'v4t': ['-proc', 'v4t'],
'v5t': ['-proc', 'v5t'],
'v5te': ['-proc', 'v5te'],
'v6': ['-proc', 'v6'],
'arm7tdmi': ['-proc', 'arm7tdmi'],
'arm710t': ['-proc', 'arm710t'],
'arm720t': ['-proc', 'arm720t'],
'arm740t': ['-proc', 'arm740t'],
'arm7ej': ['-proc', 'arm7ej'],
'arm9tdmi': ['-proc', 'arm9tdmi'],
'arm920t': ['-proc', 'arm920t'],
'arm922t': ['-proc', 'arm922t'],
'arm940t': ['-proc', 'arm940t'],
'arm9ej': ['-proc', 'arm9ej'],
'arm926ej': ['-proc', 'arm926ej'],
'arm946e': ['-proc', 'arm946e'],
'arm966e': ['-proc', 'arm966e'],
'arm1020e': ['-proc', 'arm1020e'],
'arm1022e': ['-proc', 'arm1022e'],
'arm1026ej': ['-proc', 'arm1026ej'],
'dbmx1': ['-proc', 'dbmx1'],
'dbmxl': ['-proc', 'dbmxl'],
'XScale': ['-proc', 'XScale'],
'pxa255': ['-proc', 'pxa255'],
'pxa261': ['-proc', 'pxa261'],
'pxa262': ['-proc', 'pxa262'],
'pxa263': ['-proc', 'pxa263']
} # type: T.Dict[str, T.List[str]]
mwcceppc_instruction_set_args = {
'generic': ['-proc', 'generic'],
'401': ['-proc', '401'],
'403': ['-proc', '403'],
'505': ['-proc', '505'],
'509': ['-proc', '509'],
'555': ['-proc', '555'],
'601': ['-proc', '601'],
'602': ['-proc', '602'],
'603': ['-proc', '603'],
'603e': ['-proc', '603e'],
'604': ['-proc', '604'],
'604e': ['-proc', '604e'],
'740': ['-proc', '740'],
'750': ['-proc', '750'],
'801': ['-proc', '801'],
'821': ['-proc', '821'],
'823': ['-proc', '823'],
'850': ['-proc', '850'],
'860': ['-proc', '860'],
'7400': ['-proc', '7400'],
'7450': ['-proc', '7450'],
'8240': ['-proc', '8240'],
'8260': ['-proc', '8260'],
'e500': ['-proc', 'e500'],
'gekko': ['-proc', 'gekko'],
} # type: T.Dict[str, T.List[str]]
mwcc_optimization_args = {
'plain': [],
'0': ['-O0'],
'g': ['-Op'],
'1': ['-O1'],
'2': ['-O2'],
'3': ['-O3'],
's': ['-Os']
} # type: T.Dict[str, T.List[str]]
mwcc_debug_args = {
False: [],
True: ['-g']
} # type: T.Dict[bool, T.List[str]]
class MetrowerksCompiler(Compiler):
id = 'mwcc'
# These compilers can actually invoke the linker, but they choke on
# linker-specific flags. So it's best to invoke the linker directly
INVOKES_LINKER = False
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_pch', 'b_ndebug']}
default_warn_args = [] # type: T.List[str]
self.warn_args = {'0': ['-w', 'off'],
'1': default_warn_args,
'2': default_warn_args + ['-w', 'most'],
'3': default_warn_args + ['-w', 'all'],
'everything': default_warn_args + ['-w', 'full']} # type: T.Dict[str, T.List[str]]
def depfile_for_object(self, objfile: str) -> T.Optional[str]:
# Earlier versions of these compilers do not support specifying
# a custom name for a depfile, and can only generate '<input_file>.d'
return os.path.splitext(objfile)[0] + '.' + self.get_depfile_suffix()
def get_always_args(self) -> T.List[str]:
return ['-gccinc']
def get_buildtype_args(self, buildtype: str) -> T.List[str]:
return mwcc_buildtype_args[buildtype]
def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
return []
def get_compile_only_args(self) -> T.List[str]:
return ['-c']
def get_debug_args(self, is_debug: bool) -> T.List[str]:
return mwcc_debug_args[is_debug]
def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]:
# Check comment in depfile_for_object()
return ['-gccdep', '-MD']
def get_depfile_suffix(self) -> str:
return 'd'
def get_include_args(self, path: str, is_system: bool) -> T.List[str]:
if not path:
path = '.'
return ['-I' + path]
def get_no_optimization_args(self) -> T.List[str]:
return ['-opt', 'off']
def get_no_stdinc_args(self) -> T.List[str]:
return ['-nostdinc']
def get_no_stdlib_link_args(self) -> T.List[str]:
return ['-nostdlib']
def get_optimization_args(self, optimization_level: str) -> T.List[str]:
return mwcc_optimization_args[optimization_level]
def get_output_args(self, target: str) -> T.List[str]:
return ['-o', target]
def get_pic_args(self) -> T.List[str]:
return ['-pic']
def get_preprocess_only_args(self) -> T.List[str]:
return ['-E']
def get_preprocess_to_file_args(self) -> T.List[str]:
return ['-P']
def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]:
return ['-prefix', self.get_pch_name(header)]
def get_pch_name(self, name: str) -> str:
return os.path.basename(name) + '.' + self.get_pch_suffix()
def get_pch_suffix(self) -> str:
return 'mch'
def get_warn_args(self, level: str) -> T.List[str]:
return self.warn_args[level]
def get_werror_args(self) -> T.List[str]:
return ['-w', 'error']
@classmethod
def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]:
result = []
for i in args:
if i.startswith('-D'):
i = '-D' + i[2:]
if i.startswith('-I'):
i = '-I' + i[2:]
if i.startswith('-Wl,-rpath='):
continue
elif i == '--print-search-dirs':
continue
elif i.startswith('-L'):
continue
result.append(i)
return result
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':
parameter_list[idx] = i[:9] + os.path.normpath(os.path.join(build_dir, i[9:]))
return parameter_list

@ -36,6 +36,9 @@ from .linkers import (
AIXArLinker,
PGIStaticLinker,
NvidiaHPC_StaticLinker,
MetrowerksStaticLinker,
MetrowerksStaticLinkerARM,
MetrowerksStaticLinkerEmbeddedPowerPC,
DynamicLinker,
PosixDynamicLinkerMixin,
@ -58,6 +61,9 @@ from .linkers import (
PGIDynamicLinker,
NvidiaHPC_DynamicLinker,
NAGDynamicLinker,
MetrowerksLinker,
MetrowerksLinkerARM,
MetrowerksLinkerEmbeddedPowerPC,
VisualStudioLikeLinkerMixin,
MSVCDynamicLinker,
@ -98,6 +104,9 @@ __all__ = [
'AppleArLinker',
'PGIStaticLinker',
'NvidiaHPC_StaticLinker',
'MetrowerksStaticLinker',
'MetrowerksStaticLinkerARM',
'MetrowerksStaticLinkerEmbeddedPowerPC',
'DynamicLinker',
'PosixDynamicLinkerMixin',
@ -120,6 +129,9 @@ __all__ = [
'PGIDynamicLinker',
'NvidiaHPC_DynamicLinker',
'NAGDynamicLinker',
'MetrowerksLinker',
'MetrowerksLinkerARM',
'MetrowerksLinkerEmbeddedPowerPC',
'VisualStudioLikeLinkerMixin',
'MSVCDynamicLinker',

@ -327,6 +327,28 @@ class AIXArLinker(ArLikeLinker):
std_args = ['-csr', '-Xany']
class MetrowerksStaticLinker(StaticLinker):
def can_linker_accept_rsp(self) -> bool:
return True
def get_linker_always_args(self) -> T.List[str]:
return ['-library']
def get_output_args(self, target: str) -> T.List[str]:
return ['-o', target]
def rsp_file_syntax(self) -> RSPFileSyntax:
return RSPFileSyntax.GCC
class MetrowerksStaticLinkerARM(MetrowerksStaticLinker):
id = 'mwldarm'
class MetrowerksStaticLinkerEmbeddedPowerPC(MetrowerksStaticLinker):
id = 'mwldeppc'
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
@ -1554,3 +1576,46 @@ class CudaLinker(PosixDynamicLinkerMixin, DynamicLinker):
def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
suffix: str, soversion: str, darwin_versions: T.Tuple[str, str]) -> T.List[str]:
return []
class MetrowerksLinker(DynamicLinker):
def __init__(self, exelist: T.List[str], for_machine: mesonlib.MachineChoice,
*, version: str = 'unknown version'):
super().__init__(exelist, for_machine, '', [],
version=version)
def fatal_warnings(self) -> T.List[str]:
return ['-w', 'error']
def get_allow_undefined_args(self) -> T.List[str]:
return []
def get_accepts_rsp(self) -> bool:
return True
def get_lib_prefix(self) -> str:
return ""
def get_linker_always_args(self) -> T.List[str]:
return []
def get_output_args(self, target: str) -> T.List[str]:
return ['-o', target]
def get_search_args(self, dirname: str) -> T.List[str]:
return self._apply_prefix('-L' + dirname)
def invoked_by_compiler(self) -> bool:
return False
def rsp_file_syntax(self) -> RSPFileSyntax:
return RSPFileSyntax.GCC
class MetrowerksLinkerARM(MetrowerksLinker):
id = 'mwldarm'
class MetrowerksLinkerEmbeddedPowerPC(MetrowerksLinker):
id = 'mwldeppc'

@ -212,7 +212,9 @@ class InstalledFile:
suffix = '{}.{}'.format(suffix, '.'.join(self.version))
return p.with_suffix(suffix)
elif self.typ == 'exe':
if env.machines.host.is_windows() or env.machines.host.is_cygwin():
if 'mwcc' in canonical_compiler:
return p.with_suffix('.nef')
elif env.machines.host.is_windows() or env.machines.host.is_cygwin():
return p.with_suffix('.exe')
elif self.typ == 'pdb':
if self.version:

Loading…
Cancel
Save