diff options
author | Vasu Penugonda <34339497+sompen@users.noreply.github.com> | 2018-06-21 03:25:39 +0530 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2018-06-21 00:55:39 +0300 |
commit | 7140afc0a86f2aae0689617fca985ef209a7c097 (patch) | |
tree | 90ea64438db91b8c29b2d70d5d1c5683fe0e86f1 | |
parent | f3c01a3c4f973ad234ead327f696b5e7fb43e4f6 (diff) | |
download | meson-7140afc0a86f2aae0689617fca985ef209a7c097.zip meson-7140afc0a86f2aae0689617fca985ef209a7c097.tar.gz meson-7140afc0a86f2aae0689617fca985ef209a7c097.tar.bz2 |
Added ARMCLANG compiler support for C/C++ (#3717)
-rw-r--r-- | cross/armclang.txt | 20 | ||||
-rw-r--r-- | docs/markdown/Reference-tables.md | 1 | ||||
-rw-r--r-- | docs/markdown/snippets/armclang-cross.md | 25 | ||||
-rw-r--r-- | mesonbuild/compilers/__init__.py | 6 | ||||
-rw-r--r-- | mesonbuild/compilers/c.py | 29 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 80 | ||||
-rw-r--r-- | mesonbuild/compilers/cpp.py | 29 | ||||
-rw-r--r-- | mesonbuild/environment.py | 18 |
8 files changed, 206 insertions, 2 deletions
diff --git a/cross/armclang.txt b/cross/armclang.txt new file mode 100644 index 0000000..955b7ef --- /dev/null +++ b/cross/armclang.txt @@ -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' diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md index 571866f..b1a7bf6 100644 --- a/docs/markdown/Reference-tables.md +++ b/docs/markdown/Reference-tables.md @@ -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 diff --git a/docs/markdown/snippets/armclang-cross.md b/docs/markdown/snippets/armclang-cross.md new file mode 100644 index 0000000..f787876 --- /dev/null +++ b/docs/markdown/snippets/armclang-cross.md @@ -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. diff --git a/mesonbuild/compilers/__init__.py b/mesonbuild/compilers/__init__.py index 217357b..9070a9f 100644 --- a/mesonbuild/compilers/__init__.py +++ b/mesonbuild/compilers/__init__.py @@ -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, diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index cd3aad1..b63dce4 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -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) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 45caf55..21aab11 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -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): diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index c3bb59d..126900a 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -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) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 793ed22..9d1d9e1 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -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 |