summaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorLiza Chevalier <lizalc@pm.me>2025-10-29 11:17:00 -0500
committerDylan Baker <dylan@pnwbakers.com>2025-10-29 12:35:55 -0700
commitba860d72a96932608bb2b13a2f32ebda0087905a (patch)
treed40fb1da7ea242673c6f7896c70be6ed12d6416e /mesonbuild
parente9d255de1580235fff96e110001ce4293006caaa (diff)
downloadmeson-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.py17
-rw-r--r--mesonbuild/compilers/cpp.py17
-rw-r--r--mesonbuild/compilers/detect.py44
-rw-r--r--mesonbuild/compilers/mixins/microchip.py (renamed from mesonbuild/compilers/mixins/xc16.py)92
-rw-r--r--mesonbuild/envconfig.py1
-rw-r--r--mesonbuild/linkers/linkers.py28
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."""