Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 1 | # SPDX-Licnese-Identifier: Apache-2.0 |
| 2 | # Copyright 2012-2021 The Meson development team |
Christian Clauss | a502085 | 2021-10-01 00:03:23 +0200 | [diff] [blame^] | 3 | # Copyright © 2021 Intel Corporation |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 4 | |
| 5 | import enum |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 6 | import functools |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 7 | import typing as T |
Laurin-Luis Lehning | 281f5ab | 2021-06-22 07:59:08 +0200 | [diff] [blame] | 8 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 9 | from .. import build |
| 10 | from .. import coredata |
| 11 | from .. import dependencies |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 12 | from .. import mesonlib |
| 13 | from .. import mlog |
Paolo Bonzini | 8596b3b | 2021-07-22 12:01:01 +0200 | [diff] [blame] | 14 | from ..compilers import SUFFIX_TO_LANG |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 15 | from ..compilers.compilers import CompileCheckMode |
| 16 | from ..interpreterbase import (ObjectHolder, noPosargs, noKwargs, |
| 17 | FeatureNew, disablerIfNotFound, |
| 18 | InterpreterException) |
| 19 | from ..interpreterbase.decorators import ContainerTypeInfo, typed_kwargs, KwargInfo, typed_pos_args |
| 20 | from .interpreterobjects import (extract_required_kwarg, extract_search_dirs) |
Dylan Baker | 11fbaf2 | 2021-08-27 11:47:12 -0700 | [diff] [blame] | 21 | from .type_checking import REQUIRED_KW, in_set_validator, NoneType |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 22 | |
Daniel Mensinger | 202e345 | 2021-06-11 16:01:14 +0200 | [diff] [blame] | 23 | if T.TYPE_CHECKING: |
Daniel Mensinger | 7c757df | 2021-06-17 00:27:39 +0200 | [diff] [blame] | 24 | from ..interpreter import Interpreter |
Daniel Mensinger | 202e345 | 2021-06-11 16:01:14 +0200 | [diff] [blame] | 25 | from ..compilers import Compiler, RunResult |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 26 | from ..interpreterbase import TYPE_var, TYPE_kwargs |
| 27 | from .kwargs import ExtractRequired, ExtractSearchDirs |
| 28 | |
| 29 | from typing_extensions import TypedDict, Literal |
| 30 | |
| 31 | class GetSupportedArgumentKw(TypedDict): |
| 32 | |
| 33 | checked: Literal['warn', 'require', 'off'] |
| 34 | |
| 35 | class AlignmentKw(TypedDict): |
| 36 | |
| 37 | prefix: str |
| 38 | args: T.List[str] |
| 39 | dependencies: T.List[dependencies.Dependency] |
| 40 | |
| 41 | class CompileKW(TypedDict): |
| 42 | |
| 43 | name: str |
| 44 | no_builtin_args: bool |
| 45 | include_directories: T.List[build.IncludeDirs] |
| 46 | args: T.List[str] |
| 47 | dependencies: T.List[dependencies.Dependency] |
| 48 | |
| 49 | class CommonKW(TypedDict): |
| 50 | |
| 51 | prefix: str |
| 52 | no_builtin_args: bool |
| 53 | include_directories: T.List[build.IncludeDirs] |
| 54 | args: T.List[str] |
| 55 | dependencies: T.List[dependencies.Dependency] |
| 56 | |
| 57 | class CompupteIntKW(CommonKW): |
| 58 | |
| 59 | guess: T.Optional[int] |
| 60 | high: T.Optional[int] |
| 61 | low: T.Optional[int] |
| 62 | |
| 63 | class HeaderKW(CommonKW, ExtractRequired): |
| 64 | pass |
| 65 | |
| 66 | class FindLibraryKW(ExtractRequired, ExtractSearchDirs): |
| 67 | |
| 68 | disabler: bool |
| 69 | has_headers: T.List[str] |
| 70 | static: bool |
| 71 | |
| 72 | # This list must be all of the `HeaderKW` values with `header_` |
| 73 | # prepended to the key |
| 74 | header_args: T.List[str] |
| 75 | header_dependencies: T.List[dependencies.Dependency] |
| 76 | header_include_directories: T.List[build.IncludeDirs] |
| 77 | header_no_builtin_args: bool |
| 78 | header_prefix: str |
| 79 | header_required: T.Union[bool, coredata.UserFeatureOption] |
| 80 | |
| 81 | |
| 82 | class _TestMode(enum.Enum): |
| 83 | |
| 84 | """Whether we're doing a compiler or linker check.""" |
| 85 | |
| 86 | COMPILER = 0 |
| 87 | LINKER = 1 |
| 88 | |
Daniel Mensinger | 202e345 | 2021-06-11 16:01:14 +0200 | [diff] [blame] | 89 | |
| 90 | class TryRunResultHolder(ObjectHolder['RunResult']): |
Daniel Mensinger | 7c757df | 2021-06-17 00:27:39 +0200 | [diff] [blame] | 91 | def __init__(self, res: 'RunResult', interpreter: 'Interpreter'): |
| 92 | super().__init__(res, interpreter) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 93 | self.methods.update({'returncode': self.returncode_method, |
| 94 | 'compiled': self.compiled_method, |
| 95 | 'stdout': self.stdout_method, |
| 96 | 'stderr': self.stderr_method, |
| 97 | }) |
| 98 | |
| 99 | @noPosargs |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 100 | @noKwargs |
Dylan Baker | bcb5400 | 2021-07-26 15:54:56 -0700 | [diff] [blame] | 101 | def returncode_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> int: |
Daniel Mensinger | 202e345 | 2021-06-11 16:01:14 +0200 | [diff] [blame] | 102 | return self.held_object.returncode |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 103 | |
| 104 | @noPosargs |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 105 | @noKwargs |
Dylan Baker | bcb5400 | 2021-07-26 15:54:56 -0700 | [diff] [blame] | 106 | def compiled_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool: |
Daniel Mensinger | 202e345 | 2021-06-11 16:01:14 +0200 | [diff] [blame] | 107 | return self.held_object.compiled |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 108 | |
| 109 | @noPosargs |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 110 | @noKwargs |
Dylan Baker | bcb5400 | 2021-07-26 15:54:56 -0700 | [diff] [blame] | 111 | def stdout_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str: |
Daniel Mensinger | 202e345 | 2021-06-11 16:01:14 +0200 | [diff] [blame] | 112 | return self.held_object.stdout |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 113 | |
| 114 | @noPosargs |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 115 | @noKwargs |
Dylan Baker | bcb5400 | 2021-07-26 15:54:56 -0700 | [diff] [blame] | 116 | def stderr_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str: |
Daniel Mensinger | 202e345 | 2021-06-11 16:01:14 +0200 | [diff] [blame] | 117 | return self.held_object.stderr |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 118 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 119 | |
| 120 | _ARGS_KW: KwargInfo[T.List[str]] = KwargInfo( |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 121 | 'args', |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 122 | ContainerTypeInfo(list, str), |
| 123 | listify=True, |
| 124 | default=[], |
| 125 | ) |
| 126 | _DEPENDENCIES_KW: KwargInfo[T.List['dependencies.Dependency']] = KwargInfo( |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 127 | 'dependencies', |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 128 | ContainerTypeInfo(list, dependencies.Dependency), |
| 129 | listify=True, |
| 130 | default=[], |
| 131 | ) |
| 132 | _INCLUDE_DIRS_KW: KwargInfo[T.List[build.IncludeDirs]] = KwargInfo( |
| 133 | 'include_directories', |
| 134 | ContainerTypeInfo(list, build.IncludeDirs), |
| 135 | default=[], |
| 136 | listify=True, |
| 137 | ) |
| 138 | _PREFIX_KW = KwargInfo('prefix', str, default='') |
| 139 | _NO_BUILTIN_ARGS_KW = KwargInfo('no_builtin_args', bool, default=False) |
| 140 | _NAME_KW = KwargInfo('name', str, default='') |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 141 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 142 | # Many of the compiler methods take this kwarg signature exactly, this allows |
| 143 | # simplifying the `typed_kwargs` calls |
| 144 | _COMMON_KWS: T.List[KwargInfo] = [_ARGS_KW, _DEPENDENCIES_KW, _INCLUDE_DIRS_KW, _PREFIX_KW, _NO_BUILTIN_ARGS_KW] |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 145 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 146 | # Common methods of compiles, links, runs, and similar |
| 147 | _COMPILES_KWS: T.List[KwargInfo] = [_NAME_KW, _ARGS_KW, _DEPENDENCIES_KW, _INCLUDE_DIRS_KW, _NO_BUILTIN_ARGS_KW] |
| 148 | |
| 149 | _HEADER_KWS: T.List[KwargInfo] = [REQUIRED_KW.evolve(since='0.50.0', default=False), *_COMMON_KWS] |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 150 | |
Daniel Mensinger | 202e345 | 2021-06-11 16:01:14 +0200 | [diff] [blame] | 151 | class CompilerHolder(ObjectHolder['Compiler']): |
Daniel Mensinger | 7c757df | 2021-06-17 00:27:39 +0200 | [diff] [blame] | 152 | def __init__(self, compiler: 'Compiler', interpreter: 'Interpreter'): |
| 153 | super().__init__(compiler, interpreter) |
| 154 | self.environment = self.env |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 155 | self.methods.update({'compiles': self.compiles_method, |
| 156 | 'links': self.links_method, |
| 157 | 'get_id': self.get_id_method, |
| 158 | 'get_linker_id': self.get_linker_id_method, |
| 159 | 'compute_int': self.compute_int_method, |
| 160 | 'sizeof': self.sizeof_method, |
| 161 | 'get_define': self.get_define_method, |
| 162 | 'check_header': self.check_header_method, |
| 163 | 'has_header': self.has_header_method, |
| 164 | 'has_header_symbol': self.has_header_symbol_method, |
| 165 | 'run': self.run_method, |
| 166 | 'has_function': self.has_function_method, |
| 167 | 'has_member': self.has_member_method, |
| 168 | 'has_members': self.has_members_method, |
| 169 | 'has_type': self.has_type_method, |
| 170 | 'alignment': self.alignment_method, |
| 171 | 'version': self.version_method, |
| 172 | 'cmd_array': self.cmd_array_method, |
| 173 | 'find_library': self.find_library_method, |
| 174 | 'has_argument': self.has_argument_method, |
| 175 | 'has_function_attribute': self.has_func_attribute_method, |
| 176 | 'get_supported_function_attributes': self.get_supported_function_attributes_method, |
| 177 | 'has_multi_arguments': self.has_multi_arguments_method, |
| 178 | 'get_supported_arguments': self.get_supported_arguments_method, |
| 179 | 'first_supported_argument': self.first_supported_argument_method, |
| 180 | 'has_link_argument': self.has_link_argument_method, |
| 181 | 'has_multi_link_arguments': self.has_multi_link_arguments_method, |
| 182 | 'get_supported_link_arguments': self.get_supported_link_arguments_method, |
| 183 | 'first_supported_link_argument': self.first_supported_link_argument_method, |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 184 | 'symbols_have_underscore_prefix': self.symbols_have_underscore_prefix_method, |
| 185 | 'get_argument_syntax': self.get_argument_syntax_method, |
| 186 | }) |
| 187 | |
Daniel Mensinger | 202e345 | 2021-06-11 16:01:14 +0200 | [diff] [blame] | 188 | @property |
| 189 | def compiler(self) -> 'Compiler': |
| 190 | return self.held_object |
| 191 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 192 | @staticmethod |
| 193 | def _dep_msg(deps: T.List['dependencies.Dependency'], endl: str) -> str: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 194 | msg_single = 'with dependency {}' |
| 195 | msg_many = 'with dependencies {}' |
| 196 | if not deps: |
| 197 | return endl |
| 198 | if endl is None: |
| 199 | endl = '' |
| 200 | names = [] |
| 201 | for d in deps: |
| 202 | if isinstance(d, dependencies.InternalDependency): |
| 203 | continue |
| 204 | if isinstance(d, dependencies.ExternalLibrary): |
| 205 | name = '-l' + d.name |
| 206 | else: |
| 207 | name = d.name |
| 208 | names.append(name) |
| 209 | if not names: |
| 210 | return None |
| 211 | tpl = msg_many if len(names) > 1 else msg_single |
| 212 | return tpl.format(', '.join(names)) + endl |
| 213 | |
| 214 | @noPosargs |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 215 | @noKwargs |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 216 | def version_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 217 | return self.compiler.version |
| 218 | |
| 219 | @noPosargs |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 220 | @noKwargs |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 221 | def cmd_array_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> T.List[str]: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 222 | return self.compiler.exelist |
| 223 | |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 224 | def _determine_args(self, nobuiltins: bool, |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 225 | incdirs: T.List[build.IncludeDirs], |
| 226 | extra_args: T.List[str], |
| 227 | mode: CompileCheckMode = CompileCheckMode.LINK) -> T.List[str]: |
| 228 | args: T.List[str] = [] |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 229 | for i in incdirs: |
Daniel Mensinger | 7c757df | 2021-06-17 00:27:39 +0200 | [diff] [blame] | 230 | for idir in i.to_string_list(self.environment.get_source_dir()): |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 231 | args.extend(self.compiler.get_include_args(idir, False)) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 232 | if not nobuiltins: |
| 233 | opts = self.environment.coredata.options |
| 234 | args += self.compiler.get_option_compile_args(opts) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 235 | if mode is CompileCheckMode.LINK: |
| 236 | args.extend(self.compiler.get_option_link_args(opts)) |
| 237 | args.extend(extra_args) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 238 | return args |
| 239 | |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 240 | def _determine_dependencies(self, deps: T.List['dependencies.Dependency'], endl: str = ':') -> T.Tuple[T.List['dependencies.Dependency'], str]: |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 241 | if deps: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 242 | final_deps = [] |
| 243 | while deps: |
| 244 | next_deps = [] |
Daniel Mensinger | 7c757df | 2021-06-17 00:27:39 +0200 | [diff] [blame] | 245 | for d in mesonlib.listify(deps): |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 246 | if not isinstance(d, dependencies.Dependency) or d.is_built(): |
| 247 | raise InterpreterException('Dependencies must be external dependencies') |
| 248 | final_deps.append(d) |
| 249 | next_deps.extend(d.ext_deps) |
| 250 | deps = next_deps |
| 251 | deps = final_deps |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 252 | else: |
Christian Clauss | a502085 | 2021-10-01 00:03:23 +0200 | [diff] [blame^] | 253 | # Ensure that we always return a new instance |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 254 | deps = deps.copy() |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 255 | return deps, self._dep_msg(deps, endl) |
| 256 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 257 | @typed_pos_args('compiler.alignment', str) |
| 258 | @typed_kwargs( |
| 259 | 'compiler.alignment', |
| 260 | _PREFIX_KW, |
| 261 | _ARGS_KW, |
| 262 | _DEPENDENCIES_KW, |
| 263 | ) |
| 264 | def alignment_method(self, args: T.Tuple[str], kwargs: 'AlignmentKw') -> int: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 265 | typename = args[0] |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 266 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 267 | result = self.compiler.alignment(typename, kwargs['prefix'], self.environment, |
| 268 | extra_args=kwargs['args'], |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 269 | dependencies=deps) |
| 270 | mlog.log('Checking for alignment of', mlog.bold(typename, True), msg, result) |
| 271 | return result |
| 272 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 273 | @typed_pos_args('compiler.run', (str, mesonlib.File)) |
| 274 | @typed_kwargs('compiler.run', *_COMPILES_KWS) |
| 275 | def run_method(self, args: T.Tuple['mesonlib.FileOrString'], kwargs: 'CompileKW') -> 'RunResult': |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 276 | code = args[0] |
| 277 | if isinstance(code, mesonlib.File): |
| 278 | code = mesonlib.File.from_absolute_file( |
| 279 | code.rel_to_builddir(self.environment.source_dir)) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 280 | testname = kwargs['name'] |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 281 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 282 | deps, msg = self._determine_dependencies(kwargs['dependencies'], endl=None) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 283 | result = self.compiler.run(code, self.environment, extra_args=extra_args, |
| 284 | dependencies=deps) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 285 | if testname: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 286 | if not result.compiled: |
| 287 | h = mlog.red('DID NOT COMPILE') |
| 288 | elif result.returncode == 0: |
| 289 | h = mlog.green('YES') |
| 290 | else: |
| 291 | h = mlog.red('NO (%d)' % result.returncode) |
| 292 | mlog.log('Checking if', mlog.bold(testname, True), msg, 'runs:', h) |
Daniel Mensinger | 7c757df | 2021-06-17 00:27:39 +0200 | [diff] [blame] | 293 | return result |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 294 | |
| 295 | @noPosargs |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 296 | @noKwargs |
Dylan Baker | 7dda90f | 2021-07-26 14:58:24 -0700 | [diff] [blame] | 297 | def get_id_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 298 | return self.compiler.get_id() |
| 299 | |
| 300 | @noPosargs |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 301 | @noKwargs |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 302 | @FeatureNew('compiler.get_linker_id', '0.53.0') |
Dylan Baker | 7dda90f | 2021-07-26 14:58:24 -0700 | [diff] [blame] | 303 | def get_linker_id_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 304 | return self.compiler.get_linker_id() |
| 305 | |
| 306 | @noPosargs |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 307 | @noKwargs |
Dylan Baker | 7dda90f | 2021-07-26 14:58:24 -0700 | [diff] [blame] | 308 | def symbols_have_underscore_prefix_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 309 | ''' |
| 310 | Check if the compiler prefixes _ (underscore) to global C symbols |
| 311 | See: https://en.wikipedia.org/wiki/Name_mangling#C |
| 312 | ''' |
| 313 | return self.compiler.symbols_have_underscore_prefix(self.environment) |
| 314 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 315 | @typed_pos_args('compiler.has_member', str, str) |
| 316 | @typed_kwargs('compiler.has_member', *_COMMON_KWS) |
| 317 | def has_member_method(self, args: T.Tuple[str, str], kwargs: 'CommonKW') -> bool: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 318 | typename, membername = args |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 319 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 320 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 321 | had, cached = self.compiler.has_members(typename, [membername], kwargs['prefix'], |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 322 | self.environment, |
| 323 | extra_args=extra_args, |
| 324 | dependencies=deps) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 325 | cached_msg = mlog.blue('(cached)') if cached else '' |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 326 | if had: |
| 327 | hadtxt = mlog.green('YES') |
| 328 | else: |
| 329 | hadtxt = mlog.red('NO') |
| 330 | mlog.log('Checking whether type', mlog.bold(typename, True), |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 331 | 'has member', mlog.bold(membername, True), msg, hadtxt, cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 332 | return had |
| 333 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 334 | @typed_pos_args('compiler.has_members', str, varargs=str, min_varargs=1) |
| 335 | @typed_kwargs('compiler.has_members', *_COMMON_KWS) |
| 336 | def has_members_method(self, args: T.Tuple[str, T.List[str]], kwargs: 'CommonKW') -> bool: |
| 337 | typename, membernames = args |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 338 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 339 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 340 | had, cached = self.compiler.has_members(typename, membernames, kwargs['prefix'], |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 341 | self.environment, |
| 342 | extra_args=extra_args, |
| 343 | dependencies=deps) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 344 | cached_msg = mlog.blue('(cached)') if cached else '' |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 345 | if had: |
| 346 | hadtxt = mlog.green('YES') |
| 347 | else: |
| 348 | hadtxt = mlog.red('NO') |
| 349 | members = mlog.bold(', '.join([f'"{m}"' for m in membernames])) |
| 350 | mlog.log('Checking whether type', mlog.bold(typename, True), |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 351 | 'has members', members, msg, hadtxt, cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 352 | return had |
| 353 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 354 | @typed_pos_args('compiler.has_function', str) |
Daniel Mensinger | c10e228 | 2021-08-21 16:28:39 +0200 | [diff] [blame] | 355 | @typed_kwargs('compiler.has_function', *_COMMON_KWS) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 356 | def has_function_method(self, args: T.Tuple[str], kwargs: 'CommonKW') -> bool: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 357 | funcname = args[0] |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 358 | extra_args = self._determine_args(kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 359 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 360 | had, cached = self.compiler.has_function(funcname, kwargs['prefix'], self.environment, |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 361 | extra_args=extra_args, |
| 362 | dependencies=deps) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 363 | cached_msg = mlog.blue('(cached)') if cached else '' |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 364 | if had: |
| 365 | hadtxt = mlog.green('YES') |
| 366 | else: |
| 367 | hadtxt = mlog.red('NO') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 368 | mlog.log('Checking for function', mlog.bold(funcname, True), msg, hadtxt, cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 369 | return had |
| 370 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 371 | @typed_pos_args('compiler.has_type', str) |
| 372 | @typed_kwargs('compiler.has_type', *_COMMON_KWS) |
| 373 | def has_type_method(self, args: T.Tuple[str], kwargs: 'CommonKW') -> bool: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 374 | typename = args[0] |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 375 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 376 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 377 | had, cached = self.compiler.has_type(typename, kwargs['prefix'], self.environment, |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 378 | extra_args=extra_args, dependencies=deps) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 379 | cached_msg = mlog.blue('(cached)') if cached else '' |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 380 | if had: |
| 381 | hadtxt = mlog.green('YES') |
| 382 | else: |
| 383 | hadtxt = mlog.red('NO') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 384 | mlog.log('Checking for type', mlog.bold(typename, True), msg, hadtxt, cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 385 | return had |
| 386 | |
| 387 | @FeatureNew('compiler.compute_int', '0.40.0') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 388 | @typed_pos_args('compiler.compute_int', str) |
| 389 | @typed_kwargs( |
| 390 | 'compiler.compute_int', |
Dylan Baker | 11fbaf2 | 2021-08-27 11:47:12 -0700 | [diff] [blame] | 391 | KwargInfo('low', (int, NoneType)), |
| 392 | KwargInfo('high', (int, NoneType)), |
| 393 | KwargInfo('guess', (int, NoneType)), |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 394 | *_COMMON_KWS, |
| 395 | ) |
| 396 | def compute_int_method(self, args: T.Tuple[str], kwargs: 'CompupteIntKW') -> int: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 397 | expression = args[0] |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 398 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 399 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 400 | res = self.compiler.compute_int(expression, kwargs['low'], kwargs['high'], |
| 401 | kwargs['guess'], kwargs['prefix'], |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 402 | self.environment, extra_args=extra_args, |
| 403 | dependencies=deps) |
| 404 | mlog.log('Computing int of', mlog.bold(expression, True), msg, res) |
| 405 | return res |
| 406 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 407 | @typed_pos_args('compiler.sizeof', str) |
| 408 | @typed_kwargs('compiler.sizeof', *_COMMON_KWS) |
| 409 | def sizeof_method(self, args: T.Tuple[str], kwargs: 'CommonKW') -> int: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 410 | element = args[0] |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 411 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 412 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 413 | esize = self.compiler.sizeof(element, kwargs['prefix'], self.environment, |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 414 | extra_args=extra_args, dependencies=deps) |
| 415 | mlog.log('Checking for size of', mlog.bold(element, True), msg, esize) |
| 416 | return esize |
| 417 | |
| 418 | @FeatureNew('compiler.get_define', '0.40.0') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 419 | @typed_pos_args('compiler.get_define', str) |
| 420 | @typed_kwargs('compiler.get_define', *_COMMON_KWS) |
| 421 | def get_define_method(self, args: T.Tuple[str], kwargs: 'CommonKW') -> str: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 422 | element = args[0] |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 423 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 424 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 425 | value, cached = self.compiler.get_define(element, kwargs['prefix'], self.environment, |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 426 | extra_args=extra_args, |
| 427 | dependencies=deps) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 428 | cached_msg = mlog.blue('(cached)') if cached else '' |
| 429 | mlog.log('Fetching value of define', mlog.bold(element, True), msg, value, cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 430 | return value |
| 431 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 432 | @typed_pos_args('compiler.compiles', (str, mesonlib.File)) |
| 433 | @typed_kwargs('compiler.compiles', *_COMPILES_KWS) |
| 434 | def compiles_method(self, args: T.Tuple['mesonlib.FileOrString'], kwargs: 'CompileKW') -> bool: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 435 | code = args[0] |
| 436 | if isinstance(code, mesonlib.File): |
| 437 | code = mesonlib.File.from_absolute_file( |
| 438 | code.rel_to_builddir(self.environment.source_dir)) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 439 | testname = kwargs['name'] |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 440 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 441 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 442 | result, cached = self.compiler.compiles(code, self.environment, |
| 443 | extra_args=extra_args, |
| 444 | dependencies=deps) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 445 | if testname: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 446 | if result: |
| 447 | h = mlog.green('YES') |
| 448 | else: |
| 449 | h = mlog.red('NO') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 450 | cached_msg = mlog.blue('(cached)') if cached else '' |
| 451 | mlog.log('Checking if', mlog.bold(testname, True), msg, 'compiles:', h, cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 452 | return result |
| 453 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 454 | @typed_pos_args('compiler.links', (str, mesonlib.File)) |
| 455 | @typed_kwargs('compiler.links', *_COMPILES_KWS) |
| 456 | def links_method(self, args: T.Tuple['mesonlib.FileOrString'], kwargs: 'CompileKW') -> bool: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 457 | code = args[0] |
Paolo Bonzini | 8596b3b | 2021-07-22 12:01:01 +0200 | [diff] [blame] | 458 | compiler = None |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 459 | if isinstance(code, mesonlib.File): |
| 460 | code = mesonlib.File.from_absolute_file( |
| 461 | code.rel_to_builddir(self.environment.source_dir)) |
Paolo Bonzini | 8596b3b | 2021-07-22 12:01:01 +0200 | [diff] [blame] | 462 | suffix = code.suffix |
| 463 | if suffix not in self.compiler.file_suffixes: |
| 464 | for_machine = self.compiler.for_machine |
| 465 | clist = self.interpreter.coredata.compilers[for_machine] |
| 466 | if suffix not in SUFFIX_TO_LANG: |
| 467 | # just pass it to the compiler driver |
| 468 | mlog.warning(f'Unknown suffix for test file {code}') |
| 469 | elif SUFFIX_TO_LANG[suffix] not in clist: |
| 470 | mlog.warning(f'Passed {SUFFIX_TO_LANG[suffix]} source to links method, not specified for {for_machine.get_lower_case_name()} machine.') |
| 471 | else: |
| 472 | compiler = clist[SUFFIX_TO_LANG[suffix]] |
| 473 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 474 | testname = kwargs['name'] |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 475 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 476 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 477 | result, cached = self.compiler.links(code, self.environment, |
Paolo Bonzini | 8596b3b | 2021-07-22 12:01:01 +0200 | [diff] [blame] | 478 | compiler=compiler, |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 479 | extra_args=extra_args, |
| 480 | dependencies=deps) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 481 | cached_msg = mlog.blue('(cached)') if cached else '' |
| 482 | if testname: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 483 | if result: |
| 484 | h = mlog.green('YES') |
| 485 | else: |
| 486 | h = mlog.red('NO') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 487 | mlog.log('Checking if', mlog.bold(testname, True), msg, 'links:', h, cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 488 | return result |
| 489 | |
| 490 | @FeatureNew('compiler.check_header', '0.47.0') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 491 | @typed_pos_args('compiler.check_header', str) |
| 492 | @typed_kwargs('compiler.check_header', *_HEADER_KWS) |
| 493 | def check_header_method(self, args: T.Tuple[str], kwargs: 'HeaderKW') -> bool: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 494 | hname = args[0] |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 495 | disabled, required, feature = extract_required_kwarg(kwargs, self.subproject, default=False) |
| 496 | if disabled: |
| 497 | mlog.log('Check usable header', mlog.bold(hname, True), 'skipped: feature', mlog.bold(feature), 'disabled') |
| 498 | return False |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 499 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 500 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 501 | haz, cached = self.compiler.check_header(hname, kwargs['prefix'], self.environment, |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 502 | extra_args=extra_args, |
| 503 | dependencies=deps) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 504 | cached_msg = mlog.blue('(cached)') if cached else '' |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 505 | if required and not haz: |
| 506 | raise InterpreterException(f'{self.compiler.get_display_language()} header {hname!r} not usable') |
| 507 | elif haz: |
| 508 | h = mlog.green('YES') |
| 509 | else: |
| 510 | h = mlog.red('NO') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 511 | mlog.log('Check usable header', mlog.bold(hname, True), msg, h, cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 512 | return haz |
| 513 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 514 | def _has_header_impl(self, hname: str, kwargs: 'HeaderKW') -> bool: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 515 | disabled, required, feature = extract_required_kwarg(kwargs, self.subproject, default=False) |
| 516 | if disabled: |
| 517 | mlog.log('Has header', mlog.bold(hname, True), 'skipped: feature', mlog.bold(feature), 'disabled') |
| 518 | return False |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 519 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 520 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 521 | haz, cached = self.compiler.has_header(hname, kwargs['prefix'], self.environment, |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 522 | extra_args=extra_args, dependencies=deps) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 523 | cached_msg = mlog.blue('(cached)') if cached else '' |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 524 | if required and not haz: |
| 525 | raise InterpreterException(f'{self.compiler.get_display_language()} header {hname!r} not found') |
| 526 | elif haz: |
| 527 | h = mlog.green('YES') |
| 528 | else: |
| 529 | h = mlog.red('NO') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 530 | mlog.log('Has header', mlog.bold(hname, True), msg, h, cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 531 | return haz |
| 532 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 533 | @typed_pos_args('compiler.has_header', str) |
| 534 | @typed_kwargs('compiler.has_header', *_HEADER_KWS) |
| 535 | def has_header_method(self, args: T.Tuple[str], kwargs: 'HeaderKW') -> bool: |
| 536 | return self._has_header_impl(args[0], kwargs) |
| 537 | |
| 538 | @typed_pos_args('compiler.has_header_symbol', str, str) |
| 539 | @typed_kwargs('compiler.has_header_symbol', *_HEADER_KWS) |
| 540 | def has_header_symbol_method(self, args: T.Tuple[str, str], kwargs: 'HeaderKW') -> bool: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 541 | hname, symbol = args |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 542 | disabled, required, feature = extract_required_kwarg(kwargs, self.subproject, default=False) |
| 543 | if disabled: |
| 544 | mlog.log(f'Header <{hname}> has symbol', mlog.bold(symbol, True), 'skipped: feature', mlog.bold(feature), 'disabled') |
| 545 | return False |
Dylan Baker | 272674e | 2021-07-27 12:59:56 -0700 | [diff] [blame] | 546 | extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args']) |
| 547 | deps, msg = self._determine_dependencies(kwargs['dependencies']) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 548 | haz, cached = self.compiler.has_header_symbol(hname, symbol, kwargs['prefix'], self.environment, |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 549 | extra_args=extra_args, |
| 550 | dependencies=deps) |
| 551 | if required and not haz: |
| 552 | raise InterpreterException(f'{self.compiler.get_display_language()} symbol {symbol} not found in header {hname}') |
| 553 | elif haz: |
| 554 | h = mlog.green('YES') |
| 555 | else: |
| 556 | h = mlog.red('NO') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 557 | cached_msg = mlog.blue('(cached)') if cached else '' |
| 558 | mlog.log(f'Header <{hname}> has symbol', mlog.bold(symbol, True), msg, h, cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 559 | return haz |
| 560 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 561 | def notfound_library(self, libname: str) -> 'dependencies.ExternalLibrary': |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 562 | lib = dependencies.ExternalLibrary(libname, None, |
| 563 | self.environment, |
| 564 | self.compiler.language, |
| 565 | silent=True) |
Daniel Mensinger | 7c757df | 2021-06-17 00:27:39 +0200 | [diff] [blame] | 566 | return lib |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 567 | |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 568 | @disablerIfNotFound |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 569 | @typed_pos_args('compiler.find_library', str) |
| 570 | @typed_kwargs( |
| 571 | 'compiler.find_library', |
| 572 | KwargInfo('required', (bool, coredata.UserFeatureOption), default=True), |
| 573 | KwargInfo('has_headers', ContainerTypeInfo(list, str), listify=True, default=[], since='0.50.0'), |
Dylan Baker | 11fbaf2 | 2021-08-27 11:47:12 -0700 | [diff] [blame] | 574 | KwargInfo('static', (bool, NoneType), since='0.51.0'), |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 575 | KwargInfo('disabler', bool, default=False, since='0.49.0'), |
| 576 | KwargInfo('dirs', ContainerTypeInfo(list, str), listify=True, default=[]), |
Eli Schwartz | e8a85fa | 2021-08-15 11:08:26 -0400 | [diff] [blame] | 577 | *(k.evolve(name=f'header_{k.name}') for k in _HEADER_KWS) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 578 | ) |
| 579 | def find_library_method(self, args: T.Tuple[str], kwargs: 'FindLibraryKW') -> 'dependencies.ExternalLibrary': |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 580 | # TODO add dependencies support? |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 581 | libname = args[0] |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 582 | |
| 583 | disabled, required, feature = extract_required_kwarg(kwargs, self.subproject) |
| 584 | if disabled: |
| 585 | mlog.log('Library', mlog.bold(libname), 'skipped: feature', mlog.bold(feature), 'disabled') |
| 586 | return self.notfound_library(libname) |
| 587 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 588 | # This could be done with a comprehension, but that confuses the type |
| 589 | # checker, and having it check this seems valuable |
| 590 | has_header_kwargs: 'HeaderKW' = { |
| 591 | 'required': required, |
| 592 | 'args': kwargs['header_args'], |
| 593 | 'dependencies': kwargs['header_dependencies'], |
| 594 | 'include_directories': kwargs['header_include_directories'], |
| 595 | 'prefix': kwargs['header_prefix'], |
| 596 | 'no_builtin_args': kwargs['header_no_builtin_args'], |
| 597 | } |
| 598 | for h in kwargs['has_headers']: |
| 599 | if not self._has_header_impl(h, has_header_kwargs): |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 600 | return self.notfound_library(libname) |
| 601 | |
| 602 | search_dirs = extract_search_dirs(kwargs) |
| 603 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 604 | if kwargs['static'] is True: |
| 605 | libtype = mesonlib.LibType.STATIC |
| 606 | elif kwargs['static'] is False: |
| 607 | libtype = mesonlib.LibType.SHARED |
| 608 | else: |
| 609 | libtype = mesonlib.LibType.PREFER_SHARED |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 610 | linkargs = self.compiler.find_library(libname, self.environment, search_dirs, libtype) |
| 611 | if required and not linkargs: |
| 612 | if libtype == mesonlib.LibType.PREFER_SHARED: |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 613 | libtype_s = 'shared or static' |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 614 | else: |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 615 | libtype_s = libtype.name.lower() |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 616 | raise InterpreterException('{} {} library {!r} not found' |
| 617 | .format(self.compiler.get_display_language(), |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 618 | libtype_s, libname)) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 619 | lib = dependencies.ExternalLibrary(libname, linkargs, self.environment, |
| 620 | self.compiler.language) |
Daniel Mensinger | 7c757df | 2021-06-17 00:27:39 +0200 | [diff] [blame] | 621 | return lib |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 622 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 623 | def _has_argument_impl(self, arguments: T.Union[str, T.List[str]], |
| 624 | mode: _TestMode = _TestMode.COMPILER) -> bool: |
Christian Clauss | a502085 | 2021-10-01 00:03:23 +0200 | [diff] [blame^] | 625 | """Shared implementation for methods checking compiler and linker arguments.""" |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 626 | # This simplifies the callers |
| 627 | if isinstance(arguments, str): |
| 628 | arguments = [arguments] |
| 629 | test = self.compiler.has_multi_link_arguments if mode is _TestMode.LINKER else self.compiler.has_multi_arguments |
| 630 | result, cached = test(arguments, self.environment) |
| 631 | cached_msg = mlog.blue('(cached)') if cached else '' |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 632 | mlog.log( |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 633 | 'Compiler for', |
| 634 | self.compiler.get_display_language(), |
| 635 | 'supports{}'.format(' link' if mode is _TestMode.LINKER else ''), |
| 636 | 'arguments {}:'.format(' '.join(arguments)), |
| 637 | mlog.green('YES') if result else mlog.red('NO'), |
| 638 | cached_msg) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 639 | return result |
| 640 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 641 | @noKwargs |
| 642 | @typed_pos_args('compiler.has_argument', str) |
| 643 | def has_argument_method(self, args: T.Tuple[str], kwargs: 'TYPE_kwargs') -> bool: |
| 644 | return self._has_argument_impl([args[0]]) |
| 645 | |
| 646 | @noKwargs |
| 647 | @typed_pos_args('compiler.has_multi_arguments', varargs=str) |
Daniel Mensinger | c10e228 | 2021-08-21 16:28:39 +0200 | [diff] [blame] | 648 | @FeatureNew('compiler.has_multi_arguments', '0.37.0') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 649 | def has_multi_arguments_method(self, args: T.Tuple[T.List[str]], kwargs: 'TYPE_kwargs') -> bool: |
| 650 | return self._has_argument_impl(args[0]) |
| 651 | |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 652 | @FeatureNew('compiler.get_supported_arguments', '0.43.0') |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 653 | @typed_pos_args('compiler.get_supported_arguments', varargs=str) |
Laurin-Luis Lehning | 281f5ab | 2021-06-22 07:59:08 +0200 | [diff] [blame] | 654 | @typed_kwargs( |
| 655 | 'compiler.get_supported_arguments', |
| 656 | KwargInfo('checked', str, default='off', since='0.59.0', |
Dylan Baker | aa895b3 | 2021-08-23 14:07:57 -0700 | [diff] [blame] | 657 | validator=in_set_validator({'warn', 'require', 'off'})), |
Laurin-Luis Lehning | 281f5ab | 2021-06-22 07:59:08 +0200 | [diff] [blame] | 658 | ) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 659 | def get_supported_arguments_method(self, args: T.Tuple[T.List[str]], kwargs: 'GetSupportedArgumentKw') -> T.List[str]: |
| 660 | supported_args: T.List[str] = [] |
| 661 | checked = kwargs['checked'] |
Laurin-Luis Lehning | d5ed8f6 | 2021-06-18 01:42:57 +0200 | [diff] [blame] | 662 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 663 | for arg in args[0]: |
| 664 | if not self._has_argument_impl([arg]): |
Laurin-Luis Lehning | d5ed8f6 | 2021-06-18 01:42:57 +0200 | [diff] [blame] | 665 | msg = f'Compiler for {self.compiler.get_display_language()} does not support "{arg}"' |
| 666 | if checked == 'warn': |
| 667 | mlog.warning(msg) |
| 668 | elif checked == 'require': |
| 669 | raise mesonlib.MesonException(msg) |
| 670 | else: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 671 | supported_args.append(arg) |
| 672 | return supported_args |
| 673 | |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 674 | @noKwargs |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 675 | @typed_pos_args('compiler.first_supported_argument', varargs=str) |
| 676 | def first_supported_argument_method(self, args: T.Tuple[T.List[str]], kwargs: 'TYPE_kwargs') -> T.List[str]: |
| 677 | for arg in args[0]: |
| 678 | if self._has_argument_impl([arg]): |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 679 | mlog.log('First supported argument:', mlog.bold(arg)) |
| 680 | return [arg] |
| 681 | mlog.log('First supported argument:', mlog.red('None')) |
| 682 | return [] |
| 683 | |
| 684 | @FeatureNew('compiler.has_link_argument', '0.46.0') |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 685 | @noKwargs |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 686 | @typed_pos_args('compiler.has_link_argument', str) |
| 687 | def has_link_argument_method(self, args: T.Tuple[str], kwargs: 'TYPE_kwargs') -> bool: |
| 688 | return self._has_argument_impl([args[0]], mode=_TestMode.LINKER) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 689 | |
| 690 | @FeatureNew('compiler.has_multi_link_argument', '0.46.0') |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 691 | @noKwargs |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 692 | @typed_pos_args('compiler.has_multi_link_argument', varargs=str) |
| 693 | def has_multi_link_arguments_method(self, args: T.Tuple[T.List[str]], kwargs: 'TYPE_kwargs') -> bool: |
| 694 | return self._has_argument_impl(args[0], mode=_TestMode.LINKER) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 695 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 696 | @FeatureNew('compiler.get_supported_link_arguments', '0.46.0') |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 697 | @noKwargs |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 698 | @typed_pos_args('compiler.get_supported_link_arguments', varargs=str) |
| 699 | def get_supported_link_arguments_method(self, args: T.Tuple[T.List[str]], kwargs: 'TYPE_kwargs') -> T.List[str]: |
| 700 | supported_args: T.List[str] = [] |
| 701 | for arg in args[0]: |
| 702 | if self._has_argument_impl([arg], mode=_TestMode.LINKER): |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 703 | supported_args.append(arg) |
| 704 | return supported_args |
| 705 | |
| 706 | @FeatureNew('compiler.first_supported_link_argument_method', '0.46.0') |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 707 | @noKwargs |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 708 | @typed_pos_args('compiler.first_supported_link_argument', varargs=str) |
| 709 | def first_supported_link_argument_method(self, args: T.Tuple[T.List[str]], kwargs: 'TYPE_kwargs') -> T.List[str]: |
| 710 | for arg in args[0]: |
| 711 | if self._has_argument_impl([arg], mode=_TestMode.LINKER): |
| 712 | mlog.log('First supported link argument:', mlog.bold(arg)) |
| 713 | return [arg] |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 714 | mlog.log('First supported link argument:', mlog.red('None')) |
| 715 | return [] |
| 716 | |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 717 | def _has_function_attribute_impl(self, attr: str) -> bool: |
| 718 | """Common helper for function attribute testing.""" |
| 719 | result, cached = self.compiler.has_func_attribute(attr, self.environment) |
| 720 | cached_msg = mlog.blue('(cached)') if cached else '' |
| 721 | h = mlog.green('YES') if result else mlog.red('NO') |
Eli Schwartz | d06cc04 | 2021-07-08 00:06:10 -0400 | [diff] [blame] | 722 | mlog.log(f'Compiler for {self.compiler.get_display_language()} supports function attribute {attr}:', h, cached_msg) |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 723 | return result |
| 724 | |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 725 | @FeatureNew('compiler.has_function_attribute', '0.48.0') |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 726 | @noKwargs |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 727 | @typed_pos_args('compiler.has_function_attribute', str) |
| 728 | def has_func_attribute_method(self, args: T.Tuple[str], kwargs: 'TYPE_kwargs') -> bool: |
| 729 | return self._has_function_attribute_impl(args[0]) |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 730 | |
| 731 | @FeatureNew('compiler.get_supported_function_attributes', '0.48.0') |
Dylan Baker | 32d3b5c | 2021-07-22 09:21:57 -0700 | [diff] [blame] | 732 | @noKwargs |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 733 | @typed_pos_args('compiler.get_supported_function_attributes', varargs=str) |
| 734 | def get_supported_function_attributes_method(self, args: T.Tuple[T.List[str]], kwargs: 'TYPE_kwargs') -> T.List[str]: |
| 735 | return [a for a in args[0] if self._has_function_attribute_impl(a)] |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 736 | |
| 737 | @FeatureNew('compiler.get_argument_syntax_method', '0.49.0') |
| 738 | @noPosargs |
| 739 | @noKwargs |
Dylan Baker | b30dddd | 2021-07-26 14:16:31 -0700 | [diff] [blame] | 740 | def get_argument_syntax_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> str: |
Xavier Claessens | 558a7bc | 2021-04-01 08:18:44 -0400 | [diff] [blame] | 741 | return self.compiler.get_argument_syntax() |