diff options
| author | Liza Chevalier <lizalc@pm.me> | 2025-10-29 11:17:00 -0500 |
|---|---|---|
| committer | Dylan Baker <dylan@pnwbakers.com> | 2025-10-29 12:35:55 -0700 |
| commit | ba860d72a96932608bb2b13a2f32ebda0087905a (patch) | |
| tree | d40fb1da7ea242673c6f7896c70be6ed12d6416e /mesonbuild | |
| parent | e9d255de1580235fff96e110001ce4293006caaa (diff) | |
| download | meson-ba860d72a96932608bb2b13a2f32ebda0087905a.tar.gz | |
compilers: add Microchip XC32 compiler
The Microchip XC32 compiler is a GCC-based compiler implemented using
existing GNU compiler classes. As the XC32 version and GCC version do
not match mixins have been implemented to override versions used in
versions checks where applicable.
Diffstat (limited to 'mesonbuild')
| -rw-r--r-- | mesonbuild/compilers/c.py | 17 | ||||
| -rw-r--r-- | mesonbuild/compilers/cpp.py | 17 | ||||
| -rw-r--r-- | mesonbuild/compilers/detect.py | 44 | ||||
| -rw-r--r-- | mesonbuild/compilers/mixins/microchip.py (renamed from mesonbuild/compilers/mixins/xc16.py) | 92 | ||||
| -rw-r--r-- | mesonbuild/envconfig.py | 1 | ||||
| -rw-r--r-- | mesonbuild/linkers/linkers.py | 28 |
6 files changed, 183 insertions, 16 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 424b61251..53ef28e13 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -15,7 +15,7 @@ from .c_function_attributes import C_FUNC_ATTRIBUTES from .mixins.apple import AppleCompilerMixin, AppleCStdsMixin from .mixins.clike import CLikeCompiler from .mixins.ccrx import CcrxCompiler -from .mixins.xc16 import Xc16Compiler +from .mixins.microchip import Xc16Compiler, Xc32Compiler, Xc32CStds from .mixins.compcert import CompCertCompiler from .mixins.ti import TICompiler from .mixins.arm import ArmCompiler, ArmclangCompiler @@ -643,6 +643,21 @@ class Xc16CCompiler(Xc16Compiler, CCompiler): path = '.' return ['-I' + path] + +class Xc32CCompiler(Xc32CStds, Xc32Compiler, GnuCCompiler): + + """Microchip XC32 C compiler.""" + + 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, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): + GnuCCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, + info, linker=linker, full_version=full_version, defines=defines) + Xc32Compiler.__init__(self) + + class CompCertCCompiler(CompCertCompiler, CCompiler): def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, info: 'MachineInfo', diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 8533373a8..b57cbec62 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -32,6 +32,7 @@ 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 .mixins.microchip import Xc32Compiler, Xc32CPPStds if T.TYPE_CHECKING: from ..options import MutableKeyedOptionDictType @@ -158,7 +159,7 @@ class CPPCompiler(CLikeCompiler, Compiler): } # Currently, remapping is only supported for Clang, Elbrus and GCC - assert self.id in frozenset(['clang', 'lcc', 'gcc', 'emscripten', 'armltdclang', 'intel-llvm', 'nvidia_hpc']) + assert self.id in frozenset(['clang', 'lcc', 'gcc', 'emscripten', 'armltdclang', 'intel-llvm', 'nvidia_hpc', 'xc32-gcc']) if cpp_std not in CPP_FALLBACKS: # 'c++03' and 'c++98' don't have fallback types @@ -1128,3 +1129,17 @@ class MetrowerksCPPCompilerEmbeddedPowerPC(MetrowerksCompiler, CPPCompiler): if std != 'none': args.append('-lang ' + std) return args + + +class Xc32CPPCompiler(Xc32CPPStds, Xc32Compiler, GnuCPPCompiler): + + """Microchip XC32 C++ compiler.""" + + 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, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): + GnuCPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross, + info, linker=linker, full_version=full_version, defines=defines) + Xc32Compiler.__init__(self) diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py index 979b9ce60..0a5f55ddd 100644 --- a/mesonbuild/compilers/detect.py +++ b/mesonbuild/compilers/detect.py @@ -227,8 +227,11 @@ def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker return linkers.DLinker(linker, compiler.arch) if err.startswith('Renesas') and 'rlink' in linker_name: return linkers.CcrxLinker(linker) - if out.startswith('GNU ar') and 'xc16-ar' in linker_name: - return linkers.Xc16Linker(linker) + if out.startswith('GNU ar'): + if 'xc16-ar' in linker_name: + return linkers.Xc16Linker(linker) + elif 'xc32-ar' in linker_name: + return linkers.Xc32ArLinker(compiler.for_machine, linker) if 'Texas Instruments Incorporated' in out: if 'ar2000' in linker_name: return linkers.C2000Linker(linker) @@ -343,7 +346,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin guess_gcc_or_lcc = 'gcc' if 'e2k' in out and 'lcc' in out: guess_gcc_or_lcc = 'lcc' - if 'Microchip Technology' in out: + if 'Microchip' in out: # this output has "Free Software Foundation" in its version guess_gcc_or_lcc = None @@ -567,13 +570,34 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin ccache, compiler, version, for_machine, is_cross, info, full_version=full_version, linker=linker) - if 'Microchip Technology' in out: - cls = c.Xc16CCompiler - env.add_lang_args(cls.language, cls, for_machine) - linker = linkers.Xc16DynamicLinker(for_machine, version=version) - return cls( - ccache, compiler, version, for_machine, is_cross, info, - full_version=full_version, linker=linker) + if 'Microchip' in out: + if 'XC32' in out: + # XC32 versions always have the form 'vMAJOR.MINOR' + match = re.search(r'XC32.*v(\d+\.\d+)', out) + if match: + version = match.group(1) + else: + raise EnvironmentException(f'Failed to detect XC32 compiler version: full version was\n{full_version}') + + cls = c.Xc32CCompiler if lang == 'c' else cpp.Xc32CPPCompiler + defines = _get_gnu_compiler_defines(compiler, lang) + cls.gcc_version = _get_gnu_version_from_defines(defines) + + env.add_lang_args(cls.language, cls, for_machine) + linker = linkers.Xc32DynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version) + + return cls( + ccache, compiler, version, for_machine, is_cross, + info, defines=defines, full_version=full_version, + linker=linker) + else: + cls = c.Xc16CCompiler + env.add_lang_args(cls.language, cls, for_machine) + linker = linkers.Xc16DynamicLinker(for_machine, version=version) + + return cls( + ccache, compiler, version, for_machine, is_cross, info, + full_version=full_version, linker=linker) if 'CompCert' in out: cls = c.CompCertCCompiler diff --git a/mesonbuild/compilers/mixins/xc16.py b/mesonbuild/compilers/mixins/microchip.py index d95674e3e..6b989cba8 100644 --- a/mesonbuild/compilers/mixins/xc16.py +++ b/mesonbuild/compilers/mixins/microchip.py @@ -3,23 +3,26 @@ from __future__ import annotations -"""Representations specific to the Microchip XC16 C compiler family.""" +"""Representations specific to the Microchip XC C/C++ compiler family.""" import os import typing as T -from ...mesonlib import EnvironmentException +from .gnu import GnuCStds, GnuCPPStds +from ..compilers import Compiler +from ...mesonlib import EnvironmentException, version_compare if T.TYPE_CHECKING: from ...envconfig import MachineInfo from ...environment import Environment - from ...compilers.compilers import Compiler + + CompilerBase = 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 up DRYer type checking, with no runtime impact - Compiler = object + CompilerBase = object xc16_optimization_args: T.Dict[str, T.List[str]] = { 'plain': [], @@ -109,3 +112,84 @@ class Xc16Compiler(Compiler): parameter_list[idx] = i[:9] + os.path.normpath(os.path.join(build_dir, i[9:])) return parameter_list + + +class Xc32Compiler(CompilerBase): + + """Microchip XC32 compiler mixin. GCC based with some options disabled.""" + + id = 'xc32-gcc' + + gcc_version = '4.5.1' # Defaults to GCC version used by first XC32 release (v1.00). + + _COLOR_VERSION = ">=3.0" # XC32 version based on GCC 8.3.1+ + _WPEDANTIC_VERSION = ">=1.40" # XC32 version based on GCC 4.8.3+ + _LTO_AUTO_VERSION = "==-1" + _USE_MOLD_VERSION = "==-1" + + def __init__(self) -> None: + if not self.is_cross: + raise EnvironmentException("XC32 supports only cross-compilation.") + + def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[str]]: + return None + + def thread_flags(self, env: Environment) -> T.List[str]: + return [] + + def openmp_flags(self, env: Environment) -> T.List[str]: + return Compiler.openmp_flags(self, env) + + def get_pic_args(self) -> T.List[str]: + return Compiler.get_pic_args(self) + + def get_pie_args(self) -> T.List[str]: + return Compiler.get_pie_args(self) + + def get_profile_generate_args(self) -> T.List[str]: + return Compiler.get_profile_generate_args(self) + + def get_profile_use_args(self) -> T.List[str]: + return Compiler.get_profile_use_args(self) + + def sanitizer_compile_args(self, value: T.List[str]) -> T.List[str]: + return [] + + @classmethod + def use_linker_args(cls, linker: str, version: str) -> T.List[str]: + return [] + + def get_coverage_args(self) -> T.List[str]: + return [] + + def get_largefile_args(self) -> T.List[str]: + return [] + + def get_prelink_args(self, prelink_name: str, obj_list: T.List[str]) -> T.Tuple[T.List[str], T.List[str]]: + return Compiler.get_prelink_args(self, prelink_name, obj_list) + + def get_prelink_append_compile_args(self) -> bool: + return False + + def supported_warn_args(self, warn_args_by_version: T.Dict[str, T.List[str]]) -> T.List[str]: + result: T.List[str] = [] + for version, warn_args in warn_args_by_version.items(): + if version_compare(self.gcc_version, '>=' + version): + result += warn_args + return result + +class Xc32CStds(GnuCStds): + + """Mixin for setting C standards based on XC32 version.""" + + _C18_VERSION = ">=3.0" + _C2X_VERSION = "==-1" + _C23_VERSION = "==-1" + _C2Y_VERSION = "==-1" + +class Xc32CPPStds(GnuCPPStds): + + """Mixin for setting C++ standards based on XC32 version.""" + + _CPP23_VERSION = "==-1" + _CPP26_VERSION = "==-1" diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index f4616ac14..048cc8a6d 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -56,6 +56,7 @@ known_cpu_families = ( 'msp430', 'parisc', 'pic24', + 'pic32', 'ppc', 'ppc64', 'riscv32', diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index a905f0667..461bcc279 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -479,6 +479,14 @@ class Xc16Linker(StaticLinker): def get_linker_always_args(self) -> T.List[str]: return ['rcs'] + +class Xc32ArLinker(ArLinker): + + """Static linker for Microchip XC32 compiler.""" + + id = 'xc32-ar' + + class CompCertLinker(StaticLinker): def __init__(self, exelist: T.List[str]): @@ -1112,6 +1120,26 @@ class Xc16DynamicLinker(DynamicLinker): target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: return ([], set()) + +class Xc32DynamicLinker(GnuDynamicLinker): + + """Linker for Microchip XC32 compiler.""" + + id = 'ld.xc32' + + def sanitizer_args(self, value: T.List[str]) -> T.List[str]: + return [] + + def get_coverage_args(self) -> T.List[str]: + return DynamicLinker.get_coverage_args(self) + + def get_pie_args(self) -> T.List[str]: + return DynamicLinker.get_pie_args(self) + + def thread_flags(self, env: Environment) -> T.List[str]: + return [] + + class CompCertDynamicLinker(DynamicLinker): """Linker for CompCert C compiler.""" |
