1# Copyright 2019 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
15"""Mixins for compilers that *are* linkers.
16
17While many compilers (such as gcc and clang) are used by meson to dispatch
18linker commands and other (like MSVC) are not, a few (such as DMD) actually
19are both the linker and compiler in one binary. This module provides mixin
20classes for those cases.
21"""
22
23import typing as T
24
25from ...mesonlib import EnvironmentException, MesonException, is_windows
26
27if T.TYPE_CHECKING:
28    from ...coredata import KeyedOptionDictType
29    from ...environment import Environment
30    from ...compilers.compilers import Compiler
31else:
32    # This is a bit clever, for mypy we pretend that these mixins descend from
33    # Compiler, so we get all of the methods and attributes defined for us, but
34    # for runtime we make them descend from object (which all classes normally
35    # do). This gives up DRYer type checking, with no runtime impact
36    Compiler = object
37
38
39class BasicLinkerIsCompilerMixin(Compiler):
40
41    """Provides a baseline of methods that a linker would implement.
42
43    In every case this provides a "no" or "empty" answer. If a compiler
44    implements any of these it needs a different mixin or to override that
45    functionality itself.
46    """
47
48    def sanitizer_link_args(self, value: str) -> T.List[str]:
49        return []
50
51    def get_lto_link_args(self, *, threads: int = 0, mode: str = 'default') -> T.List[str]:
52        return []
53
54    def can_linker_accept_rsp(self) -> bool:
55        return is_windows()
56
57    def get_linker_exelist(self) -> T.List[str]:
58        return self.exelist.copy()
59
60    def get_linker_output_args(self, output: str) -> T.List[str]:
61        return []
62
63    def get_linker_always_args(self) -> T.List[str]:
64        return []
65
66    def get_linker_lib_prefix(self) -> str:
67        return ''
68
69    def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
70        return []
71
72    def has_multi_link_args(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
73        return False, False
74
75    def get_link_debugfile_args(self, targetfile: str) -> T.List[str]:
76        return []
77
78    def get_std_shared_lib_link_args(self) -> T.List[str]:
79        return []
80
81    def get_std_shared_module_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
82        return self.get_std_shared_lib_link_args()
83
84    def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
85        raise EnvironmentException(f'Linker {self.id} does not support link_whole')
86
87    def get_allow_undefined_link_args(self) -> T.List[str]:
88        raise EnvironmentException(f'Linker {self.id} does not support allow undefined')
89
90    def get_pie_link_args(self) -> T.List[str]:
91        raise EnvironmentException(f'Linker {self.id} does not support position-independent executable')
92
93    def get_undefined_link_args(self) -> T.List[str]:
94        return []
95
96    def get_coverage_link_args(self) -> T.List[str]:
97        return []
98
99    def no_undefined_link_args(self) -> T.List[str]:
100        return []
101
102    def bitcode_args(self) -> T.List[str]:
103        raise MesonException("This linker doesn't support bitcode bundles")
104
105    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
106                        suffix: str, soversion: str,
107                        darwin_versions: T.Tuple[str, str]) -> T.List[str]:
108        raise MesonException("This linker doesn't support soname args")
109
110    def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
111                         rpath_paths: str, build_rpath: str,
112                         install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
113        return ([], set())
114
115    def get_asneeded_args(self) -> T.List[str]:
116        return []
117
118    def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]:
119        return []
120
121    def get_link_debugfile_name(self, target: str) -> str:
122        return ''
123
124    def thread_flags(self, env: 'Environment') -> T.List[str]:
125        return []
126
127    def thread_link_flags(self, env: 'Environment') -> T.List[str]:
128        return []
129