mirror of
https://github.com/mesonbuild/meson.git
synced 2026-11-06 05:16:42 +00:00
compilers: add support for SDCC
This commit is contained in:
1 parent
4094f1bb21
commit
2b650f4845
11 files changed
+231
-3
No files matched your search
@@ -0,0 +1,21 @@
|
||||
# This file assumes that path to the SDCC toolchain is added
|
||||
# to the environment(PATH) variable, so that Meson can find
|
||||
# sdcc and sdar while building.
|
||||
[binaries]
|
||||
c = 'sdcc'
|
||||
ar = 'sdar'
|
||||
|
||||
[host_machine]
|
||||
system = 'bare metal'
|
||||
cpu_family = 'mcs51'
|
||||
cpu = '8051'
|
||||
endian = 'little'
|
||||
|
||||
[properties]
|
||||
needs_exe_wrapper = true
|
||||
|
||||
[built-in options]
|
||||
# SDCC selects the target port with '-m'; it must be passed when
|
||||
# compiling and when linking.
|
||||
c_args = ['-mmcs51']
|
||||
c_link_args = ['-mmcs51']
|
||||
@@ -36,6 +36,7 @@ These are return values of the `get_id` (Compiler family) and
|
||||
| pathscale | The Pathscale Fortran compiler | |
|
||||
| pgi | Portland PGI C/C++/Fortran compilers | |
|
||||
| rustc | Rust compiler | |
|
||||
| sdcc | Small Device C Compiler | |
|
||||
| sun | Sun Fortran compiler | |
|
||||
| c2000 | Texas Instruments C/C++ Compiler (C2000) | |
|
||||
| c6000 | Texas Instruments C/C++ Compiler (C6000) | |
|
||||
@@ -86,6 +87,7 @@ These are return values of the `get_linker_id` method in a compiler object.
|
||||
| mwldarm | The Metrowerks Linker with the ARM interface, used with mwccarm only |
|
||||
| mwldeppc | The Metrowerks Linker with the PowerPC interface, used with mwcceppc only |
|
||||
| tasking | TASKING VX-toolset |
|
||||
| sdcc | SDCC used as the linker driver |
|
||||
|
||||
For languages that don't have separate dynamic linkers such as C# and Java, the
|
||||
`get_linker_id` will return the compiler name.
|
||||
@@ -119,19 +121,25 @@ set in the cross file.
|
||||
| csky | 32 bit CSky processor |
|
||||
| dspic | 16 bit Microchip dsPIC |
|
||||
| e2k | MCST Elbrus processor |
|
||||
| f8 | 8 bit SDCC F8 |
|
||||
| ft32 | 32 bit Bridgetek MCU |
|
||||
| hc08 | 8 bit Motorola HC08/S08 |
|
||||
| ia64 | Itanium processor |
|
||||
| loongarch64 | 64 bit Loongson processor|
|
||||
| m68k | Motorola 68000 processor |
|
||||
| mcs51 | 8 bit Intel MCS-51 |
|
||||
| microblaze | MicroBlaze processor |
|
||||
| mips | 32 bit MIPS processor |
|
||||
| mips64 | 64 bit MIPS processor |
|
||||
| mos6502 | 8 bit MOS 6502/65C02 |
|
||||
| msp430 | 16 bit MSP430 processor |
|
||||
| padauk | 8 bit Padauk PDK |
|
||||
| parisc | HP PA-RISC processor |
|
||||
| pic24 | 16 bit Microchip PIC24 |
|
||||
| pic32 | 32 bit Microchip PIC32 |
|
||||
| ppc | 32 bit PPC processors |
|
||||
| ppc64 | 64 bit PPC processors |
|
||||
| rabbit | 8 bit Rabbit 2000/3000 |
|
||||
| riscv32 | 32 bit RISC-V Open ISA |
|
||||
| riscv64 | 64 bit RISC-V Open ISA |
|
||||
| rl78 | Renesas RL78 |
|
||||
@@ -139,13 +147,17 @@ set in the cross file.
|
||||
| s390 | IBM zSystem s390 |
|
||||
| s390x | IBM zSystem s390x |
|
||||
| sh4 | SuperH SH-4 |
|
||||
| sm83 | 8 bit Sharp SM83 |
|
||||
| sparc | 32 bit SPARC |
|
||||
| sparc64 | SPARC v9 processor |
|
||||
| stm8 | 8 bit STMicro STM8 |
|
||||
| sw_64 | 64 bit sunway processor |
|
||||
| tlcs90 | 8 bit Toshiba TLCS-90 |
|
||||
| wasm32 | 32 bit Webassembly |
|
||||
| wasm64 | 64 bit Webassembly |
|
||||
| x86 | 32 bit x86 processor |
|
||||
| x86_64 | 64 bit x86 processor |
|
||||
| z80 | 8 bit Zilog Z80 family |
|
||||
| tricore | Tricore 32 bit processor |
|
||||
|
||||
|
||||
|
||||
@@ -943,8 +943,7 @@ class Backend:
|
||||
else:
|
||||
gen_source = os.path.relpath(os.path.join(build_dir, rel_src),
|
||||
os.path.join(self.environment.get_source_dir(), target.get_subdir()))
|
||||
machine = self.environment.machines[target.for_machine]
|
||||
object_suffix = machine.get_object_suffix()
|
||||
object_suffix = compiler.get_object_suffix()
|
||||
# For the TASKING compiler, in case of LTO or prelinking the object suffix has to be .mil
|
||||
if compiler.get_id() == 'tasking':
|
||||
use_lto = self.get_target_option(target, 'b_lto')
|
||||
|
||||
@@ -3093,7 +3093,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
|
||||
src_filename = src
|
||||
obj_basename = self.canonicalize_filename(src_filename)
|
||||
rel_obj = os.path.join(self.get_target_private_dir(target), obj_basename)
|
||||
rel_obj += '.' + self.environment.machines[target.for_machine].get_object_suffix()
|
||||
rel_obj += '.' + compiler.get_object_suffix()
|
||||
commands += self.get_compile_debugfile_args(compiler, target, rel_obj)
|
||||
if isinstance(src, File):
|
||||
if src.is_built:
|
||||
|
||||
@@ -2242,6 +2242,8 @@ class Executable(BuildTarget, LinkableTarget):
|
||||
self.suffix = 'nef'
|
||||
elif ('c' in self.compilers and self.compilers['c'].get_id() == 'tasking'):
|
||||
self.suffix = 'elf'
|
||||
elif ('c' in self.compilers and self.compilers['c'].get_id() == 'sdcc'):
|
||||
self.suffix = 'ihx'
|
||||
else:
|
||||
self.suffix = machine.get_exe_suffix()
|
||||
self.filename = self.name
|
||||
@@ -2407,6 +2409,8 @@ class StaticLibrary(BuildTarget, LinkableTarget):
|
||||
suffix = 'a'
|
||||
elif self.environment.machines[self.for_machine].is_os2() and self.environment.coredata.optstore.get_value_for(OptionKey('os2_emxomf')):
|
||||
suffix = 'lib'
|
||||
elif 'c' in self.compilers and self.compilers['c'].get_id() == 'sdcc':
|
||||
suffix = 'lib'
|
||||
else:
|
||||
suffix = 'a'
|
||||
if 'c' in self.compilers and self.compilers['c'].get_id() == 'tasking' and not self.prelink:
|
||||
|
||||
@@ -17,6 +17,7 @@ from .mixins.clike import CLikeCompiler
|
||||
from .mixins.ccrx import CcrxCompiler
|
||||
from .mixins.microchip import Xc16Compiler, Xc32Compiler, Xc32CStds
|
||||
from .mixins.compcert import CompCertCompiler
|
||||
from .mixins.sdcc import SdccCompiler
|
||||
from .mixins.ti import TICompiler
|
||||
from .mixins.arm import ArmCompiler, ArmclangCompiler
|
||||
from .mixins.visualstudio import MSVCCompiler, ClangClCompiler
|
||||
@@ -680,6 +681,33 @@ class CompCertCCompiler(CompCertCompiler, CCompiler):
|
||||
path = '.'
|
||||
return ['-I' + path]
|
||||
|
||||
|
||||
class SdccCCompiler(SdccCompiler, CCompiler):
|
||||
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
|
||||
env: Environment,
|
||||
linker: T.Optional['DynamicLinker'] = None,
|
||||
full_version: T.Optional[str] = None):
|
||||
CCompiler.__init__(self, ccache, exelist, version, for_machine,
|
||||
env, linker=linker, full_version=full_version)
|
||||
SdccCompiler.__init__(self)
|
||||
|
||||
def get_options(self) -> 'MutableKeyedOptionDictType':
|
||||
opts = super().get_options()
|
||||
key = self.form_compileropt_key('std')
|
||||
std_opt = opts[key]
|
||||
assert isinstance(std_opt, options.UserStdOption), 'for mypy'
|
||||
std_opt.set_versions(['c89', 'c90', 'c99', 'c11', 'c17', 'c23', 'c2y'])
|
||||
return opts
|
||||
|
||||
def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]:
|
||||
args = []
|
||||
std = self.get_compileropt_value('std', target, subproject)
|
||||
assert isinstance(std, str)
|
||||
if std != 'none':
|
||||
args.append('--std-' + std)
|
||||
return args
|
||||
|
||||
|
||||
class TICCompiler(TICompiler, CCompiler):
|
||||
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice,
|
||||
env: Environment,
|
||||
|
||||
@@ -1549,6 +1549,10 @@ class Compiler(HoldableObject, metaclass=SimpleABC):
|
||||
def get_depfile_suffix(self) -> str:
|
||||
raise EnvironmentException(f'{self.id} does not implement get_depfile_suffix')
|
||||
|
||||
def get_object_suffix(self) -> str:
|
||||
"""Suffix for object files."""
|
||||
return self.environment.machines[self.for_machine].get_object_suffix()
|
||||
|
||||
def get_no_stdinc_args(self) -> T.List[str]:
|
||||
"""Arguments to turn off default inclusion of standard libraries."""
|
||||
return []
|
||||
|
||||
@@ -82,6 +82,7 @@ defaults['cuda_static_linker'] = ['nvlink']
|
||||
defaults['gcc_static_linker'] = ['gcc-ar']
|
||||
defaults['clang_static_linker'] = ['llvm-ar']
|
||||
defaults['emxomf_static_linker'] = ['emxomfar']
|
||||
defaults['sdcc_static_linker'] = ['sdar']
|
||||
defaults['nasm'] = ['nasm', 'yasm']
|
||||
|
||||
|
||||
@@ -212,6 +213,8 @@ def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker
|
||||
trials = [defaults['clang_cl_static_linker']] + trials
|
||||
if 'vs_static_linker' in defaults:
|
||||
trials = [defaults['vs_static_linker']] + trials
|
||||
elif compiler.id == 'sdcc':
|
||||
trials = [defaults['sdcc_static_linker']] + trials
|
||||
|
||||
popen_exceptions = {}
|
||||
for linker in trials:
|
||||
@@ -254,6 +257,8 @@ def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker
|
||||
return linkers.Xc16Linker(linker, env)
|
||||
elif 'xc32-ar' in linker_name:
|
||||
return linkers.Xc32ArLinker(compiler.for_machine, linker, env)
|
||||
elif 'sdar' in linker_name:
|
||||
return linkers.SdccLinker(linker, env)
|
||||
if 'Texas Instruments Incorporated' in out:
|
||||
if 'ar2000' in linker_name:
|
||||
return linkers.C2000Linker(linker, env)
|
||||
@@ -628,6 +633,16 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin
|
||||
ccache, compiler, version, for_machine, env,
|
||||
full_version=full_version, linker=linker)
|
||||
|
||||
if out.startswith('SDCC'):
|
||||
if lang != 'c':
|
||||
raise EnvironmentException(f'SDCC does not support {lang}')
|
||||
cls = c.SdccCCompiler
|
||||
env.add_lang_args(cls.language, cls, for_machine)
|
||||
linker = linkers.SdccDynamicLinker(compiler, env, for_machine, version=version)
|
||||
return cls(
|
||||
ccache, compiler, version, for_machine, env,
|
||||
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
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright 2025 The Meson development team
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
"""Representations specific to the Small Device C Compiler (SDCC)."""
|
||||
|
||||
import os
|
||||
import typing as T
|
||||
|
||||
if T.TYPE_CHECKING:
|
||||
from ...compilers.compilers import Compiler
|
||||
else:
|
||||
Compiler = object
|
||||
|
||||
sdcc_optimization_args: T.Dict[str, T.List[str]] = {
|
||||
'plain': [],
|
||||
'0': [],
|
||||
'g': [],
|
||||
'1': [],
|
||||
'2': ['--opt-code-speed'],
|
||||
'3': ['--opt-code-speed'],
|
||||
's': ['--opt-code-size'],
|
||||
}
|
||||
|
||||
sdcc_debug_args: T.Dict[bool, T.List[str]] = {
|
||||
False: [],
|
||||
True: ['--debug'],
|
||||
}
|
||||
|
||||
|
||||
class SdccCompiler(Compiler):
|
||||
|
||||
id = 'sdcc'
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.warn_args: T.Dict[str, T.List[str]] = {
|
||||
'0': [],
|
||||
'1': [],
|
||||
'2': [],
|
||||
'3': [],
|
||||
'everything': [],
|
||||
}
|
||||
|
||||
def get_always_args(self) -> T.List[str]:
|
||||
return []
|
||||
|
||||
def get_pic_args(self) -> T.List[str]:
|
||||
return []
|
||||
|
||||
def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]:
|
||||
# SDCC's own -M flags suppress codegen; -Wp routes them to sdcpp, which also compiles.
|
||||
return ['-Wp,-MD', '-Wp,-MF', '-Wp,' + outfile, '-Wp,-MQ', '-Wp,' + outtarget]
|
||||
|
||||
def get_no_optimization_args(self) -> T.List[str]:
|
||||
return []
|
||||
|
||||
def get_object_suffix(self) -> str:
|
||||
return 'rel'
|
||||
|
||||
def _sanity_check_filenames(self) -> T.Tuple[str, T.Optional[str], str]:
|
||||
cross_or_not = '_cross' if self.is_cross else ''
|
||||
return ('sanity_check_for_c.c', None, f'sanity_check_for_c{cross_or_not}.ihx')
|
||||
|
||||
def get_optimization_args(self, optimization_level: str) -> T.List[str]:
|
||||
return sdcc_optimization_args[optimization_level]
|
||||
|
||||
def get_debug_args(self, is_debug: bool) -> T.List[str]:
|
||||
return sdcc_debug_args[is_debug]
|
||||
|
||||
def get_preprocess_only_args(self) -> T.List[str]:
|
||||
return ['-E']
|
||||
|
||||
def get_werror_args(self) -> T.List[str]:
|
||||
return ['--Werror']
|
||||
|
||||
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_include_args(self, path: str, is_system: bool) -> T.List[str]:
|
||||
if not path:
|
||||
path = '.'
|
||||
return ['-I' + path]
|
||||
|
||||
def thread_flags(self) -> T.List[str]:
|
||||
return []
|
||||
|
||||
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] in {'-I', '-L'}:
|
||||
parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:]))
|
||||
return parameter_list
|
||||
@@ -47,19 +47,25 @@ known_cpu_families = (
|
||||
'csky',
|
||||
'dspic',
|
||||
'e2k',
|
||||
'f8',
|
||||
'ft32',
|
||||
'hc08',
|
||||
'ia64',
|
||||
'loongarch64',
|
||||
'm68k',
|
||||
'mcs51',
|
||||
'microblaze',
|
||||
'mips',
|
||||
'mips64',
|
||||
'mos6502',
|
||||
'msp430',
|
||||
'padauk',
|
||||
'parisc',
|
||||
'pic24',
|
||||
'pic32',
|
||||
'ppc',
|
||||
'ppc64',
|
||||
'rabbit',
|
||||
'riscv32',
|
||||
'riscv64',
|
||||
'rl78',
|
||||
@@ -67,13 +73,17 @@ known_cpu_families = (
|
||||
's390',
|
||||
's390x',
|
||||
'sh4',
|
||||
'sm83',
|
||||
'sparc',
|
||||
'sparc64',
|
||||
'stm8',
|
||||
'sw_64',
|
||||
'tlcs90',
|
||||
'wasm32',
|
||||
'wasm64',
|
||||
'x86',
|
||||
'x86_64',
|
||||
'z80',
|
||||
'tricore'
|
||||
)
|
||||
|
||||
|
||||
@@ -499,6 +499,22 @@ class Xc16Linker(StaticLinker):
|
||||
return ['rcs']
|
||||
|
||||
|
||||
class SdccLinker(StaticLinker):
|
||||
|
||||
"""Static linker for the Small Device C Compiler."""
|
||||
|
||||
id = 'sdar'
|
||||
|
||||
def can_linker_accept_rsp(self) -> bool:
|
||||
return False
|
||||
|
||||
def get_output_args(self, target: str) -> T.List[str]:
|
||||
return [target]
|
||||
|
||||
def get_linker_always_args(self) -> T.List[str]:
|
||||
return ['-rc']
|
||||
|
||||
|
||||
class Xc32ArLinker(ArLinker):
|
||||
|
||||
"""Static linker for Microchip XC32 compiler."""
|
||||
@@ -1215,6 +1231,29 @@ class Xc32DynamicLinker(GnuDynamicLinker):
|
||||
return []
|
||||
|
||||
|
||||
class SdccDynamicLinker(DynamicLinker):
|
||||
|
||||
"""Linker for the Small Device C Compiler."""
|
||||
|
||||
id = 'sdcc'
|
||||
|
||||
def __init__(self, exelist: T.List[str], env: Environment, for_machine: mesonlib.MachineChoice,
|
||||
*, version: str = 'unknown version'):
|
||||
super().__init__(exelist, env, for_machine, None, [], version=version)
|
||||
|
||||
def get_accepts_rsp(self) -> bool:
|
||||
return False
|
||||
|
||||
def get_allow_undefined_args(self) -> T.List[str]:
|
||||
return []
|
||||
|
||||
def get_output_args(self, outputname: str) -> T.List[str]:
|
||||
return ['-o', outputname]
|
||||
|
||||
def get_search_args(self, dirname: str) -> T.List[str]:
|
||||
return ['-L' + dirname]
|
||||
|
||||
|
||||
class CompCertDynamicLinker(DynamicLinker):
|
||||
|
||||
"""Linker for CompCert C compiler."""
|
||||
|
||||
Reference in new issue
Block a user