clang_cc_toolchain_config.bzl 31 KB

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