1# Copyright 2012-2020 Meson development team 2 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6 7# http://www.apache.org/licenses/LICENSE-2.0 8 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Representations specific to the arm family of compilers.""" 16 17import os 18import typing as T 19 20from ... import mesonlib 21from ...linkers import ArmClangDynamicLinker 22from ...mesonlib import OptionKey 23from ..compilers import clike_debug_args 24from .clang import clang_color_args 25 26if T.TYPE_CHECKING: 27 from ...environment import Environment 28 from ...compilers.compilers import Compiler 29else: 30 # This is a bit clever, for mypy we pretend that these mixins descend from 31 # Compiler, so we get all of the methods and attributes defined for us, but 32 # for runtime we make them descend from object (which all classes normally 33 # do). This gives up DRYer type checking, with no runtime impact 34 Compiler = object 35 36arm_buildtype_args = { 37 'plain': [], 38 'debug': [], 39 'debugoptimized': [], 40 'release': [], 41 'minsize': [], 42 'custom': [], 43} # type: T.Dict[str, T.List[str]] 44 45arm_optimization_args = { 46 '0': ['-O0'], 47 'g': ['-g'], 48 '1': ['-O1'], 49 '2': [], # Compiler defaults to -O2 50 '3': ['-O3', '-Otime'], 51 's': ['-O3'], # Compiler defaults to -Ospace 52} # type: T.Dict[str, T.List[str]] 53 54armclang_buildtype_args = { 55 'plain': [], 56 'debug': [], 57 'debugoptimized': [], 58 'release': [], 59 'minsize': [], 60 'custom': [], 61} # type: T.Dict[str, T.List[str]] 62 63armclang_optimization_args = { 64 '0': [], # Compiler defaults to -O0 65 'g': ['-g'], 66 '1': ['-O1'], 67 '2': ['-O2'], 68 '3': ['-O3'], 69 's': ['-Oz'] 70} # type: T.Dict[str, T.List[str]] 71 72 73class ArmCompiler(Compiler): 74 75 """Functionality that is common to all ARM family compilers.""" 76 77 def __init__(self) -> None: 78 if not self.is_cross: 79 raise mesonlib.EnvironmentException('armcc supports only cross-compilation.') 80 self.id = 'arm' 81 default_warn_args = [] # type: T.List[str] 82 self.warn_args = {'0': [], 83 '1': default_warn_args, 84 '2': default_warn_args + [], 85 '3': default_warn_args + []} # type: T.Dict[str, T.List[str]] 86 # Assembly 87 self.can_compile_suffixes.add('s') 88 89 def get_pic_args(self) -> T.List[str]: 90 # FIXME: Add /ropi, /rwpi, /fpic etc. qualifiers to --apcs 91 return [] 92 93 def get_buildtype_args(self, buildtype: str) -> T.List[str]: 94 return arm_buildtype_args[buildtype] 95 96 # Override CCompiler.get_always_args 97 def get_always_args(self) -> T.List[str]: 98 return [] 99 100 def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: 101 return ['--depend_target', outtarget, '--depend', outfile, '--depend_single_line'] 102 103 def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: 104 # FIXME: Add required arguments 105 # NOTE from armcc user guide: 106 # "Support for Precompiled Header (PCH) files is deprecated from ARM Compiler 5.05 107 # onwards on all platforms. Note that ARM Compiler on Windows 8 never supported 108 # PCH files." 109 return [] 110 111 def get_pch_suffix(self) -> str: 112 # NOTE from armcc user guide: 113 # "Support for Precompiled Header (PCH) files is deprecated from ARM Compiler 5.05 114 # onwards on all platforms. Note that ARM Compiler on Windows 8 never supported 115 # PCH files." 116 return 'pch' 117 118 def thread_flags(self, env: 'Environment') -> T.List[str]: 119 return [] 120 121 def get_coverage_args(self) -> T.List[str]: 122 return [] 123 124 def get_optimization_args(self, optimization_level: str) -> T.List[str]: 125 return arm_optimization_args[optimization_level] 126 127 def get_debug_args(self, is_debug: bool) -> T.List[str]: 128 return clike_debug_args[is_debug] 129 130 def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], build_dir: str) -> T.List[str]: 131 for idx, i in enumerate(parameter_list): 132 if i[:2] == '-I' or i[:2] == '-L': 133 parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) 134 135 return parameter_list 136 137 138class ArmclangCompiler(Compiler): 139 140 def __init__(self) -> None: 141 if not self.is_cross: 142 raise mesonlib.EnvironmentException('armclang supports only cross-compilation.') 143 # Check whether 'armlink' is available in path 144 if not isinstance(self.linker, ArmClangDynamicLinker): 145 raise mesonlib.EnvironmentException(f'Unsupported Linker {self.linker.exelist}, must be armlink') 146 if not mesonlib.version_compare(self.version, '==' + self.linker.version): 147 raise mesonlib.EnvironmentException('armlink version does not match with compiler version') 148 self.id = 'armclang' 149 self.base_options = { 150 OptionKey(o) for o in 151 ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage', 152 'b_ndebug', 'b_staticpic', 'b_colorout']} 153 # Assembly 154 self.can_compile_suffixes.add('s') 155 156 def get_pic_args(self) -> T.List[str]: 157 # PIC support is not enabled by default for ARM, 158 # if users want to use it, they need to add the required arguments explicitly 159 return [] 160 161 def get_colorout_args(self, colortype: str) -> T.List[str]: 162 return clang_color_args[colortype][:] 163 164 def get_buildtype_args(self, buildtype: str) -> T.List[str]: 165 return armclang_buildtype_args[buildtype] 166 167 def get_pch_suffix(self) -> str: 168 return 'gch' 169 170 def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: 171 # Workaround for Clang bug http://llvm.org/bugs/show_bug.cgi?id=15136 172 # This flag is internal to Clang (or at least not documented on the man page) 173 # so it might change semantics at any time. 174 return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))] 175 176 def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: 177 return ['-MD', '-MT', outtarget, '-MF', outfile] 178 179 def get_optimization_args(self, optimization_level: str) -> T.List[str]: 180 return armclang_optimization_args[optimization_level] 181 182 def get_debug_args(self, is_debug: bool) -> T.List[str]: 183 return clike_debug_args[is_debug] 184 185 def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], build_dir: str) -> T.List[str]: 186 for idx, i in enumerate(parameter_list): 187 if i[:2] == '-I' or i[:2] == '-L': 188 parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) 189 190 return parameter_list 191