1# Copyright 2012-2017 The 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 15import subprocess, os.path 16import typing as T 17 18from ..mesonlib import EnvironmentException, MachineChoice 19 20from .compilers import Compiler, swift_buildtype_args, clike_debug_args 21 22if T.TYPE_CHECKING: 23 from ..envconfig import MachineInfo 24 from ..environment import Environment 25 from ..linkers import DynamicLinker 26 27swift_optimization_args = { 28 '0': [], 29 'g': [], 30 '1': ['-O'], 31 '2': ['-O'], 32 '3': ['-O'], 33 's': ['-O'], 34} # type: T.Dict[str, T.List[str]] 35 36class SwiftCompiler(Compiler): 37 38 LINKER_PREFIX = ['-Xlinker'] 39 language = 'swift' 40 41 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, 42 is_cross: bool, info: 'MachineInfo', full_version: T.Optional[str] = None, 43 linker: T.Optional['DynamicLinker'] = None): 44 super().__init__(exelist, version, for_machine, info, 45 is_cross=is_cross, full_version=full_version, 46 linker=linker) 47 self.version = version 48 self.id = 'llvm' 49 50 def needs_static_linker(self) -> bool: 51 return True 52 53 def get_werror_args(self) -> T.List[str]: 54 return ['--fatal-warnings'] 55 56 def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: 57 return ['-emit-dependencies'] 58 59 def depfile_for_object(self, objfile: str) -> str: 60 return os.path.splitext(objfile)[0] + '.' + self.get_depfile_suffix() 61 62 def get_depfile_suffix(self) -> str: 63 return 'd' 64 65 def get_output_args(self, target: str) -> T.List[str]: 66 return ['-o', target] 67 68 def get_header_import_args(self, headername: str) -> T.List[str]: 69 return ['-import-objc-header', headername] 70 71 def get_warn_args(self, level: str) -> T.List[str]: 72 return [] 73 74 def get_buildtype_args(self, buildtype: str) -> T.List[str]: 75 return swift_buildtype_args[buildtype] 76 77 def get_std_exe_link_args(self) -> T.List[str]: 78 return ['-emit-executable'] 79 80 def get_module_args(self, modname: str) -> T.List[str]: 81 return ['-module-name', modname] 82 83 def get_mod_gen_args(self) -> T.List[str]: 84 return ['-emit-module'] 85 86 def get_include_args(self, path: str, is_system: bool) -> T.List[str]: 87 return ['-I' + path] 88 89 def get_compile_only_args(self) -> T.List[str]: 90 return ['-c'] 91 92 def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], 93 build_dir: str) -> T.List[str]: 94 for idx, i in enumerate(parameter_list): 95 if i[:2] == '-I' or i[:2] == '-L': 96 parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) 97 98 return parameter_list 99 100 def sanity_check(self, work_dir: str, environment: 'Environment') -> None: 101 src = 'swifttest.swift' 102 source_name = os.path.join(work_dir, src) 103 output_name = os.path.join(work_dir, 'swifttest') 104 extra_flags: T.List[str] = [] 105 extra_flags += environment.coredata.get_external_args(self.for_machine, self.language) 106 if self.is_cross: 107 extra_flags += self.get_compile_only_args() 108 else: 109 extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language) 110 with open(source_name, 'w', encoding='utf-8') as ofile: 111 ofile.write('''print("Swift compilation is working.") 112''') 113 pc = subprocess.Popen(self.exelist + extra_flags + ['-emit-executable', '-o', output_name, src], cwd=work_dir) 114 pc.wait() 115 if pc.returncode != 0: 116 raise EnvironmentException('Swift compiler %s can not compile programs.' % self.name_string()) 117 if self.is_cross: 118 # Can't check if the binaries run so we have to assume they do 119 return 120 if subprocess.call(output_name) != 0: 121 raise EnvironmentException('Executables created by Swift compiler %s are not runnable.' % self.name_string()) 122 123 def get_debug_args(self, is_debug: bool) -> T.List[str]: 124 return clike_debug_args[is_debug] 125 126 def get_optimization_args(self, optimization_level: str) -> T.List[str]: 127 return swift_optimization_args[optimization_level] 128