diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java index de3717ca6547bf..08944f39d391b3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java @@ -19,6 +19,7 @@ import static com.google.devtools.build.lib.packages.Attribute.attr; import static com.google.devtools.build.lib.packages.BuildType.LABEL; import static java.nio.charset.StandardCharsets.ISO_8859_1; +import static java.util.stream.Collectors.toList; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -33,6 +34,7 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg; import com.google.devtools.build.lib.analysis.actions.SpawnAction; @@ -53,6 +55,7 @@ import com.google.devtools.build.lib.rules.apple.AppleConfiguration; import com.google.devtools.build.lib.rules.apple.AppleToolchain; import com.google.devtools.build.lib.rules.apple.XcodeConfigRule; +import com.google.devtools.build.lib.rules.cpp.CcInfo; import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; import com.google.devtools.build.lib.rules.cpp.CppConfiguration; import com.google.devtools.build.lib.rules.cpp.CppHelper; @@ -82,7 +85,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.stream.Collectors; /** J2ObjC transpilation aspect for Java and proto rules. */ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectFactory { @@ -310,6 +312,11 @@ private ConfiguredAspect buildAspect( .addProvider( exportedJ2ObjcMappingFileProvider(base, ruleContext, directJ2ObjcMappingFileProvider)) .addNativeDeclaredProvider(objcProvider) + .addProvider( + J2ObjcCcInfo.build( + CcInfo.builder() + .setCcCompilationContext(objcProvider.getCcCompilationContext()) + .build())) .build(); } @@ -844,7 +851,7 @@ private static ObjcCommon common( List transpiledHeaders, List headerSearchPaths, List dependentAttributes, - List otherObjcProviders) + List otherDeps) throws InterruptedException { ObjcCommon.Builder builder = new ObjcCommon.Builder(purpose, ruleContext); IntermediateArtifacts intermediateArtifacts = @@ -861,28 +868,58 @@ private static ObjcCommon common( } for (Attribute dependentAttribute : dependentAttributes) { - if (ruleContext.attributes().has(dependentAttribute.getName(), BuildType.LABEL_LIST) - || ruleContext.attributes().has(dependentAttribute.getName(), BuildType.LABEL)) { + String attrName = dependentAttribute.getName(); + Mode attrMode = dependentAttribute.getAccessMode(); + if (ruleContext.attributes().has(attrName, BuildType.LABEL_LIST) + || ruleContext.attributes().has(attrName, BuildType.LABEL)) { + ImmutableList.Builder ccInfoList = new ImmutableList.Builder<>(); + for (TransitiveInfoCollection dep : ruleContext.getPrerequisites(attrName, attrMode)) { + J2ObjcCcInfo j2objcCcInfo = dep.getProvider(J2ObjcCcInfo.class); + CcInfo ccInfo = dep.get(CcInfo.PROVIDER); + // If a dep has both a J2ObjcCcInfo and a CcInfo, skip the CcInfo. This can only happen + // for a proto_library, whose CcInfo we don't use and may have poisoned defines. + if (j2objcCcInfo != null) { + ccInfoList.add(j2objcCcInfo.getCcInfo()); + } else if (ccInfo != null) { + ccInfoList.add(ccInfo); + } + } + builder.addDepCcHeaderProviders(ccInfoList.build()); builder.addDepObjcProviders( - ruleContext.getPrerequisites( - dependentAttribute.getName(), - dependentAttribute.getAccessMode(), - ObjcProvider.SKYLARK_CONSTRUCTOR)); + ruleContext.getPrerequisites(attrName, attrMode, ObjcProvider.SKYLARK_CONSTRUCTOR)); } } - List newOtherDeps = - otherObjcProviders - .stream() - .map(d -> d.get(ObjcProvider.SKYLARK_CONSTRUCTOR)) - .collect(Collectors.toList()); - // We can't just use addDeps since that now takes ConfiguredTargetAndTargets and we only have + // We can't just use addDeps since that now takes ConfiguredTargetAndData and we only have // TransitiveInfoCollections - builder.addDepObjcProviders(newOtherDeps); + builder.addDepObjcProviders( + otherDeps.stream().map(d -> d.get(ObjcProvider.SKYLARK_CONSTRUCTOR)).collect(toList())); + builder.addDepCcHeaderProviders( + otherDeps.stream().map(d -> d.get(CcInfo.PROVIDER)).collect(toList())); return builder .addIncludes(headerSearchPaths) .setIntermediateArtifacts(intermediateArtifacts) .build(); } + + /** + * A wrapper for {@link CcInfo}. The aspect generates this instead of a raw CcInfo, because it may + * visit a proto_library rule which already has a CcInfo. + */ + public static final class J2ObjcCcInfo implements TransitiveInfoProvider { + private final CcInfo ccInfo; + + public J2ObjcCcInfo(CcInfo ccInfo) { + this.ccInfo = ccInfo; + } + + public CcInfo getCcInfo() { + return ccInfo; + } + + public static J2ObjcCcInfo build(CcInfo ccInfo) { + return new J2ObjcCcInfo(ccInfo); + } + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java index 7839f14b4256d7..6e26b802a12fab 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.rules.objc; import static com.google.devtools.build.lib.collect.nestedset.Order.STABLE_ORDER; +import static java.util.stream.Collectors.toList; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; @@ -28,6 +29,8 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.Type; +import com.google.devtools.build.lib.rules.cpp.CcInfo; +import com.google.devtools.build.lib.rules.objc.J2ObjcAspect.J2ObjcCcInfo; import java.util.List; /** @@ -45,11 +48,15 @@ public class J2ObjcLibrary implements RuleConfiguredTargetFactory { ImmutableList.of("java_import", "java_library", "java_proto_library", "proto_library"); private ObjcCommon common(RuleContext ruleContext) throws InterruptedException { + List j2objcCcInfos = + ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcCcInfo.class); return new ObjcCommon.Builder(ObjcCommon.Purpose.LINK_ONLY, ruleContext) .setCompilationAttributes( CompilationAttributes.Builder.fromRuleContext(ruleContext).build()) .addDeps(ruleContext.getPrerequisiteConfiguredTargetAndTargets("deps", Mode.TARGET)) .addDeps(ruleContext.getPrerequisiteConfiguredTargetAndTargets("jre_deps", Mode.TARGET)) + .addDepCcHeaderProviders( + j2objcCcInfos.stream().map(J2ObjcCcInfo::getCcInfo).collect(toList())) .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext)) .setHasModuleMap() .build(); @@ -97,6 +104,10 @@ public ConfiguredTarget create(RuleContext ruleContext) .addProvider(J2ObjcEntryClassProvider.class, j2ObjcEntryClassProvider) .addProvider(J2ObjcMappingFileProvider.class, j2ObjcMappingFileProvider) .addNativeDeclaredProvider(objcProvider) + .addNativeDeclaredProvider( + CcInfo.builder() + .setCcCompilationContext(objcProvider.getCcCompilationContext()) + .build()) .addSkylarkTransitiveInfo(ObjcProvider.SKYLARK_NAME, objcProvider) .build(); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java index ee3cd050a2b7c9..0d5c8edb7e4703 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java @@ -81,8 +81,7 @@ private ConfiguredTarget getConfiguredTargetInAppleBinaryTransition(String label return getConfiguredTarget(label, childConfig); } - @Test - public void testJ2ObjCInformationExportedFromJ2ObjcLibrary() throws Exception { + private void testJ2ObjCInformationExportedFromJ2ObjcLibrary() throws Exception { ConfiguredTarget j2objcLibraryTarget = getConfiguredTarget( "//java/com/google/dummy/test:transpile"); ObjcProvider provider = j2objcLibraryTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR); @@ -103,6 +102,22 @@ public void testJ2ObjCInformationExportedFromJ2ObjcLibrary() throws Exception { .containsExactly(execPath + "java/com/google/dummy/test/_j2objc/test"); } + @Test + public void testJ2ObjCInformationExportedFromJ2ObjcLibraryPreMigration() throws Exception { + useConfiguration( + "--proto_toolchain_for_java=//tools/proto/toolchains:java", + "--incompatible_objc_compile_info_migration=false"); + testJ2ObjCInformationExportedFromJ2ObjcLibrary(); + } + + @Test + public void testJ2ObjCInformationExportedFromJ2ObjcLibraryPostMigration() throws Exception { + useConfiguration( + "--proto_toolchain_for_java=//tools/proto/toolchains:java", + "--incompatible_objc_compile_info_migration=true"); + testJ2ObjCInformationExportedFromJ2ObjcLibrary(); + } + @Test public void testJ2ObjCInformationExportedWithGeneratedJavaSources() throws Exception { scratch.file("java/com/google/test/in.txt");