clang_cc_toolchain_config.bzl 31 KB

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