1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
# SPDX-License-Identifier: Apache-2.0
# Copyright 2012-2017 The Meson development team
from __future__ import annotations
import os.path
import typing as T
from .. import mlog
from .. import mesonlib
from ..mesonlib import EnvironmentException, version_compare, LibType, OptionKey
from .compilers import CompileCheckMode, Compiler
from ..arglist import CompilerArgs
if T.TYPE_CHECKING:
from ..coredata import KeyedOptionDictType
from ..envconfig import MachineInfo
from ..environment import Environment
from ..mesonlib import MachineChoice
from ..dependencies import Dependency
class ValaCompiler(Compiler):
language = 'vala'
id = 'valac'
def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo'):
super().__init__([], exelist, version, for_machine, info, is_cross=is_cross)
self.version = version
self.base_options = {OptionKey('b_colorout')}
self.force_link = False
def needs_static_linker(self) -> bool:
return False # Because compiles into C.
def get_optimization_args(self, optimization_level: str) -> T.List[str]:
return []
def get_debug_args(self, is_debug: bool) -> T.List[str]:
return ['--debug'] if is_debug else []
def get_output_args(self, outputname: str) -> T.List[str]:
return [] # Because compiles into C.
def get_compile_only_args(self) -> T.List[str]:
return [] # Because compiles into C.
def get_compiler_args_for_mode(self, mode: CompileCheckMode) -> T.List[str]:
args: T.List[str] = []
if mode is CompileCheckMode.LINK and self.force_link:
return args
args += self.get_always_args()
if mode is CompileCheckMode.COMPILE:
args += self.get_compile_only_args()
elif mode is CompileCheckMode.PREPROCESS:
args += self.get_preprocess_only_args()
return args
def get_preprocess_only_args(self) -> T.List[str]:
return []
def get_pic_args(self) -> T.List[str]:
return []
def get_pie_args(self) -> T.List[str]:
return []
def get_pie_link_args(self) -> T.List[str]:
return []
def get_always_args(self) -> T.List[str]:
return ['-C']
def get_warn_args(self, level: str) -> T.List[str]:
return []
def get_werror_args(self) -> T.List[str]:
return ['--fatal-warnings']
def get_colorout_args(self, colortype: str) -> T.List[str]:
if version_compare(self.version, '>=0.37.1'):
return ['--color=' + colortype]
return []
def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str],
build_dir: str) -> T.List[str]:
for idx, i in enumerate(parameter_list):
if i[:9] == '--girdir=':
parameter_list[idx] = i[:9] + os.path.normpath(os.path.join(build_dir, i[9:]))
if i[:10] == '--vapidir=':
parameter_list[idx] = i[:10] + os.path.normpath(os.path.join(build_dir, i[10:]))
if i[:13] == '--includedir=':
parameter_list[idx] = i[:13] + os.path.normpath(os.path.join(build_dir, i[13:]))
if i[:14] == '--metadatadir=':
parameter_list[idx] = i[:14] + os.path.normpath(os.path.join(build_dir, i[14:]))
return parameter_list
def sanity_check(self, work_dir: str, environment: 'Environment') -> None:
code = 'class MesonSanityCheck : Object { }'
extra_flags: T.List[str] = []
extra_flags += environment.coredata.get_external_args(self.for_machine, self.language)
if self.is_cross:
extra_flags += self.get_compile_only_args()
else:
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
with self.cached_compile(code, environment.coredata, extra_args=extra_flags, mode=CompileCheckMode.COMPILE) as p:
if p.returncode != 0:
msg = f'Vala compiler {self.name_string()!r} cannot compile programs'
raise EnvironmentException(msg)
def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str],
libtype: LibType = LibType.PREFER_SHARED, lib_prefix_warning: bool = True) -> T.Optional[T.List[str]]:
if extra_dirs and isinstance(extra_dirs, str):
extra_dirs = [extra_dirs]
# Valac always looks in the default vapi dir, so only search there if
# no extra dirs are specified.
if not extra_dirs:
code = 'class MesonFindLibrary : Object { }'
args: T.List[str] = []
args += env.coredata.get_external_args(self.for_machine, self.language)
vapi_args = ['--pkg', libname]
args += vapi_args
with self.cached_compile(code, env.coredata, extra_args=args, mode=CompileCheckMode.COMPILE) as p:
if p.returncode == 0:
return vapi_args
# Not found? Try to find the vapi file itself.
for d in extra_dirs:
vapi = os.path.join(d, libname + '.vapi')
if os.path.isfile(vapi):
return [vapi]
mlog.debug(f'Searched {extra_dirs!r} and {libname!r} wasn\'t found')
return None
def thread_flags(self, env: 'Environment') -> T.List[str]:
return []
def thread_link_flags(self, env: 'Environment') -> T.List[str]:
return []
def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
def build_wrapper_args(self, env: 'Environment',
extra_args: T.Union[None, CompilerArgs, T.List[str], T.Callable[[CompileCheckMode], T.List[str]]],
dependencies: T.Optional[T.List['Dependency']],
mode: CompileCheckMode = CompileCheckMode.COMPILE) -> CompilerArgs:
if callable(extra_args):
extra_args = extra_args(mode)
if extra_args is None:
extra_args = []
if dependencies is None:
dependencies = []
# Collect compiler arguments
args = self.compiler_args(self.get_compiler_check_args(mode))
for d in dependencies:
# Add compile flags needed by dependencies
if mode is CompileCheckMode.LINK and self.force_link:
# As we are passing the parameter to valac we don't need the dependent libraries.
a = d.get_compile_args()
if a:
p = a[0]
n = p[max(p.rfind('/'), p.rfind('\\'))+1:]
if not n == d.get_name():
args += ['--pkg=' + d.get_name()] # This is used by gio-2.0 among others.
else:
args += ['--pkg=' + n]
else:
args += ['--Xcc=-l' + d.get_name()] # This is used by the maths library(-lm) among others.
else:
args += d.get_compile_args()
if mode is CompileCheckMode.LINK:
# Add link flags needed to find dependencies
if not self.force_link: # There are no need for link dependencies when linking with valac.
args += d.get_link_args()
if mode is CompileCheckMode.COMPILE:
# Add DFLAGS from the env
args += env.coredata.get_external_args(self.for_machine, self.language)
elif mode is CompileCheckMode.LINK:
# Add LDFLAGS from the env
args += env.coredata.get_external_link_args(self.for_machine, self.language)
# extra_args must override all other arguments, so we add them last
args += extra_args
return args
def links(self, code: 'mesonlib.FileOrString', env: 'Environment', *,
compiler: T.Optional['Compiler'] = None,
extra_args: T.Union[None, T.List[str], CompilerArgs, T.Callable[[CompileCheckMode], T.List[str]]] = None,
dependencies: T.Optional[T.List['Dependency']] = None,
disable_cache: bool = False) -> T.Tuple[bool, bool]:
self.force_link = True
if compiler:
with compiler._build_wrapper(code, env, dependencies=dependencies, want_output=True) as r:
objfile = mesonlib.File.from_absolute_file(r.output_name)
result = self.compiles(objfile, env, extra_args=extra_args,
dependencies=dependencies, mode=CompileCheckMode.LINK, disable_cache=True)
self.force_link = False
return result
result = self.compiles(code, env, extra_args=extra_args,
dependencies=dependencies, mode=CompileCheckMode.LINK, disable_cache=disable_cache)
self.force_link = False
return result
|