• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1""" CC Link ActionConfigs for ld.lld """
2
3load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
4load(
5    "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
6    "action_config",
7    "flag_group",
8    "flag_set",
9    "tool",
10    "variable_with_value",
11    "with_feature_set",
12)
13
14BAZEL_LINK_FLAG_SET = flag_set(
15    flag_groups = [
16        flag_group(
17            flags = ["%{linkstamp_paths}"],
18            iterate_over = "linkstamp_paths",
19            expand_if_available = "linkstamp_paths",
20        ),
21        flag_group(
22            iterate_over = "runtime_library_search_directories",
23            flag_groups = [
24                flag_group(
25                    flags = [
26                        "-Xlinker",
27                        "-rpath",
28                        "-Xlinker",
29                        "$ORIGIN/%{runtime_library_search_directories}",
30                    ],
31                ),
32            ],
33            expand_if_available =
34                "runtime_library_search_directories",
35        ),
36        flag_group(
37            flags = ["-L%{library_search_directories}"],
38            iterate_over = "library_search_directories",
39            expand_if_available = "library_search_directories",
40        ),
41        flag_group(
42            iterate_over = "libraries_to_link",
43            flag_groups = [
44                flag_group(
45                    flags = ["--start-lib"],
46                    expand_if_equal = variable_with_value(
47                        name = "libraries_to_link.type",
48                        value = "object_file_group",
49                    ),
50                ),
51                flag_group(
52                    flags = ["-whole-archive"],
53                    expand_if_true =
54                        "libraries_to_link.is_whole_archive",
55                ),
56                flag_group(
57                    flags = ["%{libraries_to_link.object_files}"],
58                    iterate_over = "libraries_to_link.object_files",
59                    expand_if_equal = variable_with_value(
60                        name = "libraries_to_link.type",
61                        value = "object_file_group",
62                    ),
63                ),
64                flag_group(
65                    flags = ["%{libraries_to_link.name}"],
66                    expand_if_equal = variable_with_value(
67                        name = "libraries_to_link.type",
68                        value = "object_file",
69                    ),
70                ),
71                flag_group(
72                    flags = ["%{libraries_to_link.name}"],
73                    expand_if_equal = variable_with_value(
74                        name = "libraries_to_link.type",
75                        value = "interface_library",
76                    ),
77                ),
78                flag_group(
79                    flags = ["%{libraries_to_link.name}"],
80                    expand_if_equal = variable_with_value(
81                        name = "libraries_to_link.type",
82                        value = "static_library",
83                    ),
84                ),
85                flag_group(
86                    flags = ["-l%{libraries_to_link.name}"],
87                    expand_if_equal = variable_with_value(
88                        name = "libraries_to_link.type",
89                        value = "dynamic_library",
90                    ),
91                ),
92                flag_group(
93                    flags = ["-l:%{libraries_to_link.name}"],
94                    expand_if_equal = variable_with_value(
95                        name = "libraries_to_link.type",
96                        value = "versioned_dynamic_library",
97                    ),
98                ),
99                flag_group(
100                    flags = ["-no-whole-archive"],
101                    expand_if_true = "libraries_to_link.is_whole_archive",
102                ),
103                flag_group(
104                    flags = ["--end-lib"],
105                    expand_if_equal = variable_with_value(
106                        name = "libraries_to_link.type",
107                        value = "object_file_group",
108                    ),
109                ),
110            ],
111            expand_if_available = "libraries_to_link",
112        ),
113        flag_group(
114            flags = ["@%{thinlto_param_file}"],
115            expand_if_true = "thinlto_param_file",
116        ),
117        flag_group(
118            flags = ["%{user_link_flags}"],
119            iterate_over = "user_link_flags",
120            expand_if_available = "user_link_flags",
121        ),
122        flag_group(
123            flags = ["-o", "%{output_execpath}"],
124            expand_if_available = "output_execpath",
125        ),
126    ],
127)
128
129def link_action_configs(
130        llvm,
131        builtin_library_directories,
132        builtin_libraries,
133        builtin_framework_directories,
134        builtin_frameworks,
135        builtin_executable_objects,
136        link_flags,
137        dbg_link_flags,
138        fastbuild_link_flags,
139        opt_link_flags):
140    """
141    Generates CC Link ActionConfigs
142
143    Args:
144        llvm (string): Path to LLVM binaries.
145        builtin_library_directories (List): List of library directories to always be passed to the linker.
146        builtin_libraries (List): List of libraries to always be passed to the linker.
147        builtin_framework_directories (List): List of Apple framework directories to always be passed to the linker.
148        builtin_frameworks (List): List of Apple frameworks to always be passed to the linker.
149        builtin_executable_objects (List): List of object files to always be passed to the linker.
150        link_flags (List): List of flags to always be passed to the linker.
151        dbg_link_flags (List): List of additional flags to always be passed to the linker in dbg configuration.
152        fastbuild_link_flags (List): List of additional flags to always be passed to the linker in fastbuild configuration.
153        opt_link_flags (List): List of additional flags to always be passed to the linker in opt configuration.
154
155    Returns:
156        List of CC Link ActionConfigs
157    """
158
159    builtin_library_directory_link_flags = []
160    for builtin_library_directory in builtin_library_directories:
161        builtin_library_directory_link_flags.append("-L")
162        builtin_library_directory_link_flags.append(builtin_library_directory)
163
164    builtin_library_link_flags = []
165    for builtin_library in builtin_libraries:
166        builtin_library_link_flags.append("-l{}".format(builtin_library))
167
168    if builtin_framework_directories:
169        fail("Frameworks not supported by `ld.lld`")
170
171    if builtin_frameworks:
172        fail("Frameworks not supported by `ld.lld`")
173
174    builtin_executable_objects_link_flags = []
175    for builtin_executable_object in builtin_executable_objects:
176        builtin_executable_objects_link_flags.append("-l{}".format(builtin_executable_object))
177
178    required_link_flags = (["-nostdlib"] +
179                           builtin_library_directory_link_flags +
180                           builtin_library_link_flags)
181    required_link_flag_set = flag_set(
182        flag_groups = ([
183            flag_group(flags = required_link_flags),
184        ] if required_link_flags else []),
185    )
186
187    required_executable_link_flags = (builtin_executable_objects_link_flags)
188    required_executable_link_flag_set = flag_set(
189        flag_groups = ([
190            flag_group(flags = required_executable_link_flags),
191        ] if required_executable_link_flags else []),
192    )
193
194    link_flag_set = flag_set(
195        flag_groups = ([
196            flag_group(flags = link_flags),
197        ] if link_flags else []),
198    )
199
200    dbg_link_flag_set = flag_set(
201        flag_groups = ([
202            flag_group(flags = dbg_link_flags),
203        ] if dbg_link_flags else []),
204        with_features = [with_feature_set(features = ["dbg"])],
205    )
206
207    fastbuild_link_flag_set = flag_set(
208        flag_groups = ([
209            flag_group(flags = fastbuild_link_flags),
210        ] if fastbuild_link_flags else []),
211        with_features = [with_feature_set(features = ["fastbuild"])],
212    )
213
214    opt_link_flag_set = flag_set(
215        flag_groups = ([
216            flag_group(flags = opt_link_flags),
217        ] if opt_link_flags else []),
218        with_features = [with_feature_set(features = ["opt"])],
219    )
220
221    return [
222        action_config(
223            action_name = ACTION_NAMES.cpp_link_dynamic_library,
224            tools = [tool(path = "{}/bin/ld.lld".format(llvm))],
225            flag_sets = [
226                # Mandatory, no link flags come through on command line.
227                flag_set(
228                    flag_groups = [
229                        flag_group(
230                            flags = ["@%{linker_param_file}"],
231                            expand_if_available = "linker_param_file",
232                        ),
233                    ],
234                ),
235                required_link_flag_set,
236                link_flag_set,
237                dbg_link_flag_set,
238                fastbuild_link_flag_set,
239                opt_link_flag_set,
240                BAZEL_LINK_FLAG_SET,
241                flag_set(
242                    flag_groups = [
243                        flag_group(
244                            flags = ["-shared"],
245                        ),
246                    ],
247                ),
248            ],
249        ),
250        action_config(
251            action_name = ACTION_NAMES.cpp_link_nodeps_dynamic_library,
252            tools = [tool(path = "{}/bin/ld.lld".format(llvm))],
253            flag_sets = [
254                # Mandatory, no link flags come through on command line.
255                flag_set(
256                    flag_groups = [
257                        flag_group(
258                            flags = ["@%{linker_param_file}"],
259                            expand_if_available = "linker_param_file",
260                        ),
261                    ],
262                ),
263                required_link_flag_set,
264                link_flag_set,
265                dbg_link_flag_set,
266                fastbuild_link_flag_set,
267                opt_link_flag_set,
268                BAZEL_LINK_FLAG_SET,
269                flag_set(
270                    flag_groups = [
271                        flag_group(
272                            flags = ["-shared"],
273                        ),
274                    ],
275                ),
276            ],
277        ),
278        action_config(
279            action_name = ACTION_NAMES.cpp_link_executable,
280            tools = [tool(path = "{}/bin/ld.lld".format(llvm))],
281            flag_sets = [
282                # Mandatory, no link flags come through on command line.
283                flag_set(
284                    flag_groups = [
285                        flag_group(
286                            flags = ["@%{linker_param_file}"],
287                            expand_if_available = "linker_param_file",
288                        ),
289                    ],
290                ),
291                required_link_flag_set,
292                required_executable_link_flag_set,
293                link_flag_set,
294                dbg_link_flag_set,
295                fastbuild_link_flag_set,
296                opt_link_flag_set,
297                BAZEL_LINK_FLAG_SET,
298                flag_set(
299                    flag_groups = [
300                        flag_group(
301                            flags = ["-pie"],
302                        ),
303                    ],
304                ),
305            ],
306        ),
307    ]
308