clang_cc_toolchain_config.bzl 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  1. # Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. # Exceptions. See /LICENSE for license information.
  3. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. """A Starlark cc_toolchain configuration rule"""
  5. load(
  6. "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
  7. "action_config",
  8. "feature",
  9. "feature_set",
  10. "flag_group",
  11. "flag_set",
  12. "tool",
  13. "tool_path",
  14. "variable_with_value",
  15. "with_feature_set",
  16. )
  17. load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
  18. load(
  19. ":clang_detected_variables.bzl",
  20. "clang_include_dirs_list",
  21. "clang_resource_dir",
  22. "llvm_bindir",
  23. "sysroot_dir",
  24. )
  25. all_c_compile_actions = [
  26. ACTION_NAMES.c_compile,
  27. ACTION_NAMES.assemble,
  28. ACTION_NAMES.preprocess_assemble,
  29. ]
  30. all_cpp_compile_actions = [
  31. ACTION_NAMES.cpp_compile,
  32. ACTION_NAMES.linkstamp_compile,
  33. ACTION_NAMES.cpp_header_parsing,
  34. ACTION_NAMES.cpp_module_compile,
  35. ACTION_NAMES.cpp_module_codegen,
  36. ]
  37. all_compile_actions = all_c_compile_actions + all_cpp_compile_actions
  38. preprocessor_compile_actions = [
  39. ACTION_NAMES.c_compile,
  40. ACTION_NAMES.cpp_compile,
  41. ACTION_NAMES.linkstamp_compile,
  42. ACTION_NAMES.preprocess_assemble,
  43. ACTION_NAMES.cpp_header_parsing,
  44. ACTION_NAMES.cpp_module_compile,
  45. ]
  46. codegen_compile_actions = [
  47. ACTION_NAMES.c_compile,
  48. ACTION_NAMES.cpp_compile,
  49. ACTION_NAMES.linkstamp_compile,
  50. ACTION_NAMES.assemble,
  51. ACTION_NAMES.preprocess_assemble,
  52. ACTION_NAMES.cpp_module_codegen,
  53. ]
  54. all_link_actions = [
  55. ACTION_NAMES.cpp_link_executable,
  56. ACTION_NAMES.cpp_link_dynamic_library,
  57. ACTION_NAMES.cpp_link_nodeps_dynamic_library,
  58. ]
  59. def _impl(ctx):
  60. tool_paths = [
  61. tool_path(name = "ar", path = llvm_bindir + "/llvm-ar"),
  62. tool_path(name = "ld", path = llvm_bindir + "/ld.lld"),
  63. tool_path(name = "cpp", path = llvm_bindir + "/clang-cpp"),
  64. tool_path(name = "gcc", path = llvm_bindir + "/clang++"),
  65. tool_path(name = "dwp", path = llvm_bindir + "/llvm-dwp"),
  66. tool_path(name = "gcov", path = llvm_bindir + "/llvm-cov"),
  67. tool_path(name = "nm", path = llvm_bindir + "/llvm-nm"),
  68. tool_path(name = "objcopy", path = llvm_bindir + "/llvm-objcopy"),
  69. tool_path(name = "objdump", path = llvm_bindir + "/llvm-objdump"),
  70. tool_path(name = "strip", path = llvm_bindir + "/llvm-strip"),
  71. ]
  72. action_configs = [
  73. action_config(action_name = name, enabled = True, tools = [tool(path = llvm_bindir + "/clang")])
  74. for name in all_c_compile_actions
  75. ] + [
  76. action_config(action_name = name, enabled = True, tools = [tool(path = llvm_bindir + "/clang++")])
  77. for name in all_cpp_compile_actions
  78. ] + [
  79. action_config(action_name = name, enabled = True, tools = [tool(path = llvm_bindir + "/clang++")])
  80. for name in all_link_actions
  81. ] + [
  82. action_config(action_name = name, enabled = True, tools = [tool(path = llvm_bindir + "/llvm-ar")])
  83. for name in [ACTION_NAMES.cpp_link_static_library]
  84. ] + [
  85. action_config(action_name = name, enabled = True, tools = [tool(path = llvm_bindir + "/llvm-strip")])
  86. for name in [ACTION_NAMES.strip]
  87. ]
  88. default_flags_feature = feature(
  89. name = "default_flags",
  90. enabled = True,
  91. flag_sets = [
  92. flag_set(
  93. actions = all_compile_actions + all_link_actions,
  94. flag_groups = ([
  95. flag_group(
  96. flags = [
  97. "-no-canonical-prefixes",
  98. "-fcolor-diagnostics",
  99. ],
  100. ),
  101. ]),
  102. ),
  103. flag_set(
  104. actions = all_compile_actions,
  105. flag_groups = ([
  106. flag_group(
  107. flags = [
  108. "-Werror",
  109. "-Wall",
  110. "-Wextra",
  111. "-Wthread-safety",
  112. "-Wself-assign",
  113. "-Wimplicit-fallthrough",
  114. "-Wctad-maybe-unsupported",
  115. # Unfortunately, LLVM isn't clean for this warning.
  116. "-Wno-unused-parameter",
  117. # Compile actions shouldn't link anything.
  118. "-c",
  119. ],
  120. ),
  121. flag_group(
  122. expand_if_available = "output_assembly_file",
  123. flags = ["-S"],
  124. ),
  125. flag_group(
  126. expand_if_available = "output_preprocess_file",
  127. flags = ["-E"],
  128. ),
  129. flag_group(
  130. flags = ["-MD", "-MF", "%{dependency_file}"],
  131. expand_if_available = "dependency_file",
  132. ),
  133. flag_group(
  134. flags = ["-frandom-seed=%{output_file}"],
  135. expand_if_available = "output_file",
  136. ),
  137. ]),
  138. ),
  139. flag_set(
  140. actions = all_cpp_compile_actions + all_link_actions,
  141. flag_groups = ([
  142. flag_group(
  143. flags = [
  144. "-std=c++17",
  145. "-stdlib=libc++",
  146. ],
  147. ),
  148. ]),
  149. ),
  150. flag_set(
  151. actions = codegen_compile_actions,
  152. flag_groups = ([
  153. flag_group(
  154. flags = [
  155. "-ffunction-sections",
  156. "-fdata-sections",
  157. ],
  158. ),
  159. ]),
  160. ),
  161. flag_set(
  162. actions = codegen_compile_actions,
  163. flag_groups = [
  164. flag_group(flags = ["-fPIC"], expand_if_available = "pic"),
  165. ],
  166. ),
  167. flag_set(
  168. actions = preprocessor_compile_actions,
  169. flag_groups = [
  170. flag_group(
  171. flags = [
  172. # Disable a warning and override builtin macros to
  173. # ensure a hermetic build.
  174. "-Wno-builtin-macro-redefined",
  175. "-D__DATE__=\"redacted\"",
  176. "-D__TIMESTAMP__=\"redacted\"",
  177. "-D__TIME__=\"redacted\"",
  178. ],
  179. ),
  180. flag_group(
  181. flags = ["-D%{preprocessor_defines}"],
  182. iterate_over = "preprocessor_defines",
  183. ),
  184. flag_group(
  185. flags = ["-include", "%{includes}"],
  186. iterate_over = "includes",
  187. expand_if_available = "includes",
  188. ),
  189. flag_group(
  190. flags = ["-iquote", "%{quote_include_paths}"],
  191. iterate_over = "quote_include_paths",
  192. ),
  193. flag_group(
  194. flags = ["-I%{include_paths}"],
  195. iterate_over = "include_paths",
  196. ),
  197. flag_group(
  198. flags = ["-isystem", "%{system_include_paths}"],
  199. iterate_over = "system_include_paths",
  200. ),
  201. ],
  202. ),
  203. flag_set(
  204. actions = [
  205. ACTION_NAMES.cpp_link_dynamic_library,
  206. ACTION_NAMES.cpp_link_nodeps_dynamic_library,
  207. ],
  208. flag_groups = [flag_group(flags = ["-shared"])],
  209. ),
  210. flag_set(
  211. actions = [
  212. ACTION_NAMES.cpp_link_executable,
  213. ],
  214. flag_groups = [
  215. flag_group(
  216. flags = ["-pie"],
  217. expand_if_available = "force_pic",
  218. ),
  219. ],
  220. ),
  221. flag_set(
  222. actions = all_link_actions,
  223. flag_groups = [
  224. flag_group(
  225. flags = ["-Wl,--gdb-index"],
  226. expand_if_available = "is_using_fission",
  227. ),
  228. flag_group(
  229. flags = ["-Wl,-S"],
  230. expand_if_available = "strip_debug_symbols",
  231. ),
  232. flag_group(
  233. flags = ["-L%{library_search_directories}"],
  234. iterate_over = "library_search_directories",
  235. expand_if_available = "library_search_directories",
  236. ),
  237. flag_group(
  238. iterate_over = "runtime_library_search_directories",
  239. flags = [
  240. "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}",
  241. ],
  242. expand_if_available =
  243. "runtime_library_search_directories",
  244. ),
  245. ],
  246. ),
  247. ],
  248. )
  249. # Handle different levels of optimization with individual features so that
  250. # they can be ordered and the defaults can override the minimal settings if
  251. # both are enabled.
  252. minimal_optimization_flags = feature(
  253. name = "minimal_optimization_flags",
  254. flag_sets = [
  255. flag_set(
  256. actions = codegen_compile_actions,
  257. flag_groups = [flag_group(flags = [
  258. "-O1",
  259. ])],
  260. ),
  261. # Use a conditional flag set for enabling the fast instruction
  262. # selector to work around an LLVM bug:
  263. # https://github.com/llvm/llvm-project/issues/56133
  264. flag_set(
  265. actions = codegen_compile_actions,
  266. flag_groups = [flag_group(flags = [
  267. "-mllvm",
  268. "-fast-isel",
  269. ])],
  270. with_features = [
  271. with_feature_set(not_features = ["fuzzer"]),
  272. ],
  273. ),
  274. ],
  275. )
  276. default_optimization_flags = feature(
  277. name = "default_optimization_flags",
  278. enabled = True,
  279. requires = [feature_set(["opt"])],
  280. flag_sets = [
  281. flag_set(
  282. actions = all_compile_actions,
  283. flag_groups = [flag_group(flags = [
  284. "-DNDEBUG",
  285. ])],
  286. ),
  287. flag_set(
  288. actions = codegen_compile_actions,
  289. flag_groups = [flag_group(flags = [
  290. "-O3",
  291. ])],
  292. ),
  293. ],
  294. )
  295. # Handle different levels and forms of debug info emission with individual
  296. # features so that they can be ordered and the defaults can override the
  297. # minimal settings if both are enabled.
  298. minimal_debug_info_flags = feature(
  299. name = "minimal_debug_info_flags",
  300. flag_sets = [flag_set(
  301. actions = codegen_compile_actions,
  302. flag_groups = [flag_group(flags = [
  303. "-gmlt",
  304. ])],
  305. )],
  306. )
  307. default_debug_info_flags = feature(
  308. name = "default_debug_info_flags",
  309. enabled = True,
  310. flag_sets = [
  311. flag_set(
  312. actions = codegen_compile_actions,
  313. flag_groups = ([
  314. flag_group(
  315. flags = ["-g"],
  316. ),
  317. ]),
  318. with_features = [with_feature_set(features = ["dbg"])],
  319. ),
  320. flag_set(
  321. actions = codegen_compile_actions,
  322. flag_groups = [
  323. flag_group(
  324. flags = ["-gsplit-dwarf", "-g"],
  325. expand_if_available = "per_object_debug_info_file",
  326. ),
  327. ],
  328. ),
  329. ],
  330. )
  331. # This feature can be enabled in conjunction with any optimizations to
  332. # ensure accurate call stacks and backtraces for profilers or errors.
  333. preserve_call_stacks = feature(
  334. name = "preserve_call_stacks",
  335. flag_sets = [flag_set(
  336. actions = codegen_compile_actions,
  337. flag_groups = [flag_group(flags = [
  338. # Ensure good backtraces by preserving frame pointers and
  339. # disabling tail call elimination.
  340. "-fno-omit-frame-pointer",
  341. "-mno-omit-leaf-frame-pointer",
  342. "-fno-optimize-sibling-calls",
  343. ])],
  344. )],
  345. )
  346. sysroot_feature = feature(
  347. name = "sysroot",
  348. enabled = True,
  349. flag_sets = [
  350. flag_set(
  351. actions = all_compile_actions + all_link_actions,
  352. flag_groups = [
  353. flag_group(
  354. flags = ["--sysroot=%{sysroot}"],
  355. expand_if_available = "sysroot",
  356. ),
  357. ],
  358. ),
  359. ],
  360. )
  361. use_module_maps = feature(
  362. name = "use_module_maps",
  363. requires = [feature_set(features = ["module_maps"])],
  364. flag_sets = [
  365. flag_set(
  366. actions = [
  367. ACTION_NAMES.c_compile,
  368. ACTION_NAMES.cpp_compile,
  369. ACTION_NAMES.cpp_header_parsing,
  370. ACTION_NAMES.cpp_module_compile,
  371. ],
  372. flag_groups = [
  373. # These flag groups are separate so they do not expand to
  374. # the cross product of the variables.
  375. flag_group(flags = ["-fmodule-name=%{module_name}"]),
  376. flag_group(
  377. flags = ["-fmodule-map-file=%{module_map_file}"],
  378. ),
  379. ],
  380. ),
  381. ],
  382. )
  383. # Tell bazel we support module maps in general, so they will be generated
  384. # for all c/c++ rules.
  385. # Note: not all C++ rules support module maps; thus, do not imply this
  386. # feature from other features - instead, require it.
  387. module_maps = feature(
  388. name = "module_maps",
  389. enabled = True,
  390. implies = [
  391. # "module_map_home_cwd",
  392. # "module_map_without_extern_module",
  393. # "generate_submodules",
  394. ],
  395. )
  396. layering_check = feature(
  397. name = "layering_check",
  398. implies = ["use_module_maps"],
  399. flag_sets = [
  400. flag_set(
  401. actions = [
  402. ACTION_NAMES.c_compile,
  403. ACTION_NAMES.cpp_compile,
  404. ACTION_NAMES.cpp_header_parsing,
  405. ACTION_NAMES.cpp_module_compile,
  406. ],
  407. flag_groups = [
  408. flag_group(flags = [
  409. "-fmodules-strict-decluse",
  410. "-Wprivate-header",
  411. ]),
  412. flag_group(
  413. iterate_over = "dependent_module_map_files",
  414. flags = [
  415. "-fmodule-map-file=%{dependent_module_map_files}",
  416. ],
  417. ),
  418. ],
  419. ),
  420. ],
  421. )
  422. sanitizer_common_flags = feature(
  423. name = "sanitizer_common_flags",
  424. requires = [feature_set(["nonhost"])],
  425. implies = ["minimal_optimization_flags", "minimal_debug_info_flags", "preserve_call_stacks"],
  426. flag_sets = [flag_set(
  427. actions = all_link_actions,
  428. flag_groups = [flag_group(flags = [
  429. "-static-libsan",
  430. ])],
  431. )],
  432. )
  433. asan = feature(
  434. name = "asan",
  435. requires = [feature_set(["nonhost"])],
  436. implies = ["sanitizer_common_flags"],
  437. flag_sets = [flag_set(
  438. actions = all_compile_actions + all_link_actions,
  439. flag_groups = [flag_group(flags = [
  440. "-fsanitize=address,undefined,nullability",
  441. "-fsanitize-address-use-after-scope",
  442. # We don't need the recovery behavior of UBSan as we expect
  443. # builds to be clean. Not recoverying is a bit cheaper.
  444. "-fno-sanitize-recover=undefined",
  445. # Don't embed the full path name for files. This limits the size
  446. # and combined with line numbers is unlikely to result in many
  447. # ambiguities.
  448. "-fsanitize-undefined-strip-path-components=-1",
  449. # Needed due to clang AST issues, such as in
  450. # clang/AST/Redeclarable.h line 199.
  451. "-fno-sanitize=vptr",
  452. ])],
  453. )],
  454. )
  455. enable_asan_in_fastbuild = feature(
  456. name = "enable_asan_in_fastbuild",
  457. enabled = True,
  458. requires = [feature_set(["nonhost", "fastbuild"])],
  459. implies = ["asan"],
  460. )
  461. fuzzer = feature(
  462. name = "fuzzer",
  463. requires = [feature_set(["nonhost"])],
  464. implies = ["asan"],
  465. flag_sets = [flag_set(
  466. actions = all_compile_actions + all_link_actions,
  467. flag_groups = [flag_group(flags = [
  468. "-fsanitize=fuzzer",
  469. ])],
  470. )],
  471. )
  472. proto_fuzzer = feature(
  473. name = "proto-fuzzer",
  474. enabled = False,
  475. requires = [feature_set(["nonhost"])],
  476. # TODO: this should really be `fuzzer`, but `-fsanitize=fuzzer` triggers
  477. # a clang crash when running `bazel test --config=fuzzer ...`. See
  478. # https://github.com/carbon-language/carbon-lang/issues/1173
  479. implies = ["asan"],
  480. )
  481. linux_flags_feature = feature(
  482. name = "linux_flags",
  483. enabled = True,
  484. flag_sets = [
  485. flag_set(
  486. actions = all_link_actions,
  487. flag_groups = ([
  488. flag_group(
  489. flags = [
  490. "-fuse-ld=lld",
  491. "-stdlib=libc++",
  492. "-unwindlib=libunwind",
  493. # Force the C++ standard library and runtime
  494. # libraries to be statically linked. This works even
  495. # with libc++ and libunwind despite the names,
  496. # provided libc++ is built with two CMake options:
  497. # - `-DCMAKE_POSITION_INDEPENDENT_CODE=ON`
  498. # - `-DLIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY`
  499. # These are both required because of PR43604
  500. # (impacting at least Debian packages of libc++) and
  501. # PR46321 (impacting most other packages).
  502. # We recommend using Homebrew's LLVM install on
  503. # Linux.
  504. "-static-libstdc++",
  505. "-static-libgcc",
  506. # Link with Clang's runtime library. This is always
  507. # linked statically.
  508. "-rtlib=compiler-rt",
  509. # Explicitly add LLVM libs to the search path to
  510. # preempt the detected GCC installation's library
  511. # paths. Those might have a system installed libc++
  512. # and we want to find the one next to our Clang.
  513. "-L" + llvm_bindir + "/../lib",
  514. # Link with pthread.
  515. "-lpthread",
  516. ],
  517. ),
  518. ]),
  519. ),
  520. flag_set(
  521. actions = all_compile_actions,
  522. flag_groups = [flag_group(flags = [
  523. # Enable libc++'s debug features.
  524. "-D_LIBCPP_DEBUG=1",
  525. ])],
  526. with_features = [
  527. # _LIBCPP_DEBUG=1 causes protobuf code to crash when linked
  528. # with `-fsanitize=fuzzer`, possibly because of ODR
  529. # violations caused by Carbon source and pre-compiled llvm
  530. # Fuzzer driver library built with different _LIBCPP_DEBUG
  531. # values.
  532. with_feature_set(not_features = ["opt", "proto-fuzzer"]),
  533. ],
  534. ),
  535. ],
  536. )
  537. default_link_libraries_feature = feature(
  538. name = "default_link_libraries",
  539. enabled = True,
  540. flag_sets = [
  541. flag_set(
  542. actions = all_link_actions,
  543. flag_groups = [
  544. flag_group(
  545. flags = ["%{linkstamp_paths}"],
  546. iterate_over = "linkstamp_paths",
  547. expand_if_available = "linkstamp_paths",
  548. ),
  549. flag_group(
  550. iterate_over = "libraries_to_link",
  551. flag_groups = [
  552. flag_group(
  553. flags = ["-Wl,--start-lib"],
  554. expand_if_equal = variable_with_value(
  555. name = "libraries_to_link.type",
  556. value = "object_file_group",
  557. ),
  558. ),
  559. flag_group(
  560. flags = ["-Wl,-whole-archive"],
  561. expand_if_true =
  562. "libraries_to_link.is_whole_archive",
  563. ),
  564. flag_group(
  565. flags = ["%{libraries_to_link.object_files}"],
  566. iterate_over = "libraries_to_link.object_files",
  567. expand_if_equal = variable_with_value(
  568. name = "libraries_to_link.type",
  569. value = "object_file_group",
  570. ),
  571. ),
  572. flag_group(
  573. flags = ["%{libraries_to_link.name}"],
  574. expand_if_equal = variable_with_value(
  575. name = "libraries_to_link.type",
  576. value = "object_file",
  577. ),
  578. ),
  579. flag_group(
  580. flags = ["%{libraries_to_link.name}"],
  581. expand_if_equal = variable_with_value(
  582. name = "libraries_to_link.type",
  583. value = "interface_library",
  584. ),
  585. ),
  586. flag_group(
  587. flags = ["%{libraries_to_link.name}"],
  588. expand_if_equal = variable_with_value(
  589. name = "libraries_to_link.type",
  590. value = "static_library",
  591. ),
  592. ),
  593. flag_group(
  594. flags = ["-l%{libraries_to_link.name}"],
  595. expand_if_equal = variable_with_value(
  596. name = "libraries_to_link.type",
  597. value = "dynamic_library",
  598. ),
  599. ),
  600. flag_group(
  601. flags = ["-l:%{libraries_to_link.name}"],
  602. expand_if_equal = variable_with_value(
  603. name = "libraries_to_link.type",
  604. value = "versioned_dynamic_library",
  605. ),
  606. ),
  607. flag_group(
  608. flags = ["-Wl,-no-whole-archive"],
  609. expand_if_true = "libraries_to_link.is_whole_archive",
  610. ),
  611. flag_group(
  612. flags = ["-Wl,--end-lib"],
  613. expand_if_equal = variable_with_value(
  614. name = "libraries_to_link.type",
  615. value = "object_file_group",
  616. ),
  617. ),
  618. ],
  619. expand_if_available = "libraries_to_link",
  620. ),
  621. # Note that the params file comes at the end, after the
  622. # libraries to link above.
  623. flag_group(
  624. expand_if_available = "linker_param_file",
  625. flags = ["@%{linker_param_file}"],
  626. ),
  627. ],
  628. ),
  629. ],
  630. )
  631. # Place user provided compile flags after all the features so that these
  632. # flags can override or customize behavior. The only thing user flags
  633. # cannot override is the output file as Bazel depends on that.
  634. #
  635. # Finally, place the source file (if present) and output file last to make
  636. # reading the compile command lines easier for humans.
  637. final_flags_feature = feature(
  638. name = "final_flags",
  639. enabled = True,
  640. flag_sets = [
  641. flag_set(
  642. actions = all_compile_actions,
  643. flag_groups = [
  644. flag_group(
  645. flags = ["%{user_compile_flags}"],
  646. iterate_over = "user_compile_flags",
  647. expand_if_available = "user_compile_flags",
  648. ),
  649. flag_group(
  650. flags = ["%{source_file}"],
  651. expand_if_available = "source_file",
  652. ),
  653. flag_group(
  654. expand_if_available = "output_file",
  655. flags = ["-o", "%{output_file}"],
  656. ),
  657. ],
  658. ),
  659. flag_set(
  660. actions = all_link_actions,
  661. flag_groups = [
  662. flag_group(
  663. flags = ["%{user_link_flags}"],
  664. iterate_over = "user_link_flags",
  665. expand_if_available = "user_link_flags",
  666. ),
  667. flag_group(
  668. flags = ["-o", "%{output_execpath}"],
  669. expand_if_available = "output_execpath",
  670. ),
  671. ],
  672. ),
  673. ],
  674. )
  675. # Archive actions have an entirely independent set of flags and don't
  676. # interact with either compiler or link actions.
  677. default_archiver_flags_feature = feature(
  678. name = "default_archiver_flags",
  679. enabled = True,
  680. flag_sets = [
  681. flag_set(
  682. actions = [ACTION_NAMES.cpp_link_static_library],
  683. flag_groups = [
  684. flag_group(flags = ["rcsD"]),
  685. flag_group(
  686. flags = ["%{output_execpath}"],
  687. expand_if_available = "output_execpath",
  688. ),
  689. flag_group(
  690. iterate_over = "libraries_to_link",
  691. flag_groups = [
  692. flag_group(
  693. flags = ["%{libraries_to_link.name}"],
  694. expand_if_equal = variable_with_value(
  695. name = "libraries_to_link.type",
  696. value = "object_file",
  697. ),
  698. ),
  699. flag_group(
  700. flags = ["%{libraries_to_link.object_files}"],
  701. iterate_over = "libraries_to_link.object_files",
  702. expand_if_equal = variable_with_value(
  703. name = "libraries_to_link.type",
  704. value = "object_file_group",
  705. ),
  706. ),
  707. ],
  708. expand_if_available = "libraries_to_link",
  709. ),
  710. flag_group(
  711. expand_if_available = "linker_param_file",
  712. flags = ["@%{linker_param_file}"],
  713. ),
  714. ],
  715. ),
  716. ],
  717. )
  718. # Now that we have built up the constituent feature definitions, compose
  719. # them, including configuration based on the target platform. Currently,
  720. # the target platform is configured with the "cpu" attribute for legacy
  721. # reasons. Further, for legacy reasons the default is a Linux OS target and
  722. # the x88-64 CPU name is "k8".
  723. # First, define features that are simply used to configure others.
  724. features = [
  725. feature(name = "dbg"),
  726. feature(name = "fastbuild"),
  727. feature(name = "host"),
  728. feature(name = "no_legacy_features"),
  729. feature(name = "nonhost"),
  730. feature(name = "opt"),
  731. feature(name = "supports_dynamic_linker", enabled = ctx.attr.target_cpu == "k8"),
  732. feature(name = "supports_pic", enabled = True),
  733. feature(name = "supports_start_end_lib", enabled = ctx.attr.target_cpu == "k8"),
  734. ]
  735. # The order of the features determines the relative order of flags used.
  736. # Start off adding the baseline features.
  737. features += [
  738. default_flags_feature,
  739. minimal_optimization_flags,
  740. default_optimization_flags,
  741. minimal_debug_info_flags,
  742. default_debug_info_flags,
  743. preserve_call_stacks,
  744. sysroot_feature,
  745. sanitizer_common_flags,
  746. asan,
  747. enable_asan_in_fastbuild,
  748. fuzzer,
  749. proto_fuzzer,
  750. layering_check,
  751. module_maps,
  752. use_module_maps,
  753. default_archiver_flags_feature,
  754. ]
  755. # Next, add the features based on the target platform. Here too the
  756. # features are order sensitive. We also setup the sysroot here.
  757. if ctx.attr.target_cpu == "k8":
  758. features += [linux_flags_feature]
  759. sysroot = None
  760. elif ctx.attr.target_cpu in ["darwin", "darwin_arm64"]:
  761. sysroot = sysroot_dir
  762. else:
  763. fail("Unsupported target platform!")
  764. # Finally append the libraries to link and any final flags.
  765. features += [
  766. default_link_libraries_feature,
  767. final_flags_feature,
  768. ]
  769. return cc_common.create_cc_toolchain_config_info(
  770. ctx = ctx,
  771. features = features,
  772. action_configs = action_configs,
  773. cxx_builtin_include_directories = clang_include_dirs_list + [
  774. # Add Clang's resource directory to the end of the builtin include
  775. # directories to cover the use of sanitizer resource files by the driver.
  776. clang_resource_dir + "/share",
  777. ],
  778. builtin_sysroot = sysroot,
  779. # This configuration only supports local non-cross builds so derive
  780. # everything from the target CPU selected.
  781. toolchain_identifier = "local-" + ctx.attr.target_cpu,
  782. host_system_name = "local-" + ctx.attr.target_cpu,
  783. target_system_name = "local-" + ctx.attr.target_cpu,
  784. target_cpu = ctx.attr.target_cpu,
  785. # These attributes aren't meaningful at all so just use placeholder
  786. # values.
  787. target_libc = "local",
  788. compiler = "local",
  789. abi_version = "local",
  790. abi_libc_version = "local",
  791. # We do have to pass in our tool paths.
  792. tool_paths = tool_paths,
  793. )
  794. cc_toolchain_config = rule(
  795. implementation = _impl,
  796. attrs = {
  797. "target_cpu": attr.string(mandatory = True),
  798. },
  799. provides = [CcToolchainConfigInfo],
  800. )