Skip to content

Commit ba860d7

Browse files
lizalcdcbaker
authored andcommitted
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.
1 parent e9d255d commit ba860d7

File tree

9 files changed

+206
-16
lines changed

9 files changed

+206
-16
lines changed

cross/xc32.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# This file assumes that path to the Microchip XC32 toolchain is added
2+
# to the environment(PATH) variable, so that Meson can find XC32 while building.
3+
4+
[binaries]
5+
c = 'xc32-gcc'
6+
cpp = 'xc32-g++'
7+
ar = 'xc32-ar'
8+
bin2hex = 'xc32-bin2hex'
9+
10+
[host_machine]
11+
system = 'baremetal'
12+
cpu_family = 'pic32'
13+
cpu = 'pic32'
14+
endian = 'little'
15+
16+
[properties]
17+
needs_exe_wrapper = true

docs/markdown/Reference-tables.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ These are return values of the `get_id` (Compiler family) and
4242
| ti | Texas Instruments C/C++ Compiler | |
4343
| valac | Vala compiler | |
4444
| xc16 | Microchip XC16 C compiler | |
45+
| xc32-gcc | Microchip XC32 C/C++ compiler | gcc |
4546
| cython | The Cython compiler | |
4647
| nasm | The NASM compiler (Since 0.64.0) | |
4748
| yasm | The YASM compiler (Since 0.64.0) | |
@@ -73,6 +74,7 @@ These are return values of the `get_linker_id` method in a compiler object.
7374
| optlink | optlink (used with DMD) |
7475
| rlink | The Renesas linker, used with CCrx only |
7576
| xc16-ar | The Microchip linker, used with XC16 only |
77+
| ld.xc32 | The Microchip linker, used with XC32 only |
7678
| ar2000 | The Texas Instruments linker, used with C2000 only |
7779
| ti-ar | The Texas Instruments linker |
7880
| ar6000 | The Texas Instruments linker, used with C6000 only |
@@ -126,6 +128,7 @@ set in the cross file.
126128
| msp430 | 16 bit MSP430 processor |
127129
| parisc | HP PA-RISC processor |
128130
| pic24 | 16 bit Microchip PIC24 |
131+
| pic32 | 32 bit Microchip PIC32 |
129132
| ppc | 32 bit PPC processors |
130133
| ppc64 | 64 bit PPC processors |
131134
| riscv32 | 32 bit RISC-V Open ISA |
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Microchip XC32 compiler support
2+
3+
The Microchip XC32 compiler is now supported.

mesonbuild/compilers/c.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from .mixins.apple import AppleCompilerMixin, AppleCStdsMixin
1616
from .mixins.clike import CLikeCompiler
1717
from .mixins.ccrx import CcrxCompiler
18-
from .mixins.xc16 import Xc16Compiler
18+
from .mixins.microchip import Xc16Compiler, Xc32Compiler, Xc32CStds
1919
from .mixins.compcert import CompCertCompiler
2020
from .mixins.ti import TICompiler
2121
from .mixins.arm import ArmCompiler, ArmclangCompiler
@@ -643,6 +643,21 @@ def get_include_args(self, path: str, is_system: bool) -> T.List[str]:
643643
path = '.'
644644
return ['-I' + path]
645645

646+
647+
class Xc32CCompiler(Xc32CStds, Xc32Compiler, GnuCCompiler):
648+
649+
"""Microchip XC32 C compiler."""
650+
651+
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool,
652+
info: MachineInfo,
653+
linker: T.Optional[DynamicLinker] = None,
654+
defines: T.Optional[T.Dict[str, str]] = None,
655+
full_version: T.Optional[str] = None):
656+
GnuCCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross,
657+
info, linker=linker, full_version=full_version, defines=defines)
658+
Xc32Compiler.__init__(self)
659+
660+
646661
class CompCertCCompiler(CompCertCompiler, CCompiler):
647662
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
648663
is_cross: bool, info: 'MachineInfo',

mesonbuild/compilers/cpp.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from .mixins.emscripten import EmscriptenMixin
3333
from .mixins.metrowerks import MetrowerksCompiler
3434
from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args
35+
from .mixins.microchip import Xc32Compiler, Xc32CPPStds
3536

3637
if T.TYPE_CHECKING:
3738
from ..options import MutableKeyedOptionDictType
@@ -158,7 +159,7 @@ def _find_best_cpp_std(self, cpp_std: str) -> str:
158159
}
159160

160161
# Currently, remapping is only supported for Clang, Elbrus and GCC
161-
assert self.id in frozenset(['clang', 'lcc', 'gcc', 'emscripten', 'armltdclang', 'intel-llvm', 'nvidia_hpc'])
162+
assert self.id in frozenset(['clang', 'lcc', 'gcc', 'emscripten', 'armltdclang', 'intel-llvm', 'nvidia_hpc', 'xc32-gcc'])
162163

163164
if cpp_std not in CPP_FALLBACKS:
164165
# 'c++03' and 'c++98' don't have fallback types
@@ -1128,3 +1129,17 @@ def get_option_std_args(self, target: BuildTarget, env: Environment, subproject:
11281129
if std != 'none':
11291130
args.append('-lang ' + std)
11301131
return args
1132+
1133+
1134+
class Xc32CPPCompiler(Xc32CPPStds, Xc32Compiler, GnuCPPCompiler):
1135+
1136+
"""Microchip XC32 C++ compiler."""
1137+
1138+
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool,
1139+
info: MachineInfo,
1140+
linker: T.Optional[DynamicLinker] = None,
1141+
defines: T.Optional[T.Dict[str, str]] = None,
1142+
full_version: T.Optional[str] = None):
1143+
GnuCPPCompiler.__init__(self, ccache, exelist, version, for_machine, is_cross,
1144+
info, linker=linker, full_version=full_version, defines=defines)
1145+
Xc32Compiler.__init__(self)

mesonbuild/compilers/detect.py

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,11 @@ def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker
227227
return linkers.DLinker(linker, compiler.arch)
228228
if err.startswith('Renesas') and 'rlink' in linker_name:
229229
return linkers.CcrxLinker(linker)
230-
if out.startswith('GNU ar') and 'xc16-ar' in linker_name:
231-
return linkers.Xc16Linker(linker)
230+
if out.startswith('GNU ar'):
231+
if 'xc16-ar' in linker_name:
232+
return linkers.Xc16Linker(linker)
233+
elif 'xc32-ar' in linker_name:
234+
return linkers.Xc32ArLinker(compiler.for_machine, linker)
232235
if 'Texas Instruments Incorporated' in out:
233236
if 'ar2000' in linker_name:
234237
return linkers.C2000Linker(linker)
@@ -343,7 +346,7 @@ def sanitize(p: T.Optional[str]) -> T.Optional[str]:
343346
guess_gcc_or_lcc = 'gcc'
344347
if 'e2k' in out and 'lcc' in out:
345348
guess_gcc_or_lcc = 'lcc'
346-
if 'Microchip Technology' in out:
349+
if 'Microchip' in out:
347350
# this output has "Free Software Foundation" in its version
348351
guess_gcc_or_lcc = None
349352

@@ -567,13 +570,34 @@ def sanitize(p: T.Optional[str]) -> T.Optional[str]:
567570
ccache, compiler, version, for_machine, is_cross, info,
568571
full_version=full_version, linker=linker)
569572

570-
if 'Microchip Technology' in out:
571-
cls = c.Xc16CCompiler
572-
env.add_lang_args(cls.language, cls, for_machine)
573-
linker = linkers.Xc16DynamicLinker(for_machine, version=version)
574-
return cls(
575-
ccache, compiler, version, for_machine, is_cross, info,
576-
full_version=full_version, linker=linker)
573+
if 'Microchip' in out:
574+
if 'XC32' in out:
575+
# XC32 versions always have the form 'vMAJOR.MINOR'
576+
match = re.search(r'XC32.*v(\d+\.\d+)', out)
577+
if match:
578+
version = match.group(1)
579+
else:
580+
raise EnvironmentException(f'Failed to detect XC32 compiler version: full version was\n{full_version}')
581+
582+
cls = c.Xc32CCompiler if lang == 'c' else cpp.Xc32CPPCompiler
583+
defines = _get_gnu_compiler_defines(compiler, lang)
584+
cls.gcc_version = _get_gnu_version_from_defines(defines)
585+
586+
env.add_lang_args(cls.language, cls, for_machine)
587+
linker = linkers.Xc32DynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version)
588+
589+
return cls(
590+
ccache, compiler, version, for_machine, is_cross,
591+
info, defines=defines, full_version=full_version,
592+
linker=linker)
593+
else:
594+
cls = c.Xc16CCompiler
595+
env.add_lang_args(cls.language, cls, for_machine)
596+
linker = linkers.Xc16DynamicLinker(for_machine, version=version)
597+
598+
return cls(
599+
ccache, compiler, version, for_machine, is_cross, info,
600+
full_version=full_version, linker=linker)
577601

578602
if 'CompCert' in out:
579603
cls = c.CompCertCCompiler

mesonbuild/compilers/mixins/xc16.py renamed to mesonbuild/compilers/mixins/microchip.py

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,26 @@
33

44
from __future__ import annotations
55

6-
"""Representations specific to the Microchip XC16 C compiler family."""
6+
"""Representations specific to the Microchip XC C/C++ compiler family."""
77

88
import os
99
import typing as T
1010

11-
from ...mesonlib import EnvironmentException
11+
from .gnu import GnuCStds, GnuCPPStds
12+
from ..compilers import Compiler
13+
from ...mesonlib import EnvironmentException, version_compare
1214

1315
if T.TYPE_CHECKING:
1416
from ...envconfig import MachineInfo
1517
from ...environment import Environment
16-
from ...compilers.compilers import Compiler
18+
19+
CompilerBase = Compiler
1720
else:
1821
# This is a bit clever, for mypy we pretend that these mixins descend from
1922
# Compiler, so we get all of the methods and attributes defined for us, but
2023
# for runtime we make them descend from object (which all classes normally
2124
# do). This gives up DRYer type checking, with no runtime impact
22-
Compiler = object
25+
CompilerBase = object
2326

2427
xc16_optimization_args: T.Dict[str, T.List[str]] = {
2528
'plain': [],
@@ -109,3 +112,84 @@ def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], bu
109112
parameter_list[idx] = i[:9] + os.path.normpath(os.path.join(build_dir, i[9:]))
110113

111114
return parameter_list
115+
116+
117+
class Xc32Compiler(CompilerBase):
118+
119+
"""Microchip XC32 compiler mixin. GCC based with some options disabled."""
120+
121+
id = 'xc32-gcc'
122+
123+
gcc_version = '4.5.1' # Defaults to GCC version used by first XC32 release (v1.00).
124+
125+
_COLOR_VERSION = ">=3.0" # XC32 version based on GCC 8.3.1+
126+
_WPEDANTIC_VERSION = ">=1.40" # XC32 version based on GCC 4.8.3+
127+
_LTO_AUTO_VERSION = "==-1"
128+
_USE_MOLD_VERSION = "==-1"
129+
130+
def __init__(self) -> None:
131+
if not self.is_cross:
132+
raise EnvironmentException("XC32 supports only cross-compilation.")
133+
134+
def get_instruction_set_args(self, instruction_set: str) -> T.Optional[T.List[str]]:
135+
return None
136+
137+
def thread_flags(self, env: Environment) -> T.List[str]:
138+
return []
139+
140+
def openmp_flags(self, env: Environment) -> T.List[str]:
141+
return Compiler.openmp_flags(self, env)
142+
143+
def get_pic_args(self) -> T.List[str]:
144+
return Compiler.get_pic_args(self)
145+
146+
def get_pie_args(self) -> T.List[str]:
147+
return Compiler.get_pie_args(self)
148+
149+
def get_profile_generate_args(self) -> T.List[str]:
150+
return Compiler.get_profile_generate_args(self)
151+
152+
def get_profile_use_args(self) -> T.List[str]:
153+
return Compiler.get_profile_use_args(self)
154+
155+
def sanitizer_compile_args(self, value: T.List[str]) -> T.List[str]:
156+
return []
157+
158+
@classmethod
159+
def use_linker_args(cls, linker: str, version: str) -> T.List[str]:
160+
return []
161+
162+
def get_coverage_args(self) -> T.List[str]:
163+
return []
164+
165+
def get_largefile_args(self) -> T.List[str]:
166+
return []
167+
168+
def get_prelink_args(self, prelink_name: str, obj_list: T.List[str]) -> T.Tuple[T.List[str], T.List[str]]:
169+
return Compiler.get_prelink_args(self, prelink_name, obj_list)
170+
171+
def get_prelink_append_compile_args(self) -> bool:
172+
return False
173+
174+
def supported_warn_args(self, warn_args_by_version: T.Dict[str, T.List[str]]) -> T.List[str]:
175+
result: T.List[str] = []
176+
for version, warn_args in warn_args_by_version.items():
177+
if version_compare(self.gcc_version, '>=' + version):
178+
result += warn_args
179+
return result
180+
181+
class Xc32CStds(GnuCStds):
182+
183+
"""Mixin for setting C standards based on XC32 version."""
184+
185+
_C18_VERSION = ">=3.0"
186+
_C2X_VERSION = "==-1"
187+
_C23_VERSION = "==-1"
188+
_C2Y_VERSION = "==-1"
189+
190+
class Xc32CPPStds(GnuCPPStds):
191+
192+
"""Mixin for setting C++ standards based on XC32 version."""
193+
194+
_CPP23_VERSION = "==-1"
195+
_CPP26_VERSION = "==-1"

mesonbuild/envconfig.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
'msp430',
5757
'parisc',
5858
'pic24',
59+
'pic32',
5960
'ppc',
6061
'ppc64',
6162
'riscv32',

mesonbuild/linkers/linkers.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,14 @@ def get_output_args(self, target: str) -> T.List[str]:
479479
def get_linker_always_args(self) -> T.List[str]:
480480
return ['rcs']
481481

482+
483+
class Xc32ArLinker(ArLinker):
484+
485+
"""Static linker for Microchip XC32 compiler."""
486+
487+
id = 'xc32-ar'
488+
489+
482490
class CompCertLinker(StaticLinker):
483491

484492
def __init__(self, exelist: T.List[str]):
@@ -1112,6 +1120,26 @@ def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str,
11121120
target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]:
11131121
return ([], set())
11141122

1123+
1124+
class Xc32DynamicLinker(GnuDynamicLinker):
1125+
1126+
"""Linker for Microchip XC32 compiler."""
1127+
1128+
id = 'ld.xc32'
1129+
1130+
def sanitizer_args(self, value: T.List[str]) -> T.List[str]:
1131+
return []
1132+
1133+
def get_coverage_args(self) -> T.List[str]:
1134+
return DynamicLinker.get_coverage_args(self)
1135+
1136+
def get_pie_args(self) -> T.List[str]:
1137+
return DynamicLinker.get_pie_args(self)
1138+
1139+
def thread_flags(self, env: Environment) -> T.List[str]:
1140+
return []
1141+
1142+
11151143
class CompCertDynamicLinker(DynamicLinker):
11161144

11171145
"""Linker for CompCert C compiler."""

0 commit comments

Comments
 (0)