• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2023 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://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, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14
15load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
16load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
17load("@rules_cc//cc/toolchains:args.bzl", "cc_args")
18load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature")
19load("@rules_cc//cc/toolchains:feature_constraint.bzl", "cc_feature_constraint")
20load("@rules_cc//cc/toolchains:feature_set.bzl", "cc_feature_set")
21load("@rules_cc//cc/toolchains:toolchain.bzl", "cc_toolchain")
22load("//pw_toolchain/cc:builtin_module_map.bzl", "builtin_module_map")
23load("//pw_toolchain/host_clang:paths.bzl", "LLVM_TOOLCHAIN")
24
25package(default_visibility = ["//visibility:public"])
26
27licenses(["notice"])
28
29filegroup(name = "empty")
30
31cc_args(
32    name = "link_with_lld",
33    actions = ["@rules_cc//cc/toolchains/actions:link_actions"],
34    args = ["-fuse-ld=lld"],
35)
36
37cc_args(
38    name = "macos_link_libs",
39    actions = ["@rules_cc//cc/toolchains/actions:link_actions"],
40    args = [
41        # Force dropping the system libc++.
42        "-nostdlib++",
43        # Use libc++ provided by the toolchain.
44        LLVM_TOOLCHAIN + "/lib/libc++.a",
45    ],
46    target_compatible_with = ["@platforms//os:macos"],
47)
48
49cc_args(
50    name = "linux_link_libs",
51    actions = ["@rules_cc//cc/toolchains/actions:link_actions"],
52    args = [
53        "-pthread",
54        "-stdlib=libc++",
55        "--rtlib=compiler-rt",
56        "--unwindlib=libunwind",
57    ],
58    target_compatible_with = ["@platforms//os:linux"],
59)
60
61cc_args(
62    name = "libtool_darwin_flags",
63    actions = ["@rules_cc//cc/toolchains/actions:cpp_link_static_library"],
64    args = ["-no_warning_for_no_symbols"],
65)
66
67# Thread safety warnings are only supported by Clang.
68cc_args(
69    name = "thread_safety_warnings",
70    actions = [
71        "@rules_cc//cc/toolchains/actions:c_compile_actions",
72        "@rules_cc//cc/toolchains/actions:cpp_compile_actions",
73    ],
74    args = [
75        "-Wthread-safety",
76        "-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1",
77    ],
78)
79
80cc_args(
81    name = "verbose_compiler_flags",
82    actions = [
83        "@rules_cc//cc/toolchains/actions:compile_actions",
84        "@rules_cc//cc/toolchains/actions:link_actions",
85    ],
86    args = ["-v"],
87)
88
89# A feature that can be easily toggled to include extra compiler output to help
90# debug things like include search path ordering and showing all the flags
91# passed to the compiler.
92#
93# Add `--features=verbose_compiler_output` to your Bazel invocation to enable.
94cc_feature(
95    name = "verbose_compiler_output",
96    args = [":verbose_compiler_flags"],
97    feature_name = "verbose_compiler_output",
98)
99
100cc_args(
101    name = "no_unknown_warning_option",
102    actions = [
103        "@rules_cc//cc/toolchains/actions:c_compile_actions",
104        "@rules_cc//cc/toolchains/actions:cpp_compile_actions",
105    ],
106    args = [
107        "-Wno-unknown-warning-option",
108    ],
109)
110
111bool_flag(
112    name = "asan",
113    build_setting_default = False,
114)
115
116config_setting(
117    name = "asan_enabled",
118    flag_values = {
119        ":asan": "true",
120    },
121)
122
123cc_feature(
124    name = "asan_feature",
125    args = ["//pw_toolchain/cc/args:asan"],
126    feature_name = "asan",
127    requires_any_of = [":asan_constraint"],
128)
129
130cc_feature_set(
131    name = "asan_constraint",
132    # Rust uses the C++ linker, but not the C++ compiler, so we need to ensure
133    # -fsanitize=address is not be specified during Rust linking.
134    all_of = [":rules_rust_unsupported_feature"],
135)
136
137bool_flag(
138    name = "ubsan",
139    build_setting_default = False,
140)
141
142config_setting(
143    name = "ubsan_enabled",
144    flag_values = {
145        ":ubsan": "true",
146    },
147)
148
149cc_feature(
150    name = "ubsan_feature",
151    args = ["//pw_toolchain/cc/args:ubsan"],
152    feature_name = "ubsan",
153    requires_any_of = [":ubsan_constraint"],
154)
155
156cc_feature_set(
157    name = "ubsan_constraint",
158    # Rust uses the C++ linker, but not the C++ compiler, so we need to ensure
159    # -fsanitize=undefined is not be specified during Rust linking.
160    all_of = [":rules_rust_unsupported_feature"],
161)
162
163bool_flag(
164    name = "tsan",
165    build_setting_default = False,
166)
167
168config_setting(
169    name = "tsan_enabled",
170    flag_values = {
171        ":tsan": "true",
172    },
173)
174
175cc_feature(
176    name = "tsan_feature",
177    args = ["//pw_toolchain/cc/args:tsan"],
178    feature_name = "tsan",
179    requires_any_of = [":tsan_constraint"],
180)
181
182cc_feature_set(
183    name = "tsan_constraint",
184    # Rust uses the C++ linker, but not the C++ compiler, so we need to ensure
185    # -fsanitize=undefined is not be specified during Rust linking.
186    all_of = [":rules_rust_unsupported_feature"],
187)
188
189bool_flag(
190    name = "fuzztest",
191    build_setting_default = False,
192)
193
194config_setting(
195    name = "fuzztest_enabled",
196    flag_values = {
197        ":fuzztest": "true",
198    },
199)
200
201cc_feature(
202    name = "fuzztest_feature",
203    args = ["//pw_toolchain/cc/args:fuzztest"],
204    feature_name = "fuzztest",
205)
206
207# This is a sentinel feature defined by rules_rust. It is by definition
208# unsupported: rules_rust will disable this feature when linking Rust code.
209cc_feature(
210    name = "rules_rust_unsupported_feature",
211    feature_name = "rules_rust_unsupported_feature",
212)
213
214# This is a sentinel feature defined by rules_go. It is by definition
215# unsupported: rules_go will disable this feature when linking Go code.
216cc_feature(
217    name = "rules_go_unsupported_feature",
218    feature_name = "rules_go_unsupported_feature",
219)
220
221cc_feature_constraint(
222    name = "rules_go_constraint",
223
224    # This constraint is saying "not not Golang" (yes Golang / only Golang).
225    none_of = [":rules_go_unsupported_feature"],
226)
227
228# Golang doesn't link with PIE enabled. See pwbug.dev/347708308.
229#
230# We want to disable PIE only when we're *not* compiling Golang code.
231cc_args(
232    name = "no_pie_for_go_flags",
233    actions = ["@rules_cc//cc/toolchains/actions:link_actions"],
234    args = [
235        "-no-pie",
236    ],
237    requires_any_of = [":rules_go_constraint"],
238    target_compatible_with = ["@platforms//os:linux"],
239)
240
241cc_args(
242    name = "silence_cgo_warnings",
243    actions = [
244        "@rules_cc//cc/toolchains/actions:compile_actions",
245        "@rules_cc//cc/toolchains/actions:link_actions",
246    ],
247    args = ["-Wno-unused-parameter"],
248    requires_any_of = [":rules_go_constraint"],
249)
250
251cc_feature(
252    name = "supports_pic",
253    feature_name = "supports_pic",
254)
255
256# Symlink to clangd, for user convenience.
257copy_file(
258    name = "copy_clangd",
259    src = select({
260        "@platforms//os:macos": "@llvm_toolchain_macos//:bin/clangd",
261        "//conditions:default": "@llvm_toolchain//:bin/clangd",
262    }),
263    out = "clangd",
264    allow_symlink = True,
265)
266
267# Symlink to clang-tidy, for user convenience.
268copy_file(
269    name = "copy_clang_tidy",
270    src = select({
271        "@platforms//os:macos": "@llvm_toolchain_macos//:clang-tidy",
272        "//conditions:default": "@llvm_toolchain//:clang-tidy",
273    }),
274    out = "clang-tidy",
275    allow_symlink = True,
276    is_executable = True,
277)
278
279cc_feature(
280    name = "use_module_maps",
281    args = ["//pw_toolchain/cc/args:dependent_module_map_files"],
282    feature_name = "use_module_maps",
283    requires_any_of = [":module_maps"],
284)
285
286cc_feature(
287    name = "module_maps",
288    feature_name = "module_maps",
289)
290
291cc_feature(
292    name = "layering_check_feature",
293    args = [
294        "//pw_toolchain/cc/args:layering_check",
295        "//pw_toolchain/cc/args:module_name",
296        "//pw_toolchain/cc/args:module_map_file",
297    ],
298    feature_name = "layering_check",
299    implies = [":use_module_maps"],
300)
301
302bool_flag(
303    name = "layering_check",
304    build_setting_default = False,
305)
306
307config_setting(
308    name = "layering_check_enabled",
309    flag_values = {":layering_check": "True"},
310)
311
312builtin_module_map(
313    name = "builtin_module_map",
314    include_directories = select({
315        "@platforms//os:linux": [
316            "@llvm_toolchain//:include-x86_64-unknown-linux-gnu-c++-v1",
317            "@llvm_toolchain//:include-c++-v1",
318            "@llvm_toolchain//:lib-clang-include",
319            "@linux_sysroot//:usr-include-x86_64-linux-gnu",
320            "@linux_sysroot//:usr-include-arm-linux-gnueabihf",
321            "@linux_sysroot//:usr-include",
322        ],
323        "@platforms//os:macos": [
324            "@llvm_toolchain_macos//:include-x86_64-unknown-linux-gnu-c++-v1",
325            "@llvm_toolchain_macos//:include-c++-v1",
326            "@llvm_toolchain_macos//:lib-clang-include",
327            "@macos_sysroot//:usr-include",
328            "@macos_sysroot//:CoreFoundation.framework-Headers",
329            "@macos_sysroot//:IOKit.framework-Headers",
330            "@macos_sysroot//:Security.framework-Headers",
331        ],
332        "//conditions:default": [],
333    }),
334)
335
336alias(
337    name = "sysroot_root",
338    actual = select({
339        "@platforms//os:linux": "@linux_sysroot//:sysroot",
340        "@platforms//os:macos": "@macos_sysroot//:sysroot",
341        "//conditions:default": "//pw_build:empty_cc_library",
342    }),
343)
344
345cc_toolchain(
346    name = "host_toolchain",
347    args = select({
348        "@platforms//os:linux": [
349            ":linux_link_libs",
350            ":no_pie_for_go_flags",
351            "@linux_sysroot//:sysroot",
352        ],
353        "@platforms//os:macos": [
354            ":macos_link_libs",
355            ":libtool_darwin_flags",
356            "@macos_sysroot//:sysroot",
357        ],
358        "//conditions:default": [],
359    }) + [
360        ":thread_safety_warnings",
361        ":link_with_lld",
362        "//pw_toolchain/cc/args:debugging",
363        "//pw_toolchain/cc/args:reduced_size",
364        "//pw_toolchain/cc/args:no_canonical_prefixes",
365        "//pw_toolchain/cc/args:no_rtti",
366        "//pw_toolchain/cc/args:wno_register",
367        "//pw_toolchain/cc/args:wnon_virtual_dtor",
368        "//pw_toolchain/cc/args:common_warnings",
369        "//pw_toolchain/cc/args:color_diagnostics",
370        # Must go after the general warnings that are enabled.
371        ":silence_cgo_warnings",
372    ] + select({
373        "//pw_build:kythe": [":no_unknown_warning_option"],
374        "//conditions:default": [],
375    }),
376    enabled_features = [
377        "@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features",
378        ":supports_pic",
379        ":module_maps",
380        ":rules_go_unsupported_feature",
381        ":rules_rust_unsupported_feature",
382        "//pw_toolchain/cc/capability:compiler_is_clang",
383        "//pw_toolchain/cc/capability:linker_is_clang",
384    ] + select({
385        ":asan_enabled": [":asan_feature"],
386        "//conditions:default": [],
387    }) + select({
388        ":ubsan_enabled": [":ubsan_feature"],
389        "//conditions:default": [],
390    }) + select({
391        ":tsan_enabled": [":tsan_feature"],
392        "//conditions:default": [],
393    }) + select({
394        "//pw_toolchain/cc:c++17_enabled": ["//pw_toolchain/cc/args:c++17_feature"],
395        "//conditions:default": [],
396    }) + select({
397        "//pw_toolchain/cc:c++20_enabled": ["//pw_toolchain/cc/args:c++20_feature"],
398        "//conditions:default": [],
399    }) + select({
400        ":fuzztest_enabled": [":fuzztest_feature"],
401        "//conditions:default": [],
402    }),
403    known_features = [
404        "@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features",
405        ":layering_check_feature",
406        ":module_maps",
407        ":use_module_maps",
408        ":asan_feature",
409        ":ubsan_feature",
410        ":tsan_feature",
411        ":verbose_compiler_output",
412        ":rules_rust_unsupported_feature",
413        ":supports_pic",
414        "//pw_toolchain/cc/args:c++17_feature",
415        "//pw_toolchain/cc/args:c++20_feature",
416        "//pw_toolchain/cc/capability:compiler_is_clang",
417        "//pw_toolchain/cc/capability:linker_is_clang",
418    ],
419    # TODO: https://pwbug.dev/219091175 - Remove this select (always set this to
420    # builtin_module_map) once all Pigweed downstream projects are on Bazel 8.
421    module_map = select({
422        ":layering_check_enabled": ":builtin_module_map",
423        "//conditions:default": None,
424    }),
425    tool_map = select({
426        "@platforms//os:macos": "@llvm_toolchain_macos//:all_tools",
427        "//conditions:default": "@llvm_toolchain//:all_tools",
428    }),
429)
430
431toolchain(
432    name = "host_cc_toolchain_linux",
433    exec_compatible_with = [
434        "@platforms//os:linux",
435    ],
436    target_compatible_with = [
437        "@platforms//os:linux",
438    ],
439    toolchain = ":host_toolchain",
440    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
441)
442
443toolchain(
444    name = "host_cc_toolchain_macos",
445    exec_compatible_with = [
446        "@platforms//os:macos",
447    ],
448    target_compatible_with = [
449        "@platforms//os:macos",
450    ],
451    toolchain = ":host_toolchain",
452    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
453)
454