aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java76
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java38
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationArtifacts.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java40
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java76
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java23
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java35
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibraryRule.java20
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoProvider.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java33
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ProtoSupport.java301
14 files changed, 475 insertions, 194 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index 48d31f5c7a..df63b8a78b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -132,6 +132,7 @@ import com.google.devtools.build.lib.rules.objc.ObjcConfigurationLoader;
import com.google.devtools.build.lib.rules.objc.ObjcFrameworkRule;
import com.google.devtools.build.lib.rules.objc.ObjcImportRule;
import com.google.devtools.build.lib.rules.objc.ObjcLibraryRule;
+import com.google.devtools.build.lib.rules.objc.ObjcProtoAspect;
import com.google.devtools.build.lib.rules.objc.ObjcProtoLibraryRule;
import com.google.devtools.build.lib.rules.objc.ObjcProvider;
import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses;
@@ -288,6 +289,7 @@ public class BazelRuleClassProvider {
J2ObjcAspect j2ObjcAspect = new J2ObjcAspect(TOOLS_REPOSITORY, bazelJ2ObjcProtoAspect);
AndroidStudioInfoAspect androidStudioInfoAspect =
new AndroidStudioInfoAspect(TOOLS_REPOSITORY, new BazelAndroidStudioInfoSemantics());
+ ObjcProtoAspect objcProtoAspect = new ObjcProtoAspect();
builder.addNativeAspectClass(androidNeverlinkAspect);
builder.addNativeAspectClass(dexArchiveAspect);
@@ -295,6 +297,7 @@ public class BazelRuleClassProvider {
builder.addNativeAspectClass(bazelJ2ObjcProtoAspect);
builder.addNativeAspectClass(j2ObjcAspect);
builder.addNativeAspectClass(androidStudioInfoAspect);
+ builder.addNativeAspectClass(objcProtoAspect);
builder.addRuleDefinition(new WorkspaceBaseRule());
@@ -397,7 +400,7 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new ObjcRuleClasses.ReleaseBundlingRule());
builder.addRuleDefinition(new ObjcRuleClasses.SimulatorRule());
builder.addRuleDefinition(new ObjcRuleClasses.CompilingRule());
- builder.addRuleDefinition(new ObjcRuleClasses.LinkingRule());
+ builder.addRuleDefinition(new ObjcRuleClasses.LinkingRule(objcProtoAspect));
builder.addRuleDefinition(new ObjcRuleClasses.ResourcesRule());
builder.addRuleDefinition(new ObjcRuleClasses.XcodegenRule());
builder.addRuleDefinition(new ObjcRuleClasses.AlwaysLinkRule());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
index 0e4cb61c1a..690207b3ab 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
@@ -39,6 +39,8 @@ import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider;
import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes;
+import com.google.devtools.build.lib.rules.objc.ProtoSupport.TargetType;
+import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.List;
import java.util.Set;
@@ -47,7 +49,7 @@ import java.util.Set;
* Implementation for the "apple_binary" rule.
*/
public class AppleBinary implements RuleConfiguredTargetFactory {
-
+
/**
* {@link SplitTransitionProvider} instance for the apple binary rule. (This is exposed for
* convenience as a single static instance as it possesses no internal state.)
@@ -67,9 +69,9 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
ObjcProvider.class);
ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap =
ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT);
-
+
Set<BuildConfiguration> childConfigurations = getChildConfigurations(ruleContext);
-
+
IntermediateArtifacts ruleIntermediateArtifacts =
ObjcRuleClasses.intermediateArtifacts(ruleContext);
@@ -80,7 +82,7 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
NestedSetBuilder<Artifact> filesToBuild =
NestedSetBuilder.<Artifact>stableOrder()
.add(ruleIntermediateArtifacts.combinedArchitectureBinary());
-
+
for (BuildConfiguration childConfig : childConfigurations) {
IntermediateArtifacts intermediateArtifacts =
ObjcRuleClasses.intermediateArtifacts(ruleContext, childConfig);
@@ -90,7 +92,7 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
ImmutableList.Builder<J2ObjcMappingFileProvider> j2ObjcMappingFileProviders =
ImmutableList.builder();
J2ObjcEntryClassProvider.Builder j2ObjcEntryClassProviderBuilder =
- new J2ObjcEntryClassProvider.Builder();
+ new J2ObjcEntryClassProvider.Builder();
for (TransitiveInfoCollection dep : configToDepsCollectionMap.get(childConfig)) {
if (dep.getProvider(J2ObjcMappingFileProvider.class) != null) {
j2ObjcMappingFileProviders.add(dep.getProvider(J2ObjcMappingFileProvider.class));
@@ -103,18 +105,32 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
J2ObjcMappingFileProvider j2ObjcMappingFileProvider =
J2ObjcMappingFileProvider.union(j2ObjcMappingFileProviders.build());
J2ObjcEntryClassProvider j2ObjcEntryClassProvider = j2ObjcEntryClassProviderBuilder.build();
-
+
if (!common.getCompilationArtifacts().get().getArchive().isPresent()) {
ruleContext.throwWithRuleError(REQUIRES_AT_LEAST_ONE_SOURCE_FILE);
}
archivesToLipo.add(common.getCompilationArtifacts().get().getArchive().get());
binariesToLipo.add(intermediateArtifacts.strippedSingleArchitectureBinary());
+
+ ProtoSupport protoSupport = new ProtoSupport(ruleContext, TargetType.LINKING_TARGET);
+ Iterable<PathFragment> priorityHeaders;
+ ObjcConfiguration objcConfiguration = childConfig.getFragment(ObjcConfiguration.class);
+ if (objcConfiguration.experimentalAutoTopLevelUnionObjCProtos()) {
+ protoSupport.registerActions();
+ priorityHeaders = protoSupport.getUserHeaderSearchPaths();
+ } else {
+ priorityHeaders = ImmutableList.of();
+ }
+
new CompilationSupport(ruleContext, childConfig)
- .registerCompileAndArchiveActions(common)
+ .registerCompileAndArchiveActions(common, priorityHeaders)
.registerLinkActions(
- common.getObjcProvider(), j2ObjcMappingFileProvider, j2ObjcEntryClassProvider,
- new ExtraLinkArgs(), ImmutableList.<Artifact>of(),
+ common.getObjcProvider(),
+ j2ObjcMappingFileProvider,
+ j2ObjcEntryClassProvider,
+ new ExtraLinkArgs(),
+ ImmutableList.<Artifact>of(),
DsymOutputType.APP)
.validateAttributes();
ruleContext.assertNoErrors();
@@ -146,26 +162,38 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
CompilationArtifacts compilationArtifacts =
CompilationSupport.compilationArtifacts(ruleContext, intermediateArtifacts);
+ ObjcConfiguration objcConfiguration = buildConfiguration.getFragment(ObjcConfiguration.class);
+ if (objcConfiguration.experimentalAutoTopLevelUnionObjCProtos()) {
+ ProtoSupport protoSupport = new ProtoSupport(ruleContext, TargetType.LINKING_TARGET);
+ compilationArtifacts =
+ new CompilationArtifacts.Builder()
+ .setPchFile(compilationArtifacts.getPchFile())
+ .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
+ .addAllSources(compilationArtifacts)
+ .addAllSources(protoSupport.getCompilationArtifacts())
+ .build();
+ }
+
return new ObjcCommon.Builder(ruleContext, buildConfiguration)
- .setCompilationAttributes(new CompilationAttributes(ruleContext))
- .setResourceAttributes(new ResourceAttributes(ruleContext))
- .setCompilationArtifacts(compilationArtifacts)
- .addDefines(ruleContext.getTokenizedStringListAttr("defines"))
- .addDeps(propagatedDeps)
- .addDepObjcProviders(
- ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
- .addNonPropagatedDepObjcProviders(nonPropagatedObjcDeps)
- .setIntermediateArtifacts(intermediateArtifacts)
- .setAlwayslink(false)
- .setHasModuleMap()
- .setLinkedBinary(intermediateArtifacts.strippedSingleArchitectureBinary())
- .build();
+ .setCompilationAttributes(new CompilationAttributes(ruleContext))
+ .setCompilationArtifacts(compilationArtifacts)
+ .setResourceAttributes(new ResourceAttributes(ruleContext))
+ .addDefines(ruleContext.getTokenizedStringListAttr("defines"))
+ .addDeps(propagatedDeps)
+ .addDepObjcProviders(
+ ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
+ .addNonPropagatedDepObjcProviders(nonPropagatedObjcDeps)
+ .setIntermediateArtifacts(intermediateArtifacts)
+ .setAlwayslink(false)
+ .setHasModuleMap()
+ .setLinkedBinary(intermediateArtifacts.strippedSingleArchitectureBinary())
+ .build();
}
private <T> List<T> nullToEmptyList(List<T> inputList) {
return inputList != null ? inputList : ImmutableList.<T>of();
}
-
+
private Set<BuildConfiguration> getChildConfigurations(RuleContext ruleContext) {
// This is currently a hack to obtain all child configurations regardless of the attribute
// values of this rule -- this rule does not currently use the actual info provided by
@@ -173,7 +201,7 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
ImmutableListMultimap<BuildConfiguration, CcToolchainProvider> configToProvider =
ruleContext.getPrerequisitesByConfiguration(":cc_toolchain", Mode.SPLIT,
CcToolchainProvider.class);
-
+
return configToProvider.keySet();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
index 66af77d6b9..9a981d5086 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
@@ -35,8 +35,10 @@ import com.google.devtools.build.lib.rules.apple.Platform;
import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes;
+import com.google.devtools.build.lib.rules.objc.ProtoSupport.TargetType;
import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider;
+import com.google.devtools.build.lib.vfs.PathFragment;
/**
* Implementation for rules that link binaries.
@@ -79,10 +81,21 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
ObjcProvider objcProvider = common.getObjcProvider();
assertLibraryOrSources(objcProvider, ruleContext);
+ XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder();
+
+ ProtoSupport protoSupport = new ProtoSupport(ruleContext, TargetType.LINKING_TARGET);
+ Iterable<PathFragment> priorityHeaders;
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+ if (objcConfiguration.experimentalAutoTopLevelUnionObjCProtos()) {
+ protoSupport.registerActions().addXcodeProviderOptions(xcodeProviderBuilder);
+ priorityHeaders = protoSupport.getUserHeaderSearchPaths();
+ } else {
+ priorityHeaders = ImmutableList.of();
+ }
+
IntermediateArtifacts intermediateArtifacts =
ObjcRuleClasses.intermediateArtifacts(ruleContext);
- XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder();
NestedSetBuilder<Artifact> filesToBuild =
NestedSetBuilder.<Artifact>stableOrder()
.add(intermediateArtifacts.strippedSingleArchitectureBinary());
@@ -102,11 +115,13 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
CompilationSupport compilationSupport =
new CompilationSupport(ruleContext)
- .registerCompileAndArchiveActions(common)
+ .registerCompileAndArchiveActions(common, priorityHeaders)
.registerFullyLinkAction(common.getObjcProvider())
.addXcodeSettings(xcodeProviderBuilder, common)
.registerLinkActions(
- objcProvider, j2ObjcMappingFileProvider, j2ObjcEntryClassProvider,
+ objcProvider,
+ j2ObjcMappingFileProvider,
+ j2ObjcEntryClassProvider,
getExtraLinkArgs(ruleContext),
ImmutableList.<Artifact>of(),
DsymOutputType.APP)
@@ -116,7 +131,6 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
Optional<RunfilesSupport> maybeRunfilesSupport = Optional.absent();
switch (hasReleaseBundlingSupport) {
case YES:
- ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
// TODO(bazel-team): Remove once all bundle users are migrated to ios_application.
ReleaseBundlingSupport releaseBundlingSupport =
@@ -198,15 +212,25 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
CompilationArtifacts compilationArtifacts =
CompilationSupport.compilationArtifacts(ruleContext);
+ if (ObjcRuleClasses.objcConfiguration(ruleContext).experimentalAutoTopLevelUnionObjCProtos()) {
+ ProtoSupport protoSupport = new ProtoSupport(ruleContext, TargetType.LINKING_TARGET);
+ compilationArtifacts =
+ new CompilationArtifacts.Builder()
+ .setPchFile(compilationArtifacts.getPchFile())
+ .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
+ .addAllSources(compilationArtifacts)
+ .addAllSources(protoSupport.getCompilationArtifacts())
+ .build();
+ }
+
ObjcCommon.Builder builder =
new ObjcCommon.Builder(ruleContext)
.setCompilationAttributes(new CompilationAttributes(ruleContext))
- .setResourceAttributes(new ResourceAttributes(ruleContext))
.setCompilationArtifacts(compilationArtifacts)
+ .setResourceAttributes(new ResourceAttributes(ruleContext))
.addDefines(ruleContext.getTokenizedStringListAttr("defines"))
.addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET))
- .addDepObjcProviders(
- ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
+ .addDeps(ruleContext.getPrerequisites("bundles", Mode.TARGET))
.addNonPropagatedDepObjcProviders(
ruleContext.getPrerequisites(
"non_propagated_deps", Mode.TARGET, ObjcProvider.class))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationArtifacts.java
index 326a208301..099541ab07 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationArtifacts.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationArtifacts.java
@@ -72,7 +72,7 @@ final class CompilationArtifacts {
this.precompiledSrcs = Iterables.concat(this.precompiledSrcs, precompiledSrcs);
return this;
}
-
+
Builder setPchFile(Optional<Artifact> pchFile) {
Preconditions.checkState(this.pchFile == null,
"pchFile is already set to: %s", this.pchFile);
@@ -87,6 +87,14 @@ final class CompilationArtifacts {
return this;
}
+ Builder addAllSources(CompilationArtifacts otherArtifacts) {
+ return this.addNonArcSrcs(otherArtifacts.getNonArcSrcs())
+ .addSrcs(otherArtifacts.getSrcs())
+ .addPrecompiledSrcs(otherArtifacts.getPrecompiledSrcs())
+ .addPrivateHdrs(otherArtifacts.getPrivateHdrs())
+ .addAdditionalHdrs(otherArtifacts.getAdditionalHdrs());
+ }
+
CompilationArtifacts build() {
Optional<Artifact> archive = Optional.absent();
if (!Iterables.isEmpty(srcs)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
index 3fff5d53bd..919bdc8713 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
@@ -305,7 +305,33 @@ public final class CompilationSupport {
* @return this compilation support
*/
CompilationSupport registerCompileAndArchiveActions(ObjcCommon common) {
- return registerCompileAndArchiveActions(common, ExtraCompileArgs.NONE);
+ return registerCompileAndArchiveActions(
+ common, ExtraCompileArgs.NONE, ImmutableList.<PathFragment>of());
+ }
+
+ /**
+ * Registers all actions necessary to compile this rule's sources and archive them.
+ *
+ * @param common common information about this rule and its dependencies
+ * @param priorityHeaders priority headers to be included before the dependency headers
+ * @return this compilation support
+ */
+ CompilationSupport registerCompileAndArchiveActions(
+ ObjcCommon common, Iterable<PathFragment> priorityHeaders) {
+ return registerCompileAndArchiveActions(common, ExtraCompileArgs.NONE, priorityHeaders);
+ }
+
+ /**
+ * Registers all actions necessary to compile this rule's sources and archive them.
+ *
+ * @param common common information about this rule and its dependencies
+ * @param extraCompileArgs args to be added to compile actions
+ * @return this compilation support
+ */
+ CompilationSupport registerCompileAndArchiveActions(
+ ObjcCommon common, ExtraCompileArgs extraCompileArgs) {
+ return registerCompileAndArchiveActions(
+ common, extraCompileArgs, ImmutableList.<PathFragment>of());
}
/**
@@ -313,11 +339,13 @@ public final class CompilationSupport {
*
* @param common common information about this rule and its dependencies
* @param extraCompileArgs args to be added to compile actions
+ * @param priorityHeaders priority headers to be included before the dependency headers
* @return this compilation support
*/
CompilationSupport registerCompileAndArchiveActions(
ObjcCommon common,
- ExtraCompileArgs extraCompileArgs) {
+ ExtraCompileArgs extraCompileArgs,
+ Iterable<PathFragment> priorityHeaders) {
if (common.getCompilationArtifacts().isPresent()) {
registerGenerateModuleMapAction(common.getCompilationArtifacts());
Optional<CppModuleMap> moduleMap;
@@ -330,6 +358,7 @@ public final class CompilationSupport {
common.getCompilationArtifacts().get(),
common.getObjcProvider(),
extraCompileArgs,
+ priorityHeaders,
moduleMap,
buildConfiguration.isCodeCoverageEnabled());
}
@@ -344,6 +373,7 @@ public final class CompilationSupport {
CompilationArtifacts compilationArtifacts,
ObjcProvider objcProvider,
ExtraCompileArgs extraCompileArgs,
+ Iterable<PathFragment> priorityHeaders,
Optional<CppModuleMap> moduleMap,
boolean isCodeCoverageEnabled) {
ImmutableList.Builder<Artifact> objFiles = new ImmutableList.Builder<>();
@@ -357,6 +387,7 @@ public final class CompilationSupport {
sourceFile,
objFile,
objcProvider,
+ priorityHeaders,
moduleMap,
compilationArtifacts,
Iterables.concat(extraCompileArgs, ImmutableList.of("-fobjc-arc")),
@@ -370,6 +401,7 @@ public final class CompilationSupport {
nonArcSourceFile,
objFile,
objcProvider,
+ priorityHeaders,
moduleMap,
compilationArtifacts,
Iterables.concat(extraCompileArgs, ImmutableList.of("-fno-objc-arc")),
@@ -377,7 +409,7 @@ public final class CompilationSupport {
}
objFiles.addAll(compilationArtifacts.getPrecompiledSrcs());
-
+
if (compilationArtifacts.hasSwiftSources()) {
registerSwiftModuleMergeAction(compilationArtifacts, objcProvider);
}
@@ -411,6 +443,7 @@ public final class CompilationSupport {
Artifact sourceFile,
Artifact objFile,
ObjcProvider objcProvider,
+ Iterable<PathFragment> priorityHeaders,
Optional<CppModuleMap> moduleMap,
CompilationArtifacts compilationArtifacts,
Iterable<String> otherFlags,
@@ -448,6 +481,7 @@ public final class CompilationSupport {
.add(objcConfiguration.getCoptsForCompilationMode())
.addBeforeEachPath("-iquote", ObjcCommon.userHeaderSearchPaths(buildConfiguration))
.addBeforeEachExecPath("-include", compilationArtifacts.getPchFile().asSet())
+ .addBeforeEachPath("-I", priorityHeaders)
.addBeforeEachPath("-I", objcProvider.get(INCLUDE))
.addBeforeEachPath("-isystem", objcProvider.get(INCLUDE_SYSTEM))
.add(otherFlags)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
index 062eaed308..b4e7c855bb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
@@ -35,13 +35,14 @@ import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
+import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
+import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes;
+import com.google.devtools.build.lib.rules.objc.ProtoSupport.TargetType;
import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary;
import com.google.devtools.build.lib.rules.test.ExecutionInfoProvider;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider;
import com.google.devtools.build.lib.syntax.Type;
-
-import java.util.ArrayList;
-import java.util.List;
+import com.google.devtools.build.lib.vfs.PathFragment;
/**
* Implementation for {@code ios_test} rule in Bazel.
@@ -99,6 +100,16 @@ public final class IosTest implements RuleConfiguredTargetFactory {
NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
addResourceFilesToBuild(ruleContext, common.getObjcProvider(), filesToBuild);
+ ProtoSupport protoSupport = new ProtoSupport(ruleContext, TargetType.LINKING_TARGET);
+ Iterable<PathFragment> priorityHeaders;
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+ if (objcConfiguration.experimentalAutoTopLevelUnionObjCProtos()) {
+ protoSupport.registerActions().addXcodeProviderOptions(xcodeProviderBuilder);
+ priorityHeaders = protoSupport.getUserHeaderSearchPaths();
+ } else {
+ priorityHeaders = ImmutableList.of();
+ }
+
XcodeProductType productType = getProductType(ruleContext);
ExtraLinkArgs extraLinkArgs;
Iterable<Artifact> extraLinkInputs;
@@ -131,7 +142,7 @@ public final class IosTest implements RuleConfiguredTargetFactory {
filesToBuild.add(testApp.getIpa());
}
-
+
J2ObjcMappingFileProvider j2ObjcMappingFileProvider = J2ObjcMappingFileProvider.union(
ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcMappingFileProvider.class));
J2ObjcEntryClassProvider j2ObjcEntryClassProvider = new J2ObjcEntryClassProvider.Builder()
@@ -141,14 +152,17 @@ public final class IosTest implements RuleConfiguredTargetFactory {
new CompilationSupport(ruleContext)
.registerLinkActions(
- common.getObjcProvider(), j2ObjcMappingFileProvider, j2ObjcEntryClassProvider,
- extraLinkArgs, extraLinkInputs, DsymOutputType.TEST)
- .registerCompileAndArchiveActions(common)
+ common.getObjcProvider(),
+ j2ObjcMappingFileProvider,
+ j2ObjcEntryClassProvider,
+ extraLinkArgs,
+ extraLinkInputs,
+ DsymOutputType.TEST)
+ .registerCompileAndArchiveActions(common, priorityHeaders)
.registerFullyLinkAction(common.getObjcProvider())
.addXcodeSettings(xcodeProviderBuilder, common)
.validateAttributes();
- ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
new ReleaseBundlingSupport(
ruleContext,
common.getObjcProvider(),
@@ -232,23 +246,53 @@ public final class IosTest implements RuleConfiguredTargetFactory {
}
}
+ /**
+ * Constructs an {@link ObjcCommon} instance based on the attributes.
+ */
private ObjcCommon common(RuleContext ruleContext) {
- ImmutableList<SdkFramework> extraSdkFrameworks = isXcTest(ruleContext)
- ? AUTOMATIC_SDK_FRAMEWORKS_FOR_XCTEST : ImmutableList.<SdkFramework>of();
- List<ObjcProvider> extraDepObjcProviders = new ArrayList<>();
+ CompilationArtifacts compilationArtifacts =
+ CompilationSupport.compilationArtifacts(ruleContext);
+
+ if (ObjcRuleClasses.objcConfiguration(ruleContext).experimentalAutoTopLevelUnionObjCProtos()) {
+ ProtoSupport protoSupport = new ProtoSupport(ruleContext, TargetType.LINKING_TARGET);
+ compilationArtifacts =
+ new CompilationArtifacts.Builder()
+ .setPchFile(compilationArtifacts.getPchFile())
+ .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
+ .addAllSources(compilationArtifacts)
+ .addAllSources(protoSupport.getCompilationArtifacts())
+ .build();
+ }
+
+ ObjcCommon.Builder builder =
+ new ObjcCommon.Builder(ruleContext)
+ .setCompilationAttributes(new CompilationAttributes(ruleContext))
+ .setCompilationArtifacts(compilationArtifacts)
+ .setResourceAttributes(new ResourceAttributes(ruleContext))
+ .addDefines(ruleContext.getTokenizedStringListAttr("defines"))
+ .addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET))
+ .addDeps(ruleContext.getPrerequisites("bundles", Mode.TARGET))
+ .addNonPropagatedDepObjcProviders(
+ ruleContext.getPrerequisites(
+ "non_propagated_deps", Mode.TARGET, ObjcProvider.class))
+ .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
+ .setHasModuleMap();
+
if (isXcTest(ruleContext)) {
- extraDepObjcProviders.add(xcTestAppProvider(ruleContext).getObjcProvider());
+ builder
+ .addExtraSdkFrameworks(AUTOMATIC_SDK_FRAMEWORKS_FOR_XCTEST)
+ .addDepObjcProviders(ImmutableList.of(xcTestAppProvider(ruleContext).getObjcProvider()));
}
// Add the memleaks library if the --ios_memleaks flag is true. The library pauses the test
// after all tests have been executed so that leaks can be run.
ObjcConfiguration config = ruleContext.getFragment(ObjcConfiguration.class);
if (config.runMemleaks()) {
- extraDepObjcProviders
- .add(ruleContext.getPrerequisite(MEMLEAKS_DEP_ATTR, Mode.TARGET, ObjcProvider.class));
+ builder.addDepObjcProviders(
+ ruleContext.getPrerequisites(MEMLEAKS_DEP_ATTR, Mode.TARGET, ObjcProvider.class));
}
- return ObjcLibrary.common(ruleContext, extraSdkFrameworks, /*alwayslink=*/false,
- extraDepObjcProviders);
+
+ return builder.build();
}
protected static boolean isXcTest(RuleContext ruleContext) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
index 12f69defd7..4292f4a9b0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
@@ -18,7 +18,6 @@ import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTran
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
-import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule;
import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
@@ -37,6 +36,7 @@ import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
+import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.FileType;
@@ -182,7 +182,6 @@ public class IosTestRule implements RuleDefinition {
.ancestors(
BaseRuleClasses.BaseRule.class,
BaseRuleClasses.TestBaseRule.class,
- ObjcRuleClasses.CompilingRule.class,
ObjcRuleClasses.ReleaseBundlingRule.class,
ObjcRuleClasses.LinkingRule.class,
ObjcRuleClasses.XcodegenRule.class,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
index 6d4f47552f..7cf1fcf323 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java
@@ -193,6 +193,7 @@ public class ObjcCommandLineOptions extends FragmentOptions {
)
public Label extraEntitlements;
+ // TODO(b/28451644): Make this option the default behavior.
@Option(
name = "experimental_auto_top_level_union_objc_protos",
defaultValue = "false",
@@ -212,7 +213,7 @@ public class ObjcCommandLineOptions extends FragmentOptions {
+ "when signing."
)
public boolean deviceDebugEntitlements;
-
+
@VisibleForTesting static final String DEFAULT_MINIMUM_IOS = "7.0";
@SuppressWarnings("unchecked")
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
index 41a0201586..b7a3faa9ae 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
@@ -16,7 +16,6 @@ package com.google.devtools.build.lib.rules.objc;
import static com.google.devtools.build.lib.rules.objc.XcodeProductType.LIBRARY_STATIC;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
@@ -68,41 +67,29 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory {
}
/**
- * Constructs an {@link ObjcCommon} instance based on the attributes of the given rule. The rule
- * should inherit from {@link ObjcLibraryRule}..
+ * Constructs an {@link ObjcCommon} instance based on the attributes of the given rule context.
*/
- static ObjcCommon common(RuleContext ruleContext, Iterable<SdkFramework> extraSdkFrameworks,
- boolean alwayslink, Iterable<ObjcProvider> extraDepObjcProviders) {
- CompilationArtifacts compilationArtifacts =
- CompilationSupport.compilationArtifacts(ruleContext);
-
+ private ObjcCommon common(RuleContext ruleContext) {
return new ObjcCommon.Builder(ruleContext)
.setCompilationAttributes(new CompilationAttributes(ruleContext))
.setResourceAttributes(new ResourceAttributes(ruleContext))
- .addExtraSdkFrameworks(extraSdkFrameworks)
.addDefines(ruleContext.getTokenizedStringListAttr("defines"))
- .setCompilationArtifacts(compilationArtifacts)
+ .setCompilationArtifacts(CompilationSupport.compilationArtifacts(ruleContext))
.addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET))
.addDepObjcProviders(
ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
.addNonPropagatedDepObjcProviders(
ruleContext.getPrerequisites("non_propagated_deps", Mode.TARGET, ObjcProvider.class))
.setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
- .setAlwayslink(alwayslink)
+ .setAlwayslink(ruleContext.attributes().get("alwayslink", Type.BOOLEAN))
.setHasModuleMap()
- .addDepObjcProviders(extraDepObjcProviders)
.build();
}
@Override
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException {
- final ObjcCommon common =
- common(
- ruleContext,
- ImmutableList.<SdkFramework>of(),
- ruleContext.attributes().get("alwayslink", Type.BOOLEAN),
- ImmutableList.<ObjcProvider>of());
+ ObjcCommon common = common(ruleContext);
XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder();
NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder()
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
index a6ec22d9f1..79cfb1d20c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
@@ -23,6 +23,7 @@ import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.objc.ProtoSupport.TargetType;
/**
* Implementation for the "objc_proto_library" rule.
@@ -31,18 +32,17 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory {
@Override
public ConfiguredTarget create(final RuleContext ruleContext)
throws InterruptedException, RuleErrorException {
- ProtoSupport protoSupport = new ProtoSupport(ruleContext);
-
ObjcCommon.Builder commonBuilder = new ObjcCommon.Builder(ruleContext);
XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder();
NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
- protoSupport
- .validate()
- .addCommonOptions(commonBuilder)
- .addXcodeProviderOptions(xcodeProviderBuilder)
- .addFilesToBuild(filesToBuild)
- .registerActions();
+ ProtoSupport protoSupport =
+ new ProtoSupport(ruleContext, TargetType.PROTO_TARGET)
+ .validate()
+ .addCommonOptions(commonBuilder)
+ .addXcodeProviderOptions(xcodeProviderBuilder)
+ .addFilesToBuild(filesToBuild)
+ .registerActions();
if (ruleContext.hasErrors()) {
return null;
@@ -52,17 +52,26 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory {
filesToBuild.addAll(common.getCompiledArchive().asSet());
- new CompilationSupport(ruleContext)
- .registerCompileAndArchiveActions(commonBuilder.build())
- .registerFullyLinkAction(common.getObjcProvider());
-
new XcodeSupport(ruleContext)
.addFilesToBuild(filesToBuild)
.addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), LIBRARY_STATIC)
.addDependencies(
- xcodeProviderBuilder, new Attribute(ObjcProtoLibraryRule.PROTO_LIB_ATTR, Mode.TARGET))
+ xcodeProviderBuilder, new Attribute(ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET))
.registerActions(xcodeProviderBuilder.build());
+ boolean usesProtobufLibrary = protoSupport.usesProtobufLibrary();
+
+ boolean experimentalAutoUnion =
+ ObjcRuleClasses.objcConfiguration(ruleContext).experimentalAutoTopLevelUnionObjCProtos();
+
+ // If the experimental flag is not set, or if it's set and doesn't use the protobuf library,
+ // register the compilation actions, as the output needs to be linked in the final binary.
+ if (!experimentalAutoUnion || !usesProtobufLibrary) {
+ new CompilationSupport(ruleContext)
+ .registerCompileAndArchiveActions(common)
+ .registerFullyLinkAction(common.getObjcProvider());
+ }
+
return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
.addProvider(XcodeProvider.class, xcodeProviderBuilder.build())
.addProvider(ObjcProvider.class, common.getObjcProvider())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibraryRule.java
index 2cb9f9cafc..c8b62fe7ad 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibraryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibraryRule.java
@@ -14,16 +14,20 @@
package com.google.devtools.build.lib.rules.objc;
-import static com.google.devtools.build.lib.packages.Attribute.ComputedDefault;
import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
+import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.PROTOBUF_WELL_KNOWN_TYPES;
+import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.PROTO_COMPILER_ATTR;
+import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.PROTO_COMPILER_SUPPORT_ATTR;
+import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.PROTO_LIB_ATTR;
import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.packages.Attribute.ComputedDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
@@ -43,10 +47,6 @@ public class ObjcProtoLibraryRule implements RuleDefinition {
static final String PER_PROTO_INCLUDES_ATTR = "per_proto_includes";
static final String PORTABLE_PROTO_FILTERS_ATTR = "portable_proto_filters";
- static final String PROTO_COMPILER_ATTR = "$googlemac_proto_compiler";
- static final String PROTO_COMPILER_SUPPORT_ATTR = "$googlemac_proto_compiler_support";
- static final String PROTO_LIB_ATTR = "$lib_protobuf";
- static final String PROTOBUF_WELL_KNOWN_TYPES = "$protobuf_well_known_types";
static final String XCODE_GEN_ATTR = "$xcodegen";
@Override
@@ -123,7 +123,7 @@ public class ObjcProtoLibraryRule implements RuleDefinition {
@Override
public Object getDefault(AttributeMap rule) {
if (rule.isAttributeValueExplicitlySpecified(PORTABLE_PROTO_FILTERS_ATTR)) {
- return env.getLabel("//external:objc_protobuf_lib");
+ return env.getToolsLabel("//tools/objc:objc_protobuf_lib");
} else {
return rule.get(OUTPUT_CPP_ATTR, Type.BOOLEAN)
? env.getLabel("//external:objc_proto_cpp_lib")
@@ -132,15 +132,9 @@ public class ObjcProtoLibraryRule implements RuleDefinition {
}
}))
.add(
- // The well known type proto label should resolve to the shared location of proto
- // dependencies of targets in the workspace. Unless all dependencies refer to the same
- // label for these proto dependencies, an artifact comparison between them is not
- // possible. Ultimately, we will need to resolve this cross-repository dependency, but,
- // for now, these well-known protos do not exist in a common repository, and must thus
- // be present in the root workspace.
attr(PROTOBUF_WELL_KNOWN_TYPES, LABEL)
.cfg(HOST)
- .value(env.getLabel("//tools/objc:protobuf_well_known_types")))
+ .value(env.getToolsLabel("//tools/objc:protobuf_well_known_types")))
.add(
attr(XCODE_GEN_ATTR, LABEL)
.cfg(HOST)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoProvider.java
index d1ed2b9aea..6692988a82 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoProvider.java
@@ -55,7 +55,7 @@ public class ObjcProtoProvider implements TransitiveInfoProvider {
* several transitive dependencies.
*/
public static final class Builder {
- private final NestedSetBuilder<Artifact> protoSources = NestedSetBuilder.linkOrder();
+ private final NestedSetBuilder<Artifact> protoSources = NestedSetBuilder.naiveLinkOrder();
private final NestedSetBuilder<Artifact> portableProtoFilters = NestedSetBuilder.linkOrder();
/**
@@ -69,8 +69,8 @@ public class ObjcProtoProvider implements TransitiveInfoProvider {
/**
* Adds all the proto filters to the set of dependencies.
*/
- public Builder addPortableProtoFilters(Iterable<Artifact> protoFilters) {
- this.portableProtoFilters.addAll(protoFilters);
+ public Builder addPortableProtoFilters(NestedSet<Artifact> protoFilters) {
+ this.portableProtoFilters.addTransitive(protoFilters);
return this;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
index 48981fbbe0..4c089de70c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
@@ -808,9 +808,24 @@ public class ObjcRuleClasses {
}
/**
+ * Protocol buffer related implicit attributes.
+ */
+ static final String PROTO_COMPILER_ATTR = "$googlemac_proto_compiler";
+ static final String PROTO_COMPILER_SUPPORT_ATTR = "$googlemac_proto_compiler_support";
+ static final String PROTO_LIB_ATTR = "$lib_protobuf";
+ static final String PROTOBUF_WELL_KNOWN_TYPES = "$protobuf_well_known_types";
+
+ /**
* Common attributes for {@code objc_*} rules that link sources and dependencies.
*/
public static class LinkingRule implements RuleDefinition {
+
+ private final ObjcProtoAspect objcProtoAspect;
+
+ public LinkingRule(ObjcProtoAspect objcProtoAspect) {
+ this.objcProtoAspect = objcProtoAspect;
+ }
+
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
return builder
@@ -827,8 +842,24 @@ public class ObjcRuleClasses {
.singleArtifact()
.value(env.getToolsLabel("//tools/objc:j2objc_dead_code_pruner")))
.add(attr("$dummy_lib", LABEL).value(env.getToolsLabel("//tools/objc:dummy_lib")))
+ .add(
+ attr(PROTO_COMPILER_ATTR, LABEL)
+ .allowedFileTypes(FileType.of(".py"))
+ .cfg(HOST)
+ .singleArtifact()
+ .value(env.getToolsLabel("//tools/objc:protobuf_compiler")))
+ .add(
+ attr(PROTO_COMPILER_SUPPORT_ATTR, LABEL)
+ .legacyAllowAnyFileType()
+ .cfg(HOST)
+ .value(env.getToolsLabel("//tools/objc:protobuf_compiler_support")))
+ .add(
+ attr(PROTOBUF_WELL_KNOWN_TYPES, LABEL)
+ .cfg(HOST)
+ .value(env.getToolsLabel("//tools/objc:protobuf_well_known_types")))
+ .override(builder.copy("deps").aspect(objcProtoAspect))
/* <!-- #BLAZE_RULE($objc_linking_rule).ATTRIBUTE(linkopts) -->
- Extra flags to pass to the linker.
+ Extra flags to pass to the linker.
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("linkopts", STRING_LIST))
.build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtoSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtoSupport.java
index 4c2d8d60ad..c6844f9d4d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtoSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtoSupport.java
@@ -16,12 +16,13 @@ package com.google.devtools.build.lib.rules.objc;
import static com.google.common.base.CaseFormat.LOWER_UNDERSCORE;
import static com.google.common.base.CaseFormat.UPPER_CAMEL;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.CharMatcher;
import com.google.common.base.Function;
import com.google.common.base.Optional;
-import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
@@ -59,6 +60,8 @@ import javax.annotation.Nullable;
* <p>Methods on this class can be called in any order without impacting the result.
*/
final class ProtoSupport {
+ private static final PathFragment BAZEL_TOOLS_PREFIX = new PathFragment("external/bazel_tools/");
+
private static final Function<Artifact, PathFragment> PARENT_PATHFRAGMENT =
new Function<Artifact, PathFragment>() {
@Override
@@ -67,6 +70,25 @@ final class ProtoSupport {
}
};
+ /**
+ * Type of target that is generating the protos. There is a distinction because when generating
+ * the protos from an objc_proto_library, the attributes of the rule need to be considered, but
+ * when generating from a linking target (e.g. objc_binary), the attributes don't exist, but the
+ * ObjcProtoProviders need to be checked.
+ */
+ enum TargetType {
+ /**
+ * The generating rule is an objc_proto_library rule.
+ */
+ PROTO_TARGET,
+
+ /**
+ * The generating target is a linking rule, which generates, compiles and links all the protos
+ * in the transitive closure of dependencies.
+ */
+ LINKING_TARGET,
+ }
+
@VisibleForTesting
static final String NO_PROTOS_ERROR =
"no protos to compile - a non-empty deps attribute is required";
@@ -95,15 +117,18 @@ final class ProtoSupport {
private final RuleContext ruleContext;
private final Attributes attributes;
+ private final TargetType targetType;
/**
* Creates a new proto support.
*
* @param ruleContext context this proto library is constructed in
+ * @param targetType the type of target generating the protos
*/
- public ProtoSupport(RuleContext ruleContext) {
+ public ProtoSupport(RuleContext ruleContext, TargetType targetType) {
this.ruleContext = ruleContext;
this.attributes = new Attributes(ruleContext);
+ this.targetType = targetType;
}
/**
@@ -123,7 +148,7 @@ final class ProtoSupport {
ruleContext.ruleError(NO_PROTOS_ERROR);
}
- if (attributes.usesProtobufLibrary()) {
+ if (usesProtobufLibrary()) {
if (attributes.getPortableProtoFilters().isEmpty()) {
ruleContext.ruleError(PORTABLE_PROTO_FILTERS_EMPTY_ERROR);
}
@@ -144,8 +169,8 @@ final class ProtoSupport {
* @return this proto support
*/
public ProtoSupport registerActions() {
- registerProtoInputListFileAction();
- if (!attributes.getProtoFiles().isEmpty()) {
+ if (!Iterables.isEmpty(getProtoSources())) {
+ registerProtoInputListFileAction();
registerGenerateProtoFilesAction();
}
return this;
@@ -155,17 +180,25 @@ final class ProtoSupport {
* Adds required configuration to the ObjcCommon support class for proto compilation.
*
* @param commonBuilder The builder for the ObjcCommon support class.
- * @return this bundle support
+ * @return this proto support
*/
public ProtoSupport addCommonOptions(ObjcCommon.Builder commonBuilder) {
commonBuilder
- .setCompilationArtifacts(getCompilationArtifacts())
- .addUserHeaderSearchPaths(getSearchPathEntries())
.setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
.addDepObjcProviders(
ruleContext.getPrerequisites(
- ObjcProtoLibraryRule.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.class))
+ ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.class))
.setHasModuleMap();
+
+ if (usesProtobufLibrary() && experimentalAutoUnion() && targetType == TargetType.PROTO_TARGET) {
+ commonBuilder
+ .addDirectDependencyHeaderSearchPaths(getUserHeaderSearchPaths())
+ .setCompilationArtifacts(getCompilationArtifacts());
+ } else {
+ commonBuilder
+ .addUserHeaderSearchPaths(getUserHeaderSearchPaths())
+ .setCompilationArtifacts(getCompilationArtifacts());
+ }
return this;
}
@@ -173,11 +206,11 @@ final class ProtoSupport {
* Adds required configuration to the XcodeProvider support class for proto compilation.
*
* @param xcodeProviderBuilder The builder for the XcodeProvider support class.
- * @return this bundle support
+ * @return this proto support
*/
public ProtoSupport addXcodeProviderOptions(XcodeProvider.Builder xcodeProviderBuilder) {
xcodeProviderBuilder
- .addUserHeaderSearchPaths(getSearchPathEntries())
+ .addUserHeaderSearchPaths(getUserHeaderSearchPaths())
.addCopts(ObjcRuleClasses.objcConfiguration(ruleContext).getCopts())
.addHeaders(getGeneratedHeaders())
.setCompilationArtifacts(getCompilationArtifacts());
@@ -188,13 +221,126 @@ final class ProtoSupport {
* Adds the files needed to be built by the rule.
*
* @param filesToBuild An aggregated set of the files to be built by the rule.
- * @return this bundle support
+ * @return this proto support
*/
public ProtoSupport addFilesToBuild(NestedSetBuilder<Artifact> filesToBuild) {
filesToBuild.addAll(getGeneratedSources()).addAll(getGeneratedHeaders());
return this;
}
+ /**
+ * Returns the proto compilation artifacts for the current rule.
+ */
+ public CompilationArtifacts getCompilationArtifacts() {
+ ImmutableList<Artifact> generatedSources = getGeneratedSources();
+ CompilationArtifacts.Builder builder =
+ new CompilationArtifacts.Builder()
+ .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
+ .setPchFile(Optional.<Artifact>absent())
+ .addAdditionalHdrs(getGeneratedHeaders())
+ .addAdditionalHdrs(generatedSources);
+
+ if (experimentalAutoUnion()) {
+ if (targetType == TargetType.PROTO_TARGET && !usesProtobufLibrary()
+ || targetType == TargetType.LINKING_TARGET) {
+ builder.addNonArcSrcs(generatedSources);
+ }
+ } else {
+ if (targetType == TargetType.PROTO_TARGET) {
+ builder.addNonArcSrcs(generatedSources);
+ }
+ }
+
+ return builder.build();
+ }
+
+ /**
+ * Returns the include paths for the generated protos.
+ */
+ public ImmutableSet<PathFragment> getUserHeaderSearchPaths() {
+ PathFragment workspaceRelativeOutputDir = getWorkspaceRelativeOutputDir();
+
+ ImmutableSet.Builder<PathFragment> searchPathEntriesBuilder =
+ new ImmutableSet.Builder<PathFragment>().add(workspaceRelativeOutputDir);
+
+ if (attributes.needsPerProtoIncludes()) {
+ PathFragment generatedProtoDir =
+ new PathFragment(workspaceRelativeOutputDir, ruleContext.getLabel().getPackageFragment());
+
+ searchPathEntriesBuilder
+ .add(generatedProtoDir)
+ .addAll(Iterables.transform(getGeneratedHeaders(), PARENT_PATHFRAGMENT));
+ }
+
+ return searchPathEntriesBuilder.build();
+ }
+
+ /**
+ * Returns whether the rule is configured to use the protobuf library.
+ */
+ public boolean usesProtobufLibrary() {
+ return attributes.hasPortableProtoFilters() || targetType == TargetType.LINKING_TARGET;
+ }
+
+ private Iterable<Artifact> getProtoSources() {
+ NestedSetBuilder<Artifact> protos = NestedSetBuilder.stableOrder();
+
+ if (experimentalAutoUnion() && targetType == TargetType.LINKING_TARGET) {
+ Iterable<ObjcProtoProvider> objcProtoProviders =
+ ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProtoProvider.class);
+ for (ObjcProtoProvider objcProtoProvider : objcProtoProviders) {
+ protos.addTransitive(objcProtoProvider.getProtoSources());
+ }
+ }
+
+ protos.addTransitive(attributes.getProtoFiles());
+
+ // Transform the well known proto artifacts by removing the external/bazel_tools prefix if
+ // present. Otherwise the comparison for filtering out the well known types is not possible.
+ ImmutableSet.Builder<PathFragment> wellKnownProtoPathsBuilder = new ImmutableSet.Builder<>();
+ for (Artifact wellKnownProto : attributes.getWellKnownTypeProtos()) {
+ PathFragment execPath = wellKnownProto.getExecPath();
+ if (execPath.startsWith(BAZEL_TOOLS_PREFIX)) {
+ wellKnownProtoPathsBuilder.add(execPath.relativeTo(BAZEL_TOOLS_PREFIX));
+ } else {
+ wellKnownProtoPathsBuilder.add(execPath);
+ }
+ }
+
+ ImmutableSet<PathFragment> wellKnownProtoPaths = wellKnownProtoPathsBuilder.build();
+
+ // Filter out the well known types from being sent to be generated, as these protos have already
+ // been generated and linked in libprotobuf.a.
+ ImmutableSet.Builder<Artifact> filteredProtos = new ImmutableSet.Builder<>();
+ for (Artifact proto : protos.build()) {
+ if (!wellKnownProtoPaths.contains(proto.getExecPath())) {
+ filteredProtos.add(proto);
+ }
+ }
+
+ return filteredProtos.build();
+ }
+
+ private NestedSet<Artifact> getPortableProtoFilters() {
+ NestedSetBuilder<Artifact> portableProtoFilters = NestedSetBuilder.stableOrder();
+
+ if (experimentalAutoUnion() && targetType == TargetType.LINKING_TARGET) {
+ Iterable<ObjcProtoProvider> objcProtoProviders =
+ ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProtoProvider.class);
+ for (ObjcProtoProvider objcProtoProvider : objcProtoProviders) {
+ portableProtoFilters.addTransitive(objcProtoProvider.getPortableProtoFilters());
+ }
+ }
+
+ portableProtoFilters.addAll(attributes.getPortableProtoFilters());
+ return portableProtoFilters.build();
+ }
+
+ private boolean experimentalAutoUnion() {
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+ return objcConfiguration.experimentalAutoTopLevelUnionObjCProtos();
+ }
+
private void registerProtoInputListFileAction() {
ruleContext.registerAction(
new FileWriteAction(
@@ -215,6 +361,15 @@ final class ProtoSupport {
.build(ruleContext));
}
+ private Artifact getProtoInputListFile() {
+ return ruleContext.getUniqueDirectoryArtifact(
+ "_protos", "_proto_input_files", ruleContext.getConfiguration().getGenfilesDirectory());
+ }
+
+ private String getProtoInputListFileContents() {
+ return Artifact.joinExecPaths("\n", getProtoSources());
+ }
+
private PathFragment getWorkspaceRelativeOutputDir() {
// Generate sources in a package-and-rule-scoped directory; adds both the
// package-and-rule-scoped directory and the header-containing-directory to the include path
@@ -225,19 +380,8 @@ final class ProtoSupport {
ruleContext.getBinOrGenfilesDirectory().getExecPath(), rootRelativeOutputDir);
}
- private CompilationArtifacts getCompilationArtifacts() {
- ImmutableList<Artifact> generatedSources = getGeneratedSources();
- return new CompilationArtifacts.Builder()
- .addNonArcSrcs(generatedSources)
- .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
- .setPchFile(Optional.<Artifact>absent())
- .addAdditionalHdrs(getGeneratedHeaders())
- .addAdditionalHdrs(generatedSources)
- .build();
- }
-
private ImmutableList<Artifact> getGeneratedHeaders() {
- boolean useObjcName = attributes.usesObjcHeaderNames() || attributes.usesProtobufLibrary();
+ boolean useObjcName = attributes.usesObjcHeaderNames() || usesProtobufLibrary();
return generatedOutputArtifacts(FileType.of(".pb" + (useObjcName ? "objc.h" : ".h")));
}
@@ -245,46 +389,18 @@ final class ProtoSupport {
return generatedOutputArtifacts(
FileType.of(
".pb"
- + (attributes.usesProtobufLibrary() ? "objc" : "")
+ + (usesProtobufLibrary() ? "objc" : "")
+ (attributes.outputsCpp() ? ".cc" : ".m")));
}
- private ImmutableSet<PathFragment> getSearchPathEntries() {
- PathFragment workspaceRelativeOutputDir = getWorkspaceRelativeOutputDir();
-
- ImmutableSet.Builder<PathFragment> searchPathEntriesBuilder =
- new ImmutableSet.Builder<PathFragment>().add(workspaceRelativeOutputDir);
-
- if (attributes.needsPerProtoIncludes()) {
- PathFragment generatedProtoDir =
- new PathFragment(workspaceRelativeOutputDir, ruleContext.getLabel().getPackageFragment());
-
- searchPathEntriesBuilder
- .add(generatedProtoDir)
- .addAll(Iterables.transform(getGeneratedHeaders(), PARENT_PATHFRAGMENT));
- }
-
- return searchPathEntriesBuilder.build();
- }
-
- private Artifact getProtoInputListFile() {
- return ruleContext.getUniqueDirectoryArtifact(
- "_protos", "_proto_input_files", ruleContext.getConfiguration().getGenfilesDirectory());
- }
-
- private String getProtoInputListFileContents() {
- return Artifact.joinExecPaths("\n", getFilteredProtos());
- }
-
private NestedSet<Artifact> getGenerateActionInputs() {
NestedSetBuilder<Artifact> inputsBuilder =
NestedSetBuilder.<Artifact>stableOrder()
.add(attributes.getProtoCompiler())
- .addAll(attributes.getProtoFiles())
+ .addAll(getProtoSources())
.add(getProtoInputListFile())
- .addAll(attributes.getProtoLibrary())
.addAll(attributes.getProtoCompilerSupport())
- .addAll(attributes.getPortableProtoFilters());
+ .addAll(getPortableProtoFilters());
Artifact optionsFile = attributes.getOptionsFile();
if (optionsFile != null) {
@@ -299,7 +415,7 @@ final class ProtoSupport {
}
private CustomCommandLine getGenerateCommandLine() {
- if (attributes.usesProtobufLibrary()) {
+ if (usesProtobufLibrary()) {
return getProtobufCommandLine();
} else {
return getPb2CommandLine();
@@ -346,7 +462,7 @@ final class ProtoSupport {
.add(".");
boolean configAdded = false;
- for (Artifact portableProtoFilter : attributes.getPortableProtoFilters()) {
+ for (Artifact portableProtoFilter : getPortableProtoFilters()) {
String configFlag;
if (!configAdded) {
configFlag = "--config";
@@ -362,12 +478,12 @@ final class ProtoSupport {
private ImmutableList<Artifact> generatedOutputArtifacts(FileType newFileType) {
ImmutableList.Builder<Artifact> builder = new ImmutableList.Builder<>();
- for (Artifact protoFile : getFilteredProtos()) {
+ for (Artifact protoFile : getProtoSources()) {
String protoFileName = FileSystemUtils.removeExtension(protoFile.getFilename());
String generatedOutputName;
if (attributes.outputsCpp()) {
generatedOutputName = protoFileName;
- } else if (attributes.usesProtobufLibrary()){
+ } else if (usesProtobufLibrary()) {
// The protobuf library generates filenames with some slight modifications.
generatedOutputName = generateProtobufFilename(protoFileName);
} else {
@@ -457,14 +573,6 @@ final class ProtoSupport {
return casedSegments.toString();
}
- private Iterable<Artifact> getFilteredProtos() {
- // Filter the well known types from being sent to be generated, as these protos have already
- // been generated and linked in libprotobuf.a.
- return Iterables.filter(
- attributes.getProtoFiles(),
- Predicates.not(Predicates.in(attributes.getWellKnownTypeProtos())));
- }
-
/**
* Common rule attributes used by an Objective C proto library.
*/
@@ -479,31 +587,44 @@ final class ProtoSupport {
* Returns whether the generated files should be C++ or Objective C.
*/
boolean outputsCpp() {
- return ruleContext.attributes().get(ObjcProtoLibraryRule.OUTPUT_CPP_ATTR, Type.BOOLEAN);
+ if (ruleContext.attributes().has(ObjcProtoLibraryRule.OUTPUT_CPP_ATTR, Type.BOOLEAN)) {
+ return ruleContext.attributes().get(ObjcProtoLibraryRule.OUTPUT_CPP_ATTR, Type.BOOLEAN);
+ }
+ return false;
}
/**
* Returns whether the generated header files should have be of type pb.h or pbobjc.h.
*/
boolean usesObjcHeaderNames() {
- return ruleContext
+ if (ruleContext
.attributes()
- .get(ObjcProtoLibraryRule.USE_OBJC_HEADER_NAMES_ATTR, Type.BOOLEAN);
+ .has(ObjcProtoLibraryRule.USE_OBJC_HEADER_NAMES_ATTR, Type.BOOLEAN)) {
+ return ruleContext
+ .attributes()
+ .get(ObjcProtoLibraryRule.USE_OBJC_HEADER_NAMES_ATTR, Type.BOOLEAN);
+ }
+ return false;
}
/**
* Returns whether the includes should include each of the proto generated headers.
*/
boolean needsPerProtoIncludes() {
- return ruleContext
+ if (ruleContext
.attributes()
- .get(ObjcProtoLibraryRule.PER_PROTO_INCLUDES_ATTR, Type.BOOLEAN);
+ .has(ObjcProtoLibraryRule.PER_PROTO_INCLUDES_ATTR, Type.BOOLEAN)) {
+ return ruleContext
+ .attributes()
+ .get(ObjcProtoLibraryRule.PER_PROTO_INCLUDES_ATTR, Type.BOOLEAN);
+ }
+ return false;
}
/**
* Returns whether to use the protobuf library instead of the PB2 library.
*/
- boolean usesProtobufLibrary() {
+ boolean hasPortableProtoFilters() {
return ruleContext
.attributes()
.isAttributeValueExplicitlySpecified(ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR);
@@ -513,9 +634,14 @@ final class ProtoSupport {
* Returns the list of portable proto filters.
*/
ImmutableList<Artifact> getPortableProtoFilters() {
- return ruleContext
- .getPrerequisiteArtifacts(ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR, Mode.HOST)
- .list();
+ if (ruleContext
+ .attributes()
+ .has(ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR, LABEL_LIST)) {
+ return ruleContext
+ .getPrerequisiteArtifacts(ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR, Mode.HOST)
+ .list();
+ }
+ return ImmutableList.of();
}
/**
@@ -523,7 +649,7 @@ final class ProtoSupport {
*/
ImmutableList<Artifact> getWellKnownTypeProtos() {
return ruleContext
- .getPrerequisiteArtifacts(ObjcProtoLibraryRule.PROTOBUF_WELL_KNOWN_TYPES, Mode.HOST)
+ .getPrerequisiteArtifacts(ObjcRuleClasses.PROTOBUF_WELL_KNOWN_TYPES, Mode.HOST)
.list();
}
@@ -532,15 +658,18 @@ final class ProtoSupport {
*/
@Nullable
Artifact getOptionsFile() {
- return ruleContext.getPrerequisiteArtifact(ObjcProtoLibraryRule.OPTIONS_FILE_ATTR, Mode.HOST);
+ if (ruleContext.attributes().has(ObjcProtoLibraryRule.OPTIONS_FILE_ATTR, LABEL)) {
+ return ruleContext.getPrerequisiteArtifact(
+ ObjcProtoLibraryRule.OPTIONS_FILE_ATTR, Mode.HOST);
+ }
+ return null;
}
/**
* Returns the proto compiler to be used.
*/
Artifact getProtoCompiler() {
- return ruleContext.getPrerequisiteArtifact(
- ObjcProtoLibraryRule.PROTO_COMPILER_ATTR, Mode.HOST);
+ return ruleContext.getPrerequisiteArtifact(ObjcRuleClasses.PROTO_COMPILER_ATTR, Mode.HOST);
}
/**
@@ -548,17 +677,7 @@ final class ProtoSupport {
*/
ImmutableList<Artifact> getProtoCompilerSupport() {
return ruleContext
- .getPrerequisiteArtifacts(ObjcProtoLibraryRule.PROTO_COMPILER_SUPPORT_ATTR, Mode.HOST)
- .list();
- }
-
- /**
- * Returns the list of files that compose the proto library. This is the implicit dependency
- * added to the objc_proto_library target.
- */
- ImmutableList<Artifact> getProtoLibrary() {
- return ruleContext
- .getPrerequisiteArtifacts(ObjcProtoLibraryRule.PROTO_LIB_ATTR, Mode.TARGET)
+ .getPrerequisiteArtifacts(ObjcRuleClasses.PROTO_COMPILER_SUPPORT_ATTR, Mode.HOST)
.list();
}