@@ -362,6 +362,21 @@ def compile_action_configs(
362
362
]
363
363
364
364
#### Flags controlling how Swift/Clang modular inputs are processed
365
+
366
+ def c_layering_check_configurator (prerequisites , args , * , strict ):
367
+ # We do not enforce layering checks for the Objective-C header generated
368
+ # by Swift, because we don't have predictable control over the imports
369
+ # that it generates. Due to modular re-exports (which are especially
370
+ # common among system frameworks), it may generate an import declaration
371
+ # for a particular symbol from a different module than the Swift code
372
+ # imported it from.
373
+ if not prerequisites .is_swift_generated_header :
374
+ args .add (
375
+ "-Xcc" ,
376
+ "-fmodules-strict-decluse" if strict else "-fmodules-decluse" ,
377
+ )
378
+ return None
379
+
365
380
action_configs += [
366
381
# Treat paths in .modulemap files as workspace-relative, not modulemap-
367
382
# relative.
@@ -443,12 +458,10 @@ def compile_action_configs(
443
458
swift_toolchain_config .action_config (
444
459
actions = [swift_action_names .PRECOMPILE_C_MODULE ],
445
460
configurators = [
446
- # Enforce `use` declarations for user modules since we generate
447
- # those, but not for system modules since they typically do not
448
- # have the proper `use` decls.
449
- swift_toolchain_config .add_arg (
450
- "-Xcc" ,
451
- "-fmodules-decluse" ,
461
+ lambda prerequisites , args : c_layering_check_configurator (
462
+ prerequisites ,
463
+ args ,
464
+ strict = False ,
452
465
),
453
466
],
454
467
not_features = [
@@ -459,9 +472,10 @@ def compile_action_configs(
459
472
swift_toolchain_config .action_config (
460
473
actions = [swift_action_names .PRECOMPILE_C_MODULE ],
461
474
configurators = [
462
- swift_toolchain_config .add_arg (
463
- "-Xcc" ,
464
- "-fmodules-strict-decluse" ,
475
+ lambda prerequisites , args : c_layering_check_configurator (
476
+ prerequisites ,
477
+ args ,
478
+ strict = True ,
465
479
),
466
480
],
467
481
features = [SWIFT_FEATURE_LAYERING_CHECK ],
@@ -1480,14 +1494,15 @@ def compile(
1480
1494
feature_configuration = feature_configuration ,
1481
1495
feature_name = SWIFT_FEATURE_NO_GENERATED_MODULE_MAP ,
1482
1496
):
1483
- precompiled_module = precompile_clang_module (
1497
+ precompiled_module = _precompile_clang_module (
1484
1498
actions = actions ,
1485
1499
bin_dir = bin_dir ,
1486
1500
cc_compilation_context = cc_common .create_compilation_context (
1487
1501
headers = depset ([compile_outputs .generated_header_file ]),
1488
1502
),
1489
1503
feature_configuration = feature_configuration ,
1490
1504
genfiles_dir = genfiles_dir ,
1505
+ is_swift_generated_header = True ,
1491
1506
module_map_file = compile_outputs .generated_module_map_file ,
1492
1507
module_name = module_name ,
1493
1508
swift_info = create_swift_info (
@@ -1574,6 +1589,74 @@ def precompile_clang_module(
1574
1589
swift_info: A `SwiftInfo` provider that contains dependencies required
1575
1590
to compile this module.
1576
1591
1592
+ Returns:
1593
+ A `File` representing the precompiled module (`.pcm`) file, or `None` if
1594
+ the toolchain or target does not support precompiled modules.
1595
+ """
1596
+ return _precompile_clang_module (
1597
+ actions = actions ,
1598
+ bin_dir = bin_dir ,
1599
+ cc_compilation_context = cc_compilation_context ,
1600
+ feature_configuration = feature_configuration ,
1601
+ genfiles_dir = genfiles_dir ,
1602
+ is_swift_generated_header = False ,
1603
+ module_map_file = module_map_file ,
1604
+ module_name = module_name ,
1605
+ swift_info = swift_info ,
1606
+ swift_toolchain = swift_toolchain ,
1607
+ target_name = target_name ,
1608
+ )
1609
+
1610
+ def _precompile_clang_module (
1611
+ * ,
1612
+ actions ,
1613
+ cc_compilation_context ,
1614
+ feature_configuration ,
1615
+ is_swift_generated_header ,
1616
+ module_map_file ,
1617
+ module_name ,
1618
+ swift_toolchain ,
1619
+ target_name ,
1620
+ bin_dir = None ,
1621
+ genfiles_dir = None ,
1622
+ swift_info = None ):
1623
+ """Precompiles an explicit Clang module that is compatible with Swift.
1624
+
1625
+ Args:
1626
+ actions: The context's `actions` object.
1627
+ cc_compilation_context: A `CcCompilationContext` that contains headers
1628
+ and other information needed to compile this module. This
1629
+ compilation context should contain all headers required to compile
1630
+ the module, which includes the headers for the module itself *and*
1631
+ any others that must be present on the file system/in the sandbox
1632
+ for compilation to succeed. The latter typically refers to the set
1633
+ of headers of the direct dependencies of the module being compiled,
1634
+ which Clang needs to be physically present before it detects that
1635
+ they belong to one of the precompiled module dependencies.
1636
+ feature_configuration: A feature configuration obtained from
1637
+ `swift_common.configure_features`.
1638
+ is_swift_generated_header: If True, the action is compiling the
1639
+ Objective-C header generated by the Swift compiler for a module.
1640
+ module_map_file: A textual module map file that defines the Clang module
1641
+ to be compiled.
1642
+ module_name: The name of the top-level module in the module map that
1643
+ will be compiled.
1644
+ swift_toolchain: The `SwiftToolchainInfo` provider of the toolchain.
1645
+ target_name: The name of the target for which the code is being
1646
+ compiled, which is used to determine unique file paths for the
1647
+ outputs.
1648
+ bin_dir: The Bazel `*-bin` directory root. If provided, its path is used
1649
+ to store the cache for modules precompiled by Swift's ClangImporter,
1650
+ and it is added to ClangImporter's header search paths for
1651
+ compatibility with Bazel's C++ and Objective-C rules which support
1652
+ includes of generated headers from that location.
1653
+ genfiles_dir: The Bazel `*-genfiles` directory root. If provided, its
1654
+ path is added to ClangImporter's header search paths for
1655
+ compatibility with Bazel's C++ and Objective-C rules which support
1656
+ inclusions of generated headers from that location.
1657
+ swift_info: A `SwiftInfo` provider that contains dependencies required
1658
+ to compile this module.
1659
+
1577
1660
Returns:
1578
1661
A `File` representing the precompiled module (`.pcm`) file, or `None` if
1579
1662
the toolchain or target does not support precompiled modules.
@@ -1608,6 +1691,7 @@ def precompile_clang_module(
1608
1691
cc_info = CcInfo (compilation_context = cc_compilation_context ),
1609
1692
genfiles_dir = genfiles_dir ,
1610
1693
is_swift = False ,
1694
+ is_swift_generated_header = is_swift_generated_header ,
1611
1695
module_name = module_name ,
1612
1696
objc_include_paths_workaround = depset (),
1613
1697
objc_info = apple_common .new_objc_provider (),
0 commit comments