Blaze exports a feature for actions with objective c source in their transitive closure. PiperOrigin-RevId: 165934905
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java index db757a1..e0369a1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java
@@ -105,6 +105,9 @@ private static final String GENERATE_LINKMAP_FEATURE_NAME = "generate_linkmap"; + /** Enabled if this target has objc sources in its transitive closure. */ + private static final String CONTAINS_OBJC = "contains_objc_sources"; + private static final ImmutableList<String> ACTIVATED_ACTIONS = ImmutableList.of( "objc-compile", @@ -251,7 +254,7 @@ outputArchive, ccToolchain, fdoSupport, - getFeatureConfiguration(ruleContext, ccToolchain, buildConfiguration)) + getFeatureConfiguration(ruleContext, ccToolchain, buildConfiguration, objcProvider)) .addActionInputs(objcProvider.getObjcLibraries()) .addActionInputs(objcProvider.getCcLibraries()) .addActionInputs(objcProvider.get(IMPORTED_LIBRARY).toSet()) @@ -327,7 +330,7 @@ binaryToLink, toolchain, fdoSupport, - getFeatureConfiguration(ruleContext, toolchain, buildConfiguration)) + getFeatureConfiguration(ruleContext, toolchain, buildConfiguration, objcProvider)) .setMnemonic("ObjcLink") .addActionInputs(bazelBuiltLibraries) .addActionInputs(objcProvider.getCcLibraries()) @@ -426,7 +429,7 @@ new CcLibraryHelper( ruleContext, semantics, - getFeatureConfiguration(ruleContext, ccToolchain, buildConfiguration), + getFeatureConfiguration(ruleContext, ccToolchain, buildConfiguration, objcProvider), CcLibraryHelper.SourceCategory.CC_AND_OBJC, ccToolchain, fdoSupport, @@ -472,8 +475,11 @@ return result; } - private FeatureConfiguration getFeatureConfiguration(RuleContext ruleContext, - CcToolchainProvider ccToolchain, BuildConfiguration configuration) { + private FeatureConfiguration getFeatureConfiguration( + RuleContext ruleContext, + CcToolchainProvider ccToolchain, + BuildConfiguration configuration, + ObjcProvider objcProvider) { boolean isHost = ruleContext.getConfiguration().isHostConfiguration(); ImmutableSet.Builder<String> activatedCrosstoolSelectables = ImmutableSet.<String>builder() @@ -524,6 +530,9 @@ if (bitcodeMode != AppleBitcodeMode.NONE) { activatedCrosstoolSelectables.addAll(bitcodeMode.getFeatureNames()); } + if (objcProvider.is(Flag.USES_OBJC)) { + activatedCrosstoolSelectables.add(CONTAINS_OBJC); + } activatedCrosstoolSelectables.addAll(ruleContext.getFeatures()); try {
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 a58beff..ae1c7b7 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
@@ -26,6 +26,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FLAG; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FORCE_LOAD_LIBRARY; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_CPP; +import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_OBJC; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.HEADER; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INCLUDE; @@ -70,8 +71,10 @@ import com.google.devtools.build.lib.rules.cpp.CcLinkParams; import com.google.devtools.build.lib.rules.cpp.CcLinkParamsInfo; import com.google.devtools.build.lib.rules.cpp.CppCompilationContext; +import com.google.devtools.build.lib.rules.cpp.CppFileTypes; import com.google.devtools.build.lib.rules.cpp.CppModuleMap; import com.google.devtools.build.lib.util.FileType; +import com.google.devtools.build.lib.util.FileTypeSet; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.HashSet; @@ -523,14 +526,22 @@ } boolean usesCpp = false; + boolean usesObjc = false; for (Artifact sourceFile : Iterables.concat(artifacts.getSrcs(), artifacts.getNonArcSrcs())) { usesCpp = usesCpp || ObjcRuleClasses.CPP_SOURCES.matches(sourceFile.getExecPath()); + usesObjc = + usesObjc + || FileTypeSet.of(CppFileTypes.OBJC_SOURCE, CppFileTypes.OBJCPP_SOURCE) + .matches(sourceFile.getExecPath().getPathString()); } if (usesCpp) { objcProvider.add(FLAG, USES_CPP); } + if (usesObjc) { + objcProvider.add(FLAG, USES_OBJC); + } } if (alwayslink) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java index 502e055..c5e39a4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
@@ -349,6 +349,12 @@ */ USES_CPP, + /** + * Indicates that Objective-C (or Objective-C++) is used in any source file. This affects how + * the linker is invoked. + */ + USES_OBJC, + /** Indicates that Swift dependencies are present. This affects bundling actions. */ USES_SWIFT,
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java index abbae40..2028571 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java
@@ -59,6 +59,24 @@ useConfiguration(ObjcCrosstoolMode.OFF, args); } + @Override + @Test + public void testObjcSourcesFeatureCC() throws Exception { + // Features are not exported by legacy actions. + } + + @Override + @Test + public void testObjcSourcesFeatureObjc() throws Exception { + // Features are not exported by legacy actions. + } + + @Override + @Test + public void testObjcSourcesFeatureObjcPlusPlus() throws Exception { + // Features are not exported by legacy actions. + } + @Test public void testLibFileIsCorrectForSlashInTargetName() throws Exception { ConfiguredTarget target =
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java index 9e2d0c0..3409176 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java
@@ -1601,4 +1601,45 @@ public void testCustomModuleMap() throws Exception { checkCustomModuleMap(RULE_TYPE); } + + private boolean containsObjcFeature(String srcName) throws Exception { + MockObjcSupport.setup( + mockToolsConfig, + "feature {", + " name: 'contains_objc_sources'", + " flag_set {", + " flag_group {", + " flag: 'DUMMY_FLAG'", + " }", + " action: 'c++-compile'", + " }", + "}"); + createLibraryTargetWriter("//bottom:lib").setList("srcs", srcName).write(); + createLibraryTargetWriter("//middle:lib") + .setList("srcs", "b.cc") + .setList("deps", "//bottom:lib") + .write(); + createLibraryTargetWriter("//top:lib") + .setList("srcs", "a.cc") + .setList("deps", "//middle:lib") + .write(); + + CommandAction compileAction = compileAction("//top:lib", "a.o"); + return compileAction.getArguments().contains("DUMMY_FLAG"); + } + + @Test + public void testObjcSourcesFeatureCC() throws Exception { + assertThat(containsObjcFeature("c.cc")).isFalse(); + } + + @Test + public void testObjcSourcesFeatureObjc() throws Exception { + assertThat(containsObjcFeature("c.m")).isTrue(); + } + + @Test + public void testObjcSourcesFeatureObjcPlusPlus() throws Exception { + assertThat(containsObjcFeature("c.mm")).isTrue(); + } }