From e1ed9e9e567334fdf7c26cd0db6f20c64840f119 Mon Sep 17 00:00:00 2001 From: allevato Date: Thu, 5 Apr 2018 09:46:55 -0700 Subject: Fix strict module map propagation for j2objc. J2Objc needs special consideration to implement strict Swift-ObjC deps. The module maps for the generated Objective-C code are associated with their originating java_library targets (via the J2Objc aspect), which a swift_library cannot directly depend on. So those deeper down module maps need to be propagated transitively *until* a j2objc_library is reached; at that point, the j2objc_library should propagate all of its Java deps module maps, but *not* any of its j2objc_library deps (because that would be non-strict). PiperOrigin-RevId: 191754811 --- .../devtools/build/lib/rules/objc/ObjcCommon.java | 34 +++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java') diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java index d4a26a234d..13a915f22a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java @@ -157,6 +157,7 @@ public final class ObjcCommon { private Iterable depObjcProviders = ImmutableList.of(); private Iterable directDepObjcProviders = ImmutableList.of(); private Iterable runtimeDepObjcProviders = ImmutableList.of(); + private Iterable repropagatedModuleMapObjcProviders = ImmutableList.of(); private Iterable defines = ImmutableList.of(); private Iterable includes = ImmutableList.of(); private Iterable directDependencyIncludes = ImmutableList.of(); @@ -362,6 +363,22 @@ public final class ObjcCommon { return this; } + /** + * Adds Objc providers whose module maps should be repropagated as if they are directly + * associated with the target propagating the provider being built. + * + *

This supports a small number of specialized use cases, like J2Objc, where the module maps + * associated with the {@code java_library} (via an aspect) need to be repropagated by the + * {@code j2objc_library} that depends on them so that Swift code can access those module maps + * for the purposes of strict module map propagation (without propagating the module maps + * _fully_ transitively). + */ + Builder addRepropagatedModuleMapObjcProviders(Iterable objcProviders) { + this.repropagatedModuleMapObjcProviders = + Iterables.concat(this.repropagatedModuleMapObjcProviders, objcProviders); + return this; + } + /** * Adds additional static libraries to be linked into the final ObjC application bundle. */ @@ -544,13 +561,21 @@ public final class ObjcCommon { } } + if (useStrictObjcModuleMaps(context)) { + for (ObjcProvider provider : repropagatedModuleMapObjcProviders) { + objcProvider.addAllForDirectDependents(MODULE_MAP, provider.get(ObjcProvider.MODULE_MAP)); + objcProvider.addAllForDirectDependents( + TOP_LEVEL_MODULE_MAP, provider.get(ObjcProvider.TOP_LEVEL_MODULE_MAP)); + } + } + if (hasModuleMap) { CppModuleMap moduleMap = intermediateArtifacts.moduleMap(); Optional umbrellaHeader = moduleMap.getUmbrellaHeader(); if (umbrellaHeader.isPresent()) { objcProvider.add(UMBRELLA_HEADER, umbrellaHeader.get()); } - if (context.getFragment(ObjcConfiguration.class).useStrictObjcModuleMaps()) { + if (useStrictObjcModuleMaps(context)) { objcProvider.addForDirectDependents(MODULE_MAP, moduleMap.getArtifact()); objcProvider.addForDirectDependents(TOP_LEVEL_MODULE_MAP, moduleMap); } else { @@ -572,6 +597,13 @@ public final class ObjcCommon { return new ObjcCommon(objcProvider.build(), compilationArtifacts); } + private static boolean useStrictObjcModuleMaps(RuleContext context) { + // We need to check isLegalFragment first because some non-compilation rules, like + // objc_bundle_library, don't declare this fragment. + return context.isLegalFragment(ObjcConfiguration.class) + && context.getFragment(ObjcConfiguration.class).useStrictObjcModuleMaps(); + } + private static boolean isCcLibrary(ConfiguredTargetAndData info) { try { String targetName = info.getTarget().getTargetKind(); -- cgit v1.2.3