mirror of
https://github.com/mesonbuild/meson.git
synced 2026-11-06 05:16:42 +00:00
Added ARMCLANG compiler support for C/C++ (#3717)
This commit is contained in:
1 parent
f3c01a3c4f
commit
7140afc0a8
8 files changed
+206
-2
No files matched your search
@@ -0,0 +1,20 @@
|
||||
# This file assumes that path to the arm compiler toolchain is added
|
||||
# to the environment(PATH) variable, so that Meson can find
|
||||
# the armclang, armlink and armar while building.
|
||||
[binaries]
|
||||
c = 'armclang'
|
||||
cpp = 'armclang'
|
||||
ar = 'armar'
|
||||
strip = 'armar'
|
||||
|
||||
[properties]
|
||||
# The '--target', '-mcpu' options with the appropriate values should be mentioned
|
||||
# to cross compile c/c++ code with armclang.
|
||||
c_args = ['--target=arm-arm-none-eabi', '-mcpu=cortex-m0plus']
|
||||
cpp_args = ['--target=arm-arm-none-eabi', '-mcpu=cortex-m0plus']
|
||||
|
||||
[host_machine]
|
||||
system = 'bare metal' # Update with your system name - bare metal/OS.
|
||||
cpu_family = 'arm'
|
||||
cpu = 'Cortex-M0+'
|
||||
endian = 'little'
|
||||
@@ -23,6 +23,7 @@ These are return values of the `get_id` method in a compiler object.
|
||||
| nagfor | The NAG Fortran compiler |
|
||||
| lcc | Elbrus C/C++/Fortran Compiler |
|
||||
| arm | ARM compiler |
|
||||
| armclang | ARMCLANG compiler |
|
||||
|
||||
## Script environment variables
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
## ARM compiler(version 6) for C and CPP
|
||||
|
||||
Cross-compilation is now supported for ARM targets using ARM compiler version 6 - ARMCLANG.
|
||||
The required ARMCLANG compiler options for building a shareable library are not included in the
|
||||
current Meson implementation for ARMCLANG support, so it can not build shareable libraries.
|
||||
This current Meson implementation for ARMCLANG support can not build assembly files with
|
||||
arm syntax(we need to use armasm instead of ARMCLANG for the .s files with this syntax)
|
||||
and only supports gnu syntax.
|
||||
The default extension of the executable output is .axf.
|
||||
The environment path should be set properly for the ARM compiler executables.
|
||||
The '--target', '-mcpu' options with the appropriate values should be mentioned
|
||||
in the cross file as shown in the snippet below.
|
||||
|
||||
```
|
||||
[properties]
|
||||
c_args = ['--target=arm-arm-none-eabi', '-mcpu=cortex-m0plus']
|
||||
cpp_args = ['--target=arm-arm-none-eabi', '-mcpu=cortex-m0plus']
|
||||
|
||||
```
|
||||
|
||||
Note:
|
||||
- The current changes are tested on Windows only.
|
||||
- PIC support is not enabled by default for ARM,
|
||||
if users want to use it, they need to add the required arguments
|
||||
explicitly from cross-file(c_args/c++_args) or some other way.
|
||||
@@ -126,8 +126,9 @@ from .compilers import (
|
||||
IntelCompiler,
|
||||
)
|
||||
from .c import (
|
||||
ArmCCompiler,
|
||||
CCompiler,
|
||||
ArmCCompiler,
|
||||
ArmclangCCompiler,
|
||||
ClangCCompiler,
|
||||
GnuCCompiler,
|
||||
ElbrusCCompiler,
|
||||
@@ -135,8 +136,9 @@ from .c import (
|
||||
VisualStudioCCompiler,
|
||||
)
|
||||
from .cpp import (
|
||||
ArmCPPCompiler,
|
||||
CPPCompiler,
|
||||
ArmCPPCompiler,
|
||||
ArmclangCPPCompiler,
|
||||
ClangCPPCompiler,
|
||||
GnuCPPCompiler,
|
||||
ElbrusCPPCompiler,
|
||||
|
||||
@@ -32,6 +32,7 @@ from .compilers import (
|
||||
vs32_instruction_set_args,
|
||||
vs64_instruction_set_args,
|
||||
ArmCompiler,
|
||||
ArmclangCompiler,
|
||||
ClangCompiler,
|
||||
Compiler,
|
||||
CompilerArgs,
|
||||
@@ -979,6 +980,34 @@ class ClangCCompiler(ClangCompiler, CCompiler):
|
||||
return basic
|
||||
|
||||
|
||||
class ArmclangCCompiler(ArmclangCompiler, CCompiler):
|
||||
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
|
||||
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
|
||||
ArmclangCompiler.__init__(self)
|
||||
default_warn_args = ['-Wall', '-Winvalid-pch']
|
||||
self.warn_args = {'1': default_warn_args,
|
||||
'2': default_warn_args + ['-Wextra'],
|
||||
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
|
||||
|
||||
def get_options(self):
|
||||
opts = CCompiler.get_options(self)
|
||||
opts.update({'c_std': coredata.UserComboOption('c_std', 'C language standard to use',
|
||||
['none', 'c90', 'c99', 'c11',
|
||||
'gnu90', 'gnu99', 'gnu11'],
|
||||
'none')})
|
||||
return opts
|
||||
|
||||
def get_option_compile_args(self, options):
|
||||
args = []
|
||||
std = options['c_std']
|
||||
if std.value != 'none':
|
||||
args.append('-std=' + std.value)
|
||||
return args
|
||||
|
||||
def get_option_link_args(self, options):
|
||||
return []
|
||||
|
||||
|
||||
class GnuCCompiler(GnuCompiler, CCompiler):
|
||||
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None, **kwargs):
|
||||
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
|
||||
|
||||
@@ -131,6 +131,12 @@ gnulike_buildtype_args = {'plain': [],
|
||||
'release': ['-O3'],
|
||||
'minsize': ['-Os', '-g']}
|
||||
|
||||
armclang_buildtype_args = {'plain': [],
|
||||
'debug': ['-O0', '-g'],
|
||||
'debugoptimized': ['-O1', '-g'],
|
||||
'release': ['-Os'],
|
||||
'minsize': ['-Oz']}
|
||||
|
||||
arm_buildtype_args = {'plain': [],
|
||||
'debug': ['-O0', '--debug'],
|
||||
'debugoptimized': ['-O1', '--debug'],
|
||||
@@ -1414,6 +1420,80 @@ class ClangCompiler:
|
||||
return []
|
||||
|
||||
|
||||
class ArmclangCompiler:
|
||||
def __init__(self):
|
||||
if not self.is_cross:
|
||||
raise EnvironmentException('armclang supports only cross-compilation.')
|
||||
# Check whether 'armlink.exe' is available in path
|
||||
self.linker_exe = 'armlink.exe'
|
||||
args = '--vsn'
|
||||
try:
|
||||
p, stdo, stderr = Popen_safe(self.linker_exe, args)
|
||||
except OSError as e:
|
||||
err_msg = 'Unknown linker\nRunning "{0}" gave \n"{1}"'.format(' '.join([self.linker_exe] + [args]), e)
|
||||
raise EnvironmentException(err_msg)
|
||||
# Verify the armlink version
|
||||
ver_str = re.search('.*Component.*', stdo)
|
||||
if ver_str:
|
||||
ver_str = ver_str.group(0)
|
||||
else:
|
||||
EnvironmentException('armlink version string not found')
|
||||
# Using the regular expression from environment.search_version,
|
||||
# which is used for searching compiler version
|
||||
version_regex = '(?<!(\d|\.))(\d{1,2}(\.\d+)+(-[a-zA-Z0-9]+)?)'
|
||||
linker_ver = re.search(version_regex, ver_str)
|
||||
if linker_ver:
|
||||
linker_ver = linker_ver.group(0)
|
||||
if not version_compare(self.version, '==' + linker_ver):
|
||||
raise EnvironmentException('armlink version does not match with compiler version')
|
||||
self.id = 'armclang'
|
||||
self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
|
||||
'b_ndebug', 'b_staticpic', 'b_colorout']
|
||||
# Assembly
|
||||
self.can_compile_suffixes.update('s')
|
||||
|
||||
def can_linker_accept_rsp(self):
|
||||
return False
|
||||
|
||||
def get_pic_args(self):
|
||||
# PIC support is not enabled by default for ARM,
|
||||
# if users want to use it, they need to add the required arguments explicitly
|
||||
return []
|
||||
|
||||
def get_colorout_args(self, colortype):
|
||||
return clang_color_args[colortype][:]
|
||||
|
||||
def get_buildtype_args(self, buildtype):
|
||||
return armclang_buildtype_args[buildtype]
|
||||
|
||||
def get_buildtype_linker_args(self, buildtype):
|
||||
return arm_buildtype_linker_args[buildtype]
|
||||
|
||||
# Override CCompiler.get_std_shared_lib_link_args
|
||||
def get_std_shared_lib_link_args(self):
|
||||
return []
|
||||
|
||||
def get_pch_suffix(self):
|
||||
return 'gch'
|
||||
|
||||
def get_pch_use_args(self, pch_dir, header):
|
||||
# Workaround for Clang bug http://llvm.org/bugs/show_bug.cgi?id=15136
|
||||
# This flag is internal to Clang (or at least not documented on the man page)
|
||||
# so it might change semantics at any time.
|
||||
return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))]
|
||||
|
||||
# Override CCompiler.get_dependency_gen_args
|
||||
def get_dependency_gen_args(self, outtarget, outfile):
|
||||
return []
|
||||
|
||||
# Override CCompiler.build_rpath_args
|
||||
def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
|
||||
return []
|
||||
|
||||
def get_linker_exelist(self):
|
||||
return [self.linker_exe]
|
||||
|
||||
|
||||
# Tested on linux for ICC 14.0.3, 15.0.6, 16.0.4, 17.0.1
|
||||
class IntelCompiler:
|
||||
def __init__(self, icc_type):
|
||||
|
||||
@@ -27,6 +27,7 @@ from .compilers import (
|
||||
ElbrusCompiler,
|
||||
IntelCompiler,
|
||||
ArmCompiler,
|
||||
ArmclangCompiler,
|
||||
)
|
||||
|
||||
class CPPCompiler(CCompiler):
|
||||
@@ -98,6 +99,34 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler):
|
||||
return ['-lstdc++']
|
||||
|
||||
|
||||
class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
|
||||
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
|
||||
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
|
||||
ArmclangCompiler.__init__(self)
|
||||
default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
|
||||
self.warn_args = {'1': default_warn_args,
|
||||
'2': default_warn_args + ['-Wextra'],
|
||||
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
|
||||
|
||||
def get_options(self):
|
||||
opts = CPPCompiler.get_options(self)
|
||||
opts.update({'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
|
||||
['none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17'
|
||||
'gnu++98', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17'],
|
||||
'none')})
|
||||
return opts
|
||||
|
||||
def get_option_compile_args(self, options):
|
||||
args = []
|
||||
std = options['cpp_std']
|
||||
if std.value != 'none':
|
||||
args.append('-std=' + std.value)
|
||||
return args
|
||||
|
||||
def get_option_link_args(self, options):
|
||||
return []
|
||||
|
||||
|
||||
class GnuCPPCompiler(GnuCompiler, CPPCompiler):
|
||||
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrap, defines, **kwargs):
|
||||
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs)
|
||||
|
||||
@@ -40,6 +40,8 @@ from .compilers import (
|
||||
from .compilers import (
|
||||
ArmCCompiler,
|
||||
ArmCPPCompiler,
|
||||
ArmclangCCompiler,
|
||||
ArmclangCPPCompiler,
|
||||
ClangCCompiler,
|
||||
ClangCPPCompiler,
|
||||
ClangObjCCompiler,
|
||||
@@ -553,6 +555,22 @@ class Environment:
|
||||
cls = GnuCCompiler if lang == 'c' else GnuCPPCompiler
|
||||
return cls(ccache + compiler, version, gtype, is_cross, exe_wrap, defines, full_version=full_version)
|
||||
|
||||
if 'armclang' in out:
|
||||
# The compiler version is not present in the first line of output,
|
||||
# instead it is present in second line, startswith 'Component:'.
|
||||
# So, searching for the 'Component' in out although we know it is
|
||||
# present in second line, as we are not sure about the
|
||||
# output format in future versions
|
||||
arm_ver_str = re.search('.*Component.*', out)
|
||||
if arm_ver_str is None:
|
||||
popen_exceptions[' '.join(compiler)] = 'version string not found'
|
||||
continue
|
||||
arm_ver_str = arm_ver_str.group(0)
|
||||
# Override previous values
|
||||
version = search_version(arm_ver_str)
|
||||
full_version = arm_ver_str
|
||||
cls = ArmclangCCompiler if lang == 'c' else ArmclangCPPCompiler
|
||||
return cls(ccache + compiler, version, is_cross, exe_wrap, full_version=full_version)
|
||||
if 'clang' in out:
|
||||
if 'Apple' in out or mesonlib.for_darwin(want_cross, self):
|
||||
cltype = CLANG_OSX
|
||||
|
||||
Reference in new issue
Block a user