aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar Sergio Campama <kaipi@google.com>2016-06-06 15:12:55 +0000
committerGravatar Yun Peng <pcloudy@google.com>2016-06-06 16:42:02 +0000
commit146ecf9883883a97cf9c25b0b8e478fc3e5e2c22 (patch)
treeececc5639768aa48fcb4e9945f5f4fcbfd8e0389 /src/main/java/com/google
parent4f72b2c7afb8d27971ca41142e6c15f4a22ddf16 (diff)
Separates the proto compilation action from the other linking sources, to isolate them from the linking target's defines and copts flags. Refactors CompilationAttributes into its own class with the Builder pattern.
-- MOS_MIGRATED_REVID=124137672
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java59
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java48
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationAttributes.java480
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java83
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java38
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java161
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFrameworkRule.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcSdkFrameworks.java71
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ProtoSupport.java62
14 files changed, 670 insertions, 365 deletions
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 bc26cf74ed..ec64b37603 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
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.rules.objc;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.devtools.build.lib.actions.Artifact;
@@ -37,10 +38,8 @@ import com.google.devtools.build.lib.rules.apple.AppleConfiguration.Configuratio
import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
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;
@@ -113,18 +112,21 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
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();
+ ProtoSupport protoSupport =
+ new ProtoSupport(ruleContext, TargetType.LINKING_TARGET).registerActions();
+
+ ObjcCommon protoCommon = protoSupport.getCommon();
+ new CompilationSupport(
+ ruleContext,
+ protoSupport.getIntermediateArtifacts(),
+ new CompilationAttributes.Builder().build())
+ .registerCompileAndArchiveActions(protoCommon, protoSupport.getUserHeaderSearchPaths());
}
new CompilationSupport(ruleContext, childConfig)
- .registerCompileAndArchiveActions(common, priorityHeaders)
+ .registerCompileAndArchiveActions(common)
.registerLinkActions(
common.getObjcProvider(),
j2ObjcMappingFileProvider,
@@ -162,32 +164,31 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
CompilationArtifacts compilationArtifacts =
CompilationSupport.compilationArtifacts(ruleContext, intermediateArtifacts);
+ Optional<Artifact> protoLib;
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();
+ protoLib = protoSupport.getCommon().getCompiledArchive();
+ } else {
+ protoLib = Optional.absent();
}
return new ObjcCommon.Builder(ruleContext, buildConfiguration)
- .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();
+ .setCompilationAttributes(
+ CompilationAttributes.Builder.fromRuleContext(ruleContext).build())
+ .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())
+ .addExtraImportLibraries(protoLib.asSet())
+ .build();
}
private <T> List<T> nullToEmptyList(List<T> inputList) {
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 9a981d5086..7ee2cc8fb6 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
@@ -33,12 +33,10 @@ import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
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.
@@ -83,16 +81,6 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
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);
@@ -113,9 +101,24 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcEntryClassProvider.class))
.build();
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+ if (objcConfiguration.experimentalAutoTopLevelUnionObjCProtos()) {
+ ProtoSupport protoSupport =
+ new ProtoSupport(ruleContext, TargetType.LINKING_TARGET)
+ .registerActions()
+ .addXcodeProviderOptions(xcodeProviderBuilder);
+
+ ObjcCommon protoCommon = protoSupport.getCommon();
+ new CompilationSupport(
+ ruleContext,
+ protoSupport.getIntermediateArtifacts(),
+ new CompilationAttributes.Builder().build())
+ .registerCompileAndArchiveActions(protoCommon, protoSupport.getUserHeaderSearchPaths());
+ }
+
CompilationSupport compilationSupport =
new CompilationSupport(ruleContext)
- .registerCompileAndArchiveActions(common, priorityHeaders)
+ .registerCompileAndArchiveActions(common)
.registerFullyLinkAction(common.getObjcProvider())
.addXcodeSettings(xcodeProviderBuilder, common)
.registerLinkActions(
@@ -212,20 +215,10 @@ 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))
+ .setCompilationAttributes(
+ CompilationAttributes.Builder.fromRuleContext(ruleContext).build())
.setCompilationArtifacts(compilationArtifacts)
.setResourceAttributes(new ResourceAttributes(ruleContext))
.addDefines(ruleContext.getTokenizedStringListAttr("defines"))
@@ -248,6 +241,11 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
builder.setLinkmapFile(intermediateArtifacts.linkmap());
}
+ if (ObjcRuleClasses.objcConfiguration(ruleContext).experimentalAutoTopLevelUnionObjCProtos()) {
+ ProtoSupport protoSupport = new ProtoSupport(ruleContext, TargetType.LINKING_TARGET);
+ builder.addExtraImportLibraries(protoSupport.getCommon().getCompiledArchive().asSet());
+ }
+
return builder.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationAttributes.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationAttributes.java
new file mode 100644
index 0000000000..f41b101c2f
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationAttributes.java
@@ -0,0 +1,480 @@
+// Copyright 2016 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.rules.objc;
+
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.TOP_LEVEL_MODULE_MAP;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.packages.BuildType;
+import com.google.devtools.build.lib.rules.cpp.CcCommon;
+import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
+import com.google.devtools.build.lib.syntax.Type;
+import com.google.devtools.build.lib.util.Pair;
+import com.google.devtools.build.lib.vfs.PathFragment;
+
+import java.util.List;
+
+/**
+ * Provides a way to access attributes that are common to all compilation rules.
+ */
+// TODO(bazel-team): Delete and move into support-specific attributes classes once ObjcCommon is
+// gone.
+final class CompilationAttributes {
+ static class Builder {
+ private final NestedSetBuilder<Artifact> hdrs = NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<Artifact> textualHdrs = NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<PathFragment> includes = NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<PathFragment> sdkIncludes = NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<String> copts = NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<String> linkopts = NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<CppModuleMap> moduleMapsForDirectDeps =
+ NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<SdkFramework> sdkFrameworks = NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<SdkFramework> weakSdkFrameworks = NestedSetBuilder.stableOrder();
+ private final NestedSetBuilder<String> sdkDylibs = NestedSetBuilder.stableOrder();
+ private Optional<Artifact> bridgingHeader = Optional.absent();
+ private Optional<PathFragment> packageFragment = Optional.absent();
+ private boolean enableModules;
+
+ /**
+ * Adds the default values available through the rule's context.
+ */
+ static Builder fromRuleContext(RuleContext ruleContext) {
+ Builder builder = new Builder();
+
+ addHeadersFromRuleContext(builder, ruleContext);
+ addIncludesFromRuleContext(builder, ruleContext);
+ addSdkAttributesFromRuleContext(builder, ruleContext);
+ addCompileOptionsFromRuleContext(builder, ruleContext);
+ addModuleOptionsFromRuleContext(builder, ruleContext);
+
+ return builder;
+ }
+
+ /**
+ * Adds headers to be made available for dependents.
+ */
+ public Builder addHdrs(NestedSet<Artifact> hdrs) {
+ this.hdrs.addTransitive(hdrs);
+ return this;
+ }
+
+ /**
+ * Adds headers that cannot be compiled individually.
+ */
+ public Builder addTextualHdrs(NestedSet<Artifact> textualHdrs) {
+ this.textualHdrs.addTransitive(textualHdrs);
+ return this;
+ }
+
+ /**
+ * Adds include paths to be made available for compilation.
+ */
+ public Builder addIncludes(NestedSet<PathFragment> includes) {
+ this.includes.addTransitive(includes);
+ return this;
+ }
+
+ /**
+ * Adds paths for SDK includes.
+ */
+ public Builder addSdkIncludes(NestedSet<PathFragment> sdkIncludes) {
+ this.sdkIncludes.addTransitive(sdkIncludes);
+ return this;
+ }
+
+ /**
+ * Adds compile-time options.
+ */
+ public Builder addCopts(NestedSet<String> copts) {
+ this.copts.addTransitive(copts);
+ return this;
+ }
+
+ /**
+ * Adds link-time options.
+ */
+ public Builder addLinkopts(NestedSet<String> linkopts) {
+ this.linkopts.addTransitive(linkopts);
+ return this;
+ }
+
+ /**
+ * Adds clang module maps for direct dependencies of the rule. These are needed to generate
+ * module maps.
+ */
+ public Builder addModuleMapsForDirectDeps(NestedSet<CppModuleMap> moduleMapsForDirectDeps) {
+ this.moduleMapsForDirectDeps.addTransitive(moduleMapsForDirectDeps);
+ return this;
+ }
+
+ /**
+ * Adds SDK frameworks to link against.
+ */
+ public Builder addSdkFrameworks(NestedSet<SdkFramework> sdkFrameworks) {
+ this.sdkFrameworks.addTransitive(sdkFrameworks);
+ return this;
+ }
+
+ /**
+ * Adds SDK frameworks to be linked weakly.
+ */
+ public Builder addWeakSdkFrameworks(NestedSet<SdkFramework> weakSdkFrameworks) {
+ this.weakSdkFrameworks.addTransitive(weakSdkFrameworks);
+ return this;
+ }
+
+ /**
+ * Adds SDK Dylibs to link against.
+ */
+ public Builder addSdkDylibs(NestedSet<String> sdkDylibs) {
+ this.sdkDylibs.addTransitive(sdkDylibs);
+ return this;
+ }
+
+ /**
+ * Sets the bridging header to be used when compiling Swift sources.
+ */
+ public Builder setBridgingHeader(Artifact bridgingHeader) {
+ Preconditions.checkState(
+ !this.bridgingHeader.isPresent(),
+ "bridgingHeader is already set to %s",
+ this.bridgingHeader);
+ this.bridgingHeader = Optional.of(bridgingHeader);
+ return this;
+ }
+
+ /**
+ * Sets the package path from which to base the header search paths.
+ */
+ public Builder setPackageFragment(PathFragment packageFragment) {
+ Preconditions.checkState(
+ !this.packageFragment.isPresent(),
+ "packageFragment is already set to %s",
+ this.packageFragment);
+ this.packageFragment = Optional.of(packageFragment);
+ return this;
+ }
+
+ /**
+ * Enables the usage of clang modules maps during compilation.
+ */
+ public Builder enableModules() {
+ this.enableModules = true;
+ return this;
+ }
+
+ /**
+ * Builds a {@code CompilationAttributes} object.
+ */
+ public CompilationAttributes build() {
+ return new CompilationAttributes(
+ this.hdrs.build(),
+ this.textualHdrs.build(),
+ this.bridgingHeader,
+ this.includes.build(),
+ this.sdkIncludes.build(),
+ this.sdkFrameworks.build(),
+ this.weakSdkFrameworks.build(),
+ this.sdkDylibs.build(),
+ this.packageFragment,
+ this.copts.build(),
+ this.linkopts.build(),
+ this.moduleMapsForDirectDeps.build(),
+ this.enableModules);
+ }
+
+ private static void addHeadersFromRuleContext(Builder builder, RuleContext ruleContext) {
+ if (ruleContext.attributes().has("hdrs", BuildType.LABEL_LIST)) {
+ NestedSetBuilder<Artifact> headers = NestedSetBuilder.stableOrder();
+ for (Pair<Artifact, Label> header : CcCommon.getHeaders(ruleContext)) {
+ headers.add(header.first);
+ }
+ builder.addHdrs(headers.build());
+ }
+
+ if (ruleContext.attributes().has("textual_hdrs", BuildType.LABEL_LIST)) {
+ builder.addTextualHdrs(
+ PrerequisiteArtifacts.nestedSet(ruleContext, "textual_hdrs", Mode.TARGET));
+ }
+
+ if (ruleContext.attributes().has("bridging_header", BuildType.LABEL)) {
+ Artifact header = ruleContext.getPrerequisiteArtifact("bridging_header", Mode.TARGET);
+ if (header != null) {
+ builder.setBridgingHeader(header);
+ }
+ }
+ }
+
+ private static void addIncludesFromRuleContext(Builder builder, RuleContext ruleContext) {
+ if (ruleContext.attributes().has("includes", Type.STRING_LIST)) {
+ NestedSetBuilder<PathFragment> includes = NestedSetBuilder.stableOrder();
+ includes.addAll(
+ Iterables.transform(
+ ruleContext.attributes().get("includes", Type.STRING_LIST),
+ PathFragment.TO_PATH_FRAGMENT));
+ builder.addIncludes(includes.build());
+ }
+
+ if (ruleContext.attributes().has("sdk_includes", Type.STRING_LIST)) {
+ NestedSetBuilder<PathFragment> sdkIncludes = NestedSetBuilder.stableOrder();
+ sdkIncludes.addAll(
+ Iterables.transform(
+ ruleContext.attributes().get("sdk_includes", Type.STRING_LIST),
+ PathFragment.TO_PATH_FRAGMENT));
+ builder.addSdkIncludes(sdkIncludes.build());
+ }
+ }
+
+ private static void addSdkAttributesFromRuleContext(Builder builder, RuleContext ruleContext) {
+ if (ruleContext.attributes().has("sdk_frameworks", Type.STRING_LIST)) {
+ NestedSetBuilder<SdkFramework> frameworks = NestedSetBuilder.stableOrder();
+ // TODO(bazel-team): Move the inclusion of the default frameworks to CompilationSupport.
+ frameworks.addAll(ObjcRuleClasses.AUTOMATIC_SDK_FRAMEWORKS);
+ for (String explicit : ruleContext.attributes().get("sdk_frameworks", Type.STRING_LIST)) {
+ frameworks.add(new SdkFramework(explicit));
+ }
+ builder.addSdkFrameworks(frameworks.build());
+ }
+
+ if (ruleContext.attributes().has("weak_sdk_frameworks", Type.STRING_LIST)) {
+ NestedSetBuilder<SdkFramework> weakFrameworks = NestedSetBuilder.stableOrder();
+ for (String frameworkName :
+ ruleContext.attributes().get("weak_sdk_frameworks", Type.STRING_LIST)) {
+ weakFrameworks.add(new SdkFramework(frameworkName));
+ }
+ builder.addWeakSdkFrameworks(weakFrameworks.build());
+ }
+
+ if (ruleContext.attributes().has("sdk_dylibs", Type.STRING_LIST)) {
+ NestedSetBuilder<String> sdkDylibs = NestedSetBuilder.stableOrder();
+ sdkDylibs.addAll(ruleContext.attributes().get("sdk_dylibs", Type.STRING_LIST));
+ builder.addSdkDylibs(sdkDylibs.build());
+ }
+ }
+
+ private static void addCompileOptionsFromRuleContext(Builder builder, RuleContext ruleContext) {
+ if (ruleContext.attributes().has("copts", Type.STRING_LIST)) {
+ NestedSetBuilder<String> copts = NestedSetBuilder.stableOrder();
+ copts.addAll(ruleContext.getTokenizedStringListAttr("copts"));
+ builder.addCopts(copts.build());
+ }
+
+ if (ruleContext.attributes().has("linkopts", Type.STRING_LIST)) {
+ NestedSetBuilder<String> linkopts = NestedSetBuilder.stableOrder();
+ linkopts.addAll(ruleContext.getTokenizedStringListAttr("linkopts"));
+ builder.addLinkopts(linkopts.build());
+ }
+ }
+
+ private static void addModuleOptionsFromRuleContext(Builder builder, RuleContext ruleContext) {
+ NestedSetBuilder<CppModuleMap> moduleMaps = NestedSetBuilder.stableOrder();
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+ if (objcConfiguration.moduleMapsEnabled()) {
+ // Make sure all dependencies that have headers are included here. If a module map is
+ // missing, its private headers will be treated as public!
+ if (ruleContext.attributes().has("deps", BuildType.LABEL_LIST)) {
+ Iterable<ObjcProvider> providers =
+ ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class);
+ for (ObjcProvider provider : providers) {
+ moduleMaps.addTransitive(provider.get(TOP_LEVEL_MODULE_MAP));
+ }
+ }
+ if (ruleContext.attributes().has("non_propagated_deps", BuildType.LABEL_LIST)) {
+ Iterable<ObjcProvider> providers =
+ ruleContext.getPrerequisites("non_propagated_deps", Mode.TARGET, ObjcProvider.class);
+ for (ObjcProvider provider : providers) {
+ moduleMaps.addTransitive(provider.get(TOP_LEVEL_MODULE_MAP));
+ }
+ }
+ }
+
+ builder.addModuleMapsForDirectDeps(moduleMaps.build());
+
+ PathFragment packageFragment =
+ ruleContext.getLabel().getPackageIdentifier().getPathFragment();
+ if (packageFragment != null) {
+ builder.setPackageFragment(packageFragment);
+ }
+
+ if (ruleContext.attributes().has("enable_modules", Type.BOOLEAN)
+ && ruleContext.attributes().get("enable_modules", Type.BOOLEAN)) {
+ builder.enableModules();
+ }
+ }
+ }
+
+ private final NestedSet<Artifact> hdrs;
+ private final NestedSet<Artifact> textualHdrs;
+ private final Optional<Artifact> bridgingHeader;
+ private final NestedSet<PathFragment> includes;
+ private final NestedSet<PathFragment> sdkIncludes;
+ private final NestedSet<SdkFramework> sdkFrameworks;
+ private final NestedSet<SdkFramework> weakSdkFrameworks;
+ private final NestedSet<String> sdkDylibs;
+ private final Optional<PathFragment> packageFragment;
+ private final NestedSet<String> copts;
+ private final NestedSet<String> linkopts;
+ private final NestedSet<CppModuleMap> moduleMapsForDirectDeps;
+ private final boolean enableModules;
+
+ private CompilationAttributes(
+ NestedSet<Artifact> hdrs,
+ NestedSet<Artifact> textualHdrs,
+ Optional<Artifact> bridgingHeader,
+ NestedSet<PathFragment> includes,
+ NestedSet<PathFragment> sdkIncludes,
+ NestedSet<SdkFramework> sdkFrameworks,
+ NestedSet<SdkFramework> weakSdkFrameworks,
+ NestedSet<String> sdkDylibs,
+ Optional<PathFragment> packageFragment,
+ NestedSet<String> copts,
+ NestedSet<String> linkopts,
+ NestedSet<CppModuleMap> moduleMapsForDirectDeps,
+ boolean enableModules) {
+ this.hdrs = hdrs;
+ this.textualHdrs = textualHdrs;
+ this.bridgingHeader = bridgingHeader;
+ this.includes = includes;
+ this.sdkIncludes = sdkIncludes;
+ this.sdkFrameworks = sdkFrameworks;
+ this.weakSdkFrameworks = weakSdkFrameworks;
+ this.sdkDylibs = sdkDylibs;
+ this.packageFragment = packageFragment;
+ this.copts = copts;
+ this.linkopts = linkopts;
+ this.moduleMapsForDirectDeps = moduleMapsForDirectDeps;
+ this.enableModules = enableModules;
+ }
+
+ /**
+ * Returns the headers to be made available for dependents.
+ */
+ public NestedSet<Artifact> hdrs() {
+ return this.hdrs;
+ }
+
+ /**
+ * Returns the headers that cannot be compiled individually.
+ */
+ public NestedSet<Artifact> textualHdrs() {
+ return this.textualHdrs;
+ }
+
+ /**
+ * Returns the bridging header to be used when compiling Swift sources.
+ */
+ public Optional<Artifact> bridgingHeader() {
+ return this.bridgingHeader;
+ }
+
+ /**
+ * Returns the include paths to be made available for compilation.
+ */
+ public NestedSet<PathFragment> includes() {
+ return this.includes;
+ }
+
+ /**
+ * Returns the paths for SDK includes.
+ */
+ public NestedSet<PathFragment> sdkIncludes() {
+ return this.sdkIncludes;
+ }
+
+ /**
+ * Returns the SDK frameworks to link against.
+ */
+ public NestedSet<SdkFramework> sdkFrameworks() {
+ return this.sdkFrameworks;
+ }
+
+ /**
+ * Returns the SDK frameworks to be linked weakly.
+ */
+ public NestedSet<SdkFramework> weakSdkFrameworks() {
+ return this.weakSdkFrameworks;
+ }
+
+ /**
+ * Returns the SDK Dylibs to link against.
+ */
+ public NestedSet<String> sdkDylibs() {
+ return this.sdkDylibs;
+ }
+
+ /**
+ * Returns the exec paths of all header search paths that should be added to this target and
+ * dependers on this target, obtained from the {@code includes} attribute.
+ */
+ public NestedSet<PathFragment> headerSearchPaths(PathFragment genfilesFragment) {
+ NestedSetBuilder<PathFragment> paths = NestedSetBuilder.stableOrder();
+ if (packageFragment.isPresent()) {
+ List<PathFragment> rootFragments =
+ ImmutableList.of(
+ packageFragment.get(), genfilesFragment.getRelative(packageFragment.get()));
+
+ Iterable<PathFragment> relativeIncludes =
+ Iterables.filter(includes(), Predicates.not(PathFragment.IS_ABSOLUTE));
+ for (PathFragment include : relativeIncludes) {
+ for (PathFragment rootFragment : rootFragments) {
+ paths.add(rootFragment.getRelative(include).normalize());
+ }
+ }
+ }
+ return paths.build();
+ }
+
+ /**
+ * Returns the compile-time options.
+ */
+ public NestedSet<String> copts() {
+ return this.copts;
+ }
+
+ /**
+ * Returns the link-time options.
+ */
+ public NestedSet<String> linkopts() {
+ return this.linkopts;
+ }
+
+ /**
+ * Returns the clang module maps of direct dependencies of this rule. These are needed to generate
+ * this rule's module map.
+ */
+ public NestedSet<CppModuleMap> moduleMapsForDirectDeps() {
+ return this.moduleMapsForDirectDeps;
+ }
+
+ /**
+ * Returns whether this target uses language features that require clang modules, such as
+ * {@literal @}import.
+ */
+ public boolean enableModules() {
+ return this.enableModules;
+ }
+}
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 fb420384c5..632887e02f 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
@@ -85,7 +85,6 @@ import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
import com.google.devtools.build.lib.rules.cpp.CppModuleMapAction;
import com.google.devtools.build.lib.rules.cpp.LinkerInputs;
-import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
import com.google.devtools.build.lib.rules.objc.XcodeProvider.Builder;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec;
@@ -98,7 +97,6 @@ import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -235,7 +233,7 @@ public final class CompilationSupport {
static final ImmutableList<String> DEFAULT_COMPILER_FLAGS = ImmutableList.of("-DOS_IOS");
static final ImmutableList<String> DEFAULT_LINKER_FLAGS = ImmutableList.of("-ObjC");
-
+
/**
* Returns information about the given rule's compilation artifacts.
*/
@@ -243,7 +241,7 @@ public final class CompilationSupport {
static CompilationArtifacts compilationArtifacts(RuleContext ruleContext) {
return compilationArtifacts(ruleContext, ObjcRuleClasses.intermediateArtifacts(ruleContext));
}
-
+
/**
* Returns information about the given rule's compilation artifacts. Dependencies specified
* in the current rule's attributes are obtained via {@code ruleContext}. Output locations
@@ -277,25 +275,67 @@ public final class CompilationSupport {
private final IntermediateArtifacts intermediateArtifacts;
/**
- * Creates a new compilation support for the given rule. All actions will be created under
- * the given build configuration, which may be different than the current rule context
- * configuration.
+ * Creates a new compilation support for the given rule.
+ */
+ public CompilationSupport(RuleContext ruleContext) {
+ this(ruleContext, ruleContext.getConfiguration());
+ }
+
+ /**
+ * Creates a new compilation support for the given rule.
+ *
+ * <p>All actions will be created under the given build configuration, which may be different than
+ * the current rule context configuration.
*/
public CompilationSupport(RuleContext ruleContext, BuildConfiguration buildConfiguration) {
- this.ruleContext = ruleContext;
- this.buildConfiguration = buildConfiguration;
- this.objcConfiguration = buildConfiguration.getFragment(ObjcConfiguration.class);
- this.appleConfiguration = buildConfiguration.getFragment(AppleConfiguration.class);
- this.attributes = new CompilationAttributes(ruleContext);
- this.intermediateArtifacts =
- ObjcRuleClasses.intermediateArtifacts(ruleContext, buildConfiguration);
+ this(
+ ruleContext,
+ buildConfiguration,
+ ObjcRuleClasses.intermediateArtifacts(ruleContext, buildConfiguration),
+ CompilationAttributes.Builder.fromRuleContext(ruleContext).build());
}
/**
* Creates a new compilation support for the given rule.
+ *
+ * <p>The compilation and linking flags will be retrieved from the given compilation attributes.
+ * The names of the generated artifacts will be retrieved from the given intermediate artifacts.
+ *
+ * <p>By instantiating multiple compilation supports for the same rule but with intermediate
+ * artifacts with different output prefixes, multiple archives can be compiled for the same
+ * rule context.
*/
- public CompilationSupport(RuleContext ruleContext) {
- this(ruleContext, ruleContext.getConfiguration());
+ public CompilationSupport(
+ RuleContext ruleContext,
+ IntermediateArtifacts intermediateArtifacts,
+ CompilationAttributes compilationAttributes) {
+ this(ruleContext, ruleContext.getConfiguration(), intermediateArtifacts, compilationAttributes);
+ }
+
+ /**
+ * Creates a new compilation support for the given rule and build configuration.
+ *
+ * <p>All actions will be created under the given build configuration, which may be different than
+ * the current rule context configuration.
+ *
+ * <p>The compilation and linking flags will be retrieved from the given compilation attributes.
+ * The names of the generated artifacts will be retrieved from the given intermediate artifacts.
+ *
+ * <p>By instantiating multiple compilation supports for the same rule but with intermediate
+ * artifacts with different output prefixes, multiple archives can be compiled for the same
+ * rule context.
+ */
+ public CompilationSupport(
+ RuleContext ruleContext,
+ BuildConfiguration buildConfiguration,
+ IntermediateArtifacts intermediateArtifacts,
+ CompilationAttributes compilationAttributes) {
+ this.ruleContext = ruleContext;
+ this.buildConfiguration = buildConfiguration;
+ this.objcConfiguration = buildConfiguration.getFragment(ObjcConfiguration.class);
+ this.appleConfiguration = buildConfiguration.getFragment(AppleConfiguration.class);
+ this.attributes = compilationAttributes;
+ this.intermediateArtifacts = intermediateArtifacts;
}
/**
@@ -1370,9 +1410,9 @@ public final class CompilationSupport {
}
if (ruleContext.attributes().has("srcs", BuildType.LABEL_LIST)) {
- Set<Artifact> hdrsSet = new HashSet<>(attributes.hdrs());
- Set<Artifact> srcsSet =
- new HashSet<>(ruleContext.getPrerequisiteArtifacts("srcs", Mode.TARGET).list());
+ ImmutableSet<Artifact> hdrsSet = ImmutableSet.copyOf(attributes.hdrs());
+ ImmutableSet<Artifact> srcsSet =
+ ImmutableSet.copyOf(ruleContext.getPrerequisiteArtifacts("srcs", Mode.TARGET).list());
// Check for overlap between srcs and hdrs.
for (Artifact header : Sets.intersection(hdrsSet, srcsSet)) {
@@ -1382,8 +1422,9 @@ public final class CompilationSupport {
}
// Check for overlap between srcs and non_arc_srcs.
- Set<Artifact> nonArcSrcsSet =
- new HashSet<>(ruleContext.getPrerequisiteArtifacts("non_arc_srcs", Mode.TARGET).list());
+ ImmutableSet<Artifact> nonArcSrcsSet =
+ ImmutableSet.copyOf(
+ ruleContext.getPrerequisiteArtifacts("non_arc_srcs", Mode.TARGET).list());
for (Artifact conflict : Sets.intersection(nonArcSrcsSet, srcsSet)) {
String path = conflict.getRootRelativePath().toString();
ruleContext.attributeError(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java
index 52dd30ca20..6190ffddd3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java
@@ -31,7 +31,6 @@ import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.Val
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.VariablesExtension;
import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider;
import com.google.devtools.build.lib.rules.cpp.PrecompiledFiles;
-import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
import java.util.Collection;
@@ -79,7 +78,7 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory {
objcProvider, ruleContext.getFragment(AppleConfiguration.class))) {
frameworkSequence.addValue(framework);
}
- builder.addSequence(FRAMEWORKS_VARIABLE_NAME, frameworkSequence.build());
+ builder.addSequence(FRAMEWORKS_VARIABLE_NAME, frameworkSequence.build());
}
}
@@ -89,7 +88,8 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory {
CompilationArtifacts compilationArtifacts =
CompilationSupport.compilationArtifacts(ruleContext);
- CompilationAttributes compilationAttributes = new CompilationAttributes(ruleContext);
+ CompilationAttributes compilationAttributes =
+ CompilationAttributes.Builder.fromRuleContext(ruleContext).build();
PrecompiledFiles precompiledFiles = new PrecompiledFiles(ruleContext);
ObjcCommon common = common(ruleContext, compilationAttributes, compilationArtifacts);
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 7c49f81c0e..150bbe34a1 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
@@ -18,6 +18,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STORYBOARD;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCDATAMODEL;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
@@ -35,14 +36,12 @@ 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 com.google.devtools.build.lib.vfs.PathFragment;
/**
* Implementation for {@code ios_test} rule in Bazel.
@@ -100,14 +99,17 @@ 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();
+ ProtoSupport protoSupport =
+ new ProtoSupport(ruleContext, TargetType.LINKING_TARGET).registerActions();
+
+ ObjcCommon protoCommon = protoSupport.getCommon();
+ new CompilationSupport(
+ ruleContext,
+ protoSupport.getIntermediateArtifacts(),
+ new CompilationAttributes.Builder().build())
+ .registerCompileAndArchiveActions(protoCommon, protoSupport.getUserHeaderSearchPaths());
}
XcodeProductType productType = getProductType(ruleContext);
@@ -161,7 +163,7 @@ public final class IosTest implements RuleConfiguredTargetFactory {
extraLinkArgs,
extraLinkInputs,
DsymOutputType.TEST)
- .registerCompileAndArchiveActions(common, priorityHeaders)
+ .registerCompileAndArchiveActions(common)
.registerFullyLinkAction(common.getObjcProvider())
.addXcodeSettings(xcodeProviderBuilder, common)
.validateAttributes();
@@ -256,20 +258,19 @@ public final class IosTest implements RuleConfiguredTargetFactory {
CompilationArtifacts compilationArtifacts =
CompilationSupport.compilationArtifacts(ruleContext);
- if (ObjcRuleClasses.objcConfiguration(ruleContext).experimentalAutoTopLevelUnionObjCProtos()) {
+ Optional<Artifact> protoLib;
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+ 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();
+ protoLib = protoSupport.getCommon().getCompiledArchive();
+ } else {
+ protoLib = Optional.absent();
}
ObjcCommon.Builder builder =
new ObjcCommon.Builder(ruleContext)
- .setCompilationAttributes(new CompilationAttributes(ruleContext))
+ .setCompilationAttributes(
+ CompilationAttributes.Builder.fromRuleContext(ruleContext).build())
.setCompilationArtifacts(compilationArtifacts)
.setResourceAttributes(new ResourceAttributes(ruleContext))
.addDefines(ruleContext.getTokenizedStringListAttr("defines"))
@@ -279,6 +280,7 @@ public final class IosTest implements RuleConfiguredTargetFactory {
ruleContext.getPrerequisites(
"non_propagated_deps", Mode.TARGET, ObjcProvider.class))
.setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
+ .addExtraImportLibraries(protoLib.asSet())
.setHasModuleMap();
if (isXcTest(ruleContext)) {
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 d15148b1e2..623bde4dd1 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
@@ -58,7 +58,6 @@ import static com.google.devtools.build.lib.vfs.PathFragment.TO_PATH_FRAGMENT;
import com.google.common.annotations.VisibleForTesting;
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;
@@ -69,23 +68,17 @@ import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.rules.apple.AppleToolchain;
-import com.google.devtools.build.lib.rules.cpp.CcCommon;
import com.google.devtools.build.lib.rules.cpp.CcLinkParams;
import com.google.devtools.build.lib.rules.cpp.CcLinkParamsProvider;
import com.google.devtools.build.lib.rules.cpp.CppCompilationContext;
import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
import com.google.devtools.build.lib.rules.cpp.CppRunfilesProvider;
import com.google.devtools.build.lib.rules.cpp.LinkerInputs;
-import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.FileType;
-import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.PathFragment;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -99,160 +92,6 @@ import java.util.Set;
// rule-internal information. Any provider created by a rule should not be read, only published.
public final class ObjcCommon {
/**
- * Provides a way to access attributes that are common to all compilation rules.
- */
- // TODO(bazel-team): Delete and move into support-specific attributes classes once ObjcCommon is
- // gone.
- static final class CompilationAttributes {
- private final RuleContext ruleContext;
- private final ObjcSdkFrameworks.Attributes sdkFrameworkAttributes;
-
- CompilationAttributes(RuleContext ruleContext) {
- this.ruleContext = Preconditions.checkNotNull(ruleContext);
- this.sdkFrameworkAttributes = new ObjcSdkFrameworks.Attributes(ruleContext);
- }
-
- ImmutableList<Artifact> hdrs() {
- // Some rules may compile but not have the "hdrs" attribute.
- if (!ruleContext.attributes().has("hdrs", BuildType.LABEL_LIST)) {
- return ImmutableList.of();
- }
- ImmutableList.Builder<Artifact> headers = ImmutableList.builder();
- for (Pair<Artifact, Label> header : CcCommon.getHeaders(ruleContext)) {
- headers.add(header.first);
- }
- return headers.build();
- }
-
- /**
- * Returns headers that cannot be compiled individually.
- */
- ImmutableList<Artifact> textualHdrs() {
- // Some rules may compile but not have the "textual_hdrs" attribute.
- if (!ruleContext.attributes().has("textual_hdrs", BuildType.LABEL_LIST)) {
- return ImmutableList.of();
- }
- return ruleContext.getPrerequisiteArtifacts("textual_hdrs", Mode.TARGET).list();
- }
-
- Optional<Artifact> bridgingHeader() {
- Artifact header = ruleContext.getPrerequisiteArtifact("bridging_header", Mode.TARGET);
- return Optional.fromNullable(header);
- }
-
- Iterable<PathFragment> includes() {
- return Iterables.transform(
- ruleContext.attributes().get("includes", Type.STRING_LIST),
- PathFragment.TO_PATH_FRAGMENT);
- }
-
- Iterable<PathFragment> sdkIncludes() {
- return Iterables.transform(
- ruleContext.attributes().get("sdk_includes", Type.STRING_LIST),
- PathFragment.TO_PATH_FRAGMENT);
- }
-
- /**
- * Returns the value of the sdk_frameworks attribute plus frameworks that are included
- * automatically.
- */
- ImmutableSet<SdkFramework> sdkFrameworks() {
- return sdkFrameworkAttributes.sdkFrameworks();
- }
-
- /**
- * Returns the value of the weak_sdk_frameworks attribute.
- */
- ImmutableSet<SdkFramework> weakSdkFrameworks() {
- return sdkFrameworkAttributes.weakSdkFrameworks();
- }
-
- /**
- * Returns the value of the sdk_dylibs attribute.
- */
- ImmutableSet<String> sdkDylibs() {
- return sdkFrameworkAttributes.sdkDylibs();
- }
-
- /**
- * Returns the exec paths of all header search paths that should be added to this target and
- * dependers on this target, obtained from the {@code includes} attribute.
- */
- ImmutableList<PathFragment> headerSearchPaths(PathFragment genfilesFragment) {
- ImmutableList.Builder<PathFragment> paths = new ImmutableList.Builder<>();
- PathFragment packageFragment =
- ruleContext.getLabel().getPackageIdentifier().getPathFragment();
- List<PathFragment> rootFragments =
- ImmutableList.of(packageFragment, genfilesFragment.getRelative(packageFragment));
-
- Iterable<PathFragment> relativeIncludes =
- Iterables.filter(includes(), Predicates.not(PathFragment.IS_ABSOLUTE));
- for (PathFragment include : relativeIncludes) {
- for (PathFragment rootFragment : rootFragments) {
- paths.add(rootFragment.getRelative(include).normalize());
- }
- }
- return paths.build();
- }
-
- /**
- * Returns any values specified in this rule's {@code copts} attribute or an empty list if the
- * attribute does not exist or no values are specified.
- */
- public Iterable<String> copts() {
- return ruleContext.getTokenizedStringListAttr("copts");
- }
-
- /**
- * Returns any values specified in this rule's {@code linkopts} attribute or an empty list if
- * the attribute does not exist or no values are specified.
- */
- public Iterable<String> linkopts() {
- return ruleContext.getTokenizedStringListAttr("linkopts");
- }
-
- /**
- * The clang module maps of direct dependencies of this rule. These are needed to generate
- * this rule's module map.
- */
- public List<CppModuleMap> moduleMapsForDirectDeps() {
- // Make sure all dependencies that have headers are included here. If a module map is missing,
- // its private headers will be treated as public!
- ArrayList<CppModuleMap> moduleMaps = new ArrayList<>();
- collectModuleMapsFromAttributeIfExists(moduleMaps, "deps");
- collectModuleMapsFromAttributeIfExists(moduleMaps, "non_propagated_deps");
- return moduleMaps;
- }
-
- /**
- * Collects all module maps from the targets in a certain attribute and adds them into
- * {@code moduleMaps}.
- *
- * @param moduleMaps an {@link ArrayList} to collect the module maps into
- * @param attribute the name of a label list attribute to collect module maps from
- */
- private void collectModuleMapsFromAttributeIfExists(
- ArrayList<CppModuleMap> moduleMaps, String attribute) {
- if (ruleContext.attributes().has(attribute, BuildType.LABEL_LIST)) {
- Iterable<ObjcProvider> providers =
- ruleContext.getPrerequisites(attribute, Mode.TARGET, ObjcProvider.class);
- for (ObjcProvider provider : providers) {
- moduleMaps.addAll(provider.get(TOP_LEVEL_MODULE_MAP).toCollection());
- }
- }
- }
-
- /**
- * Returns whether this target uses language features that require clang modules, such as
- * {@literal @}import.
- */
- public boolean enableModules() {
- return ruleContext.attributes().has("enable_modules", Type.BOOLEAN)
- && ruleContext.attributes().get("enable_modules", Type.BOOLEAN);
- }
- }
-
- /**
* Provides a way to access attributes that are common to all resources rules.
*/
// TODO(bazel-team): Delete and move into support-specific attributes classes once ObjcCommon is
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
index 67c0fa80dc..e28b5e5636 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
@@ -26,7 +26,6 @@ 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.ObjcCommon.Builder;
-import com.google.devtools.build.lib.rules.objc.ObjcSdkFrameworks.Attributes;
import com.google.devtools.build.lib.syntax.Type;
/**
@@ -36,13 +35,14 @@ public class ObjcFramework implements RuleConfiguredTargetFactory {
@Override
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException {
- Attributes sdkFrameworkAttributes = new Attributes(ruleContext);
+ CompilationAttributes compilationAttributes =
+ CompilationAttributes.Builder.fromRuleContext(ruleContext).build();
ObjcCommon.Builder commonBuilder =
new Builder(ruleContext)
- .addExtraSdkFrameworks(sdkFrameworkAttributes.sdkFrameworks())
- .addExtraWeakSdkFrameworks(sdkFrameworkAttributes.weakSdkFrameworks())
- .addExtraSdkDylibs(sdkFrameworkAttributes.sdkDylibs());
+ .addExtraSdkFrameworks(compilationAttributes.sdkFrameworks())
+ .addExtraWeakSdkFrameworks(compilationAttributes.weakSdkFrameworks())
+ .addExtraSdkDylibs(compilationAttributes.sdkDylibs());
ImmutableList<Artifact> frameworkImports =
ruleContext.getPrerequisiteArtifacts("framework_imports", Mode.TARGET).list();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFrameworkRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFrameworkRule.java
index 9f264f9d4a..0fba5ca20d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFrameworkRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFrameworkRule.java
@@ -33,6 +33,7 @@ public class ObjcFrameworkRule implements RuleDefinition {
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
return builder
+ .requiresConfigurationFragments(ObjcConfiguration.class)
/* <!-- #BLAZE_RULE(objc_framework).ATTRIBUTE(framework_imports) -->
The list of files under a <code>.framework</code> directory which are
provided to Objective-C targets that depend on this target.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
index b1c10f75fc..0ef0aa8159 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
@@ -24,7 +24,6 @@ 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.ObjcCommon.CompilationAttributes;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes;
import com.google.devtools.build.lib.syntax.Type;
@@ -37,7 +36,8 @@ public class ObjcImport implements RuleConfiguredTargetFactory {
throws InterruptedException, RuleErrorException {
ObjcCommon common =
new ObjcCommon.Builder(ruleContext)
- .setCompilationAttributes(new CompilationAttributes(ruleContext))
+ .setCompilationAttributes(
+ CompilationAttributes.Builder.fromRuleContext(ruleContext).build())
.setResourceAttributes(new ResourceAttributes(ruleContext))
.setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
.setAlwayslink(ruleContext.attributes().get("alwayslink", Type.BOOLEAN))
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 b7a3faa9ae..54134cac69 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
@@ -29,7 +29,6 @@ import com.google.devtools.build.lib.rules.cpp.CcLinkParamsProvider;
import com.google.devtools.build.lib.rules.cpp.CcLinkParamsStore;
import com.google.devtools.build.lib.rules.cpp.LinkerInputs;
import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink;
-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.test.InstrumentedFilesProvider;
import com.google.devtools.build.lib.syntax.Type;
@@ -71,7 +70,8 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory {
*/
private ObjcCommon common(RuleContext ruleContext) {
return new ObjcCommon.Builder(ruleContext)
- .setCompilationAttributes(new CompilationAttributes(ruleContext))
+ .setCompilationAttributes(
+ CompilationAttributes.Builder.fromRuleContext(ruleContext).build())
.setResourceAttributes(new ResourceAttributes(ruleContext))
.addDefines(ruleContext.getTokenizedStringListAttr("defines"))
.setCompilationArtifacts(CompilationSupport.compilationArtifacts(ruleContext))
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 79cfb1d20c..89d420b2da 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
@@ -32,14 +32,12 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory {
@Override
public ConfiguredTarget create(final RuleContext ruleContext)
throws InterruptedException, RuleErrorException {
- ObjcCommon.Builder commonBuilder = new ObjcCommon.Builder(ruleContext);
XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder();
NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
ProtoSupport protoSupport =
new ProtoSupport(ruleContext, TargetType.PROTO_TARGET)
.validate()
- .addCommonOptions(commonBuilder)
.addXcodeProviderOptions(xcodeProviderBuilder)
.addFilesToBuild(filesToBuild)
.registerActions();
@@ -48,7 +46,7 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory {
return null;
}
- ObjcCommon common = commonBuilder.build();
+ ObjcCommon common = protoSupport.getCommon();
filesToBuild.addAll(common.getCompiledArchive().asSet());
@@ -67,9 +65,7 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory {
// 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());
+ new CompilationSupport(ruleContext).registerCompileAndArchiveActions(common);
}
return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcSdkFrameworks.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcSdkFrameworks.java
deleted file mode 100644
index 8ca09cfae9..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcSdkFrameworks.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2014 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.rules.objc;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.SdkFrameworksDependerRule;
-import com.google.devtools.build.lib.syntax.Type;
-
-/**
- * Common logic for rules that inherit from {@link SdkFrameworksDependerRule}.
- */
-public class ObjcSdkFrameworks {
-
- /**
- * Class that handles extraction and processing of attributes common to inheritors of {@link
- * SdkFrameworksDependerRule}.
- */
- public static class Attributes {
-
- private final RuleContext ruleContext;
-
- public Attributes(RuleContext ruleContext) {
- this.ruleContext = ruleContext;
- }
-
- /**
- * Returns the SDK frameworks defined on the rule's {@code sdk_frameworks} attribute as well as
- * base frameworks defined in {@link ObjcRuleClasses#AUTOMATIC_SDK_FRAMEWORKS}.
- */
- ImmutableSet<SdkFramework> sdkFrameworks() {
- ImmutableSet.Builder<SdkFramework> result = new ImmutableSet.Builder<>();
- result.addAll(ObjcRuleClasses.AUTOMATIC_SDK_FRAMEWORKS);
- for (String explicit : ruleContext.attributes().get("sdk_frameworks", Type.STRING_LIST)) {
- result.add(new SdkFramework(explicit));
- }
- return result.build();
- }
-
- /**
- * Returns all SDK frameworks defined on the rule's {@code weak_sdk_frameworks} attribute.
- */
- ImmutableSet<SdkFramework> weakSdkFrameworks() {
- ImmutableSet.Builder<SdkFramework> result = new ImmutableSet.Builder<>();
- for (String frameworkName :
- ruleContext.attributes().get("weak_sdk_frameworks", Type.STRING_LIST)) {
- result.add(new SdkFramework(frameworkName));
- }
- return result.build();
- }
-
- /**
- * Returns all SDK dylibs defined on the rule's {@code sdk_dylibs} attribute.
- */
- ImmutableSet<String> sdkDylibs() {
- return ImmutableSet.copyOf(ruleContext.attributes().get("sdk_dylibs", Type.STRING_LIST));
- }
- }
-}
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 7d441ecd78..5ee93099ab 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
@@ -118,6 +118,7 @@ final class ProtoSupport {
private final RuleContext ruleContext;
private final Attributes attributes;
private final TargetType targetType;
+ private final IntermediateArtifacts intermediateArtifacts;
/**
* Creates a new proto support.
@@ -129,6 +130,15 @@ final class ProtoSupport {
this.ruleContext = ruleContext;
this.attributes = new Attributes(ruleContext);
this.targetType = targetType;
+ if (targetType != TargetType.PROTO_TARGET) {
+ // Use a a prefixed version of the intermediate artifacts to avoid naming collisions, as
+ // the proto compilation step happens in the same context as the linking target.
+ this.intermediateArtifacts =
+ new IntermediateArtifacts(
+ ruleContext, "_protos", "protos", ruleContext.getConfiguration());
+ } else {
+ this.intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext);
+ }
}
/**
@@ -164,6 +174,13 @@ final class ProtoSupport {
}
/**
+ * Returns the intermediate artifacts associated with generated proto compilation.
+ */
+ public IntermediateArtifacts getIntermediateArtifacts() {
+ return intermediateArtifacts;
+ }
+
+ /**
* Registers actions required for compiling the proto files.
*
* @return this proto support
@@ -177,29 +194,30 @@ 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 proto support
+ * Returns the common object for a proto specific compilation environment.
*/
- public ProtoSupport addCommonOptions(ObjcCommon.Builder commonBuilder) {
- commonBuilder
- .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
- .addDepObjcProviders(
- ruleContext.getPrerequisites(
- 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());
+ public ObjcCommon getCommon() {
+ ObjcCommon.Builder commonBuilder =
+ new ObjcCommon.Builder(ruleContext)
+ .setIntermediateArtifacts(intermediateArtifacts)
+ .setHasModuleMap()
+ .setCompilationArtifacts(getCompilationArtifacts());
+
+ if (targetType == TargetType.LINKING_TARGET) {
+ commonBuilder.addDepObjcProviders(
+ ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class));
+ } else if (targetType == TargetType.PROTO_TARGET) {
+ commonBuilder.addDepObjcProviders(
+ ruleContext.getPrerequisites(
+ ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.class));
+
+ if (usesProtobufLibrary() && experimentalAutoUnion()) {
+ commonBuilder.addDirectDependencyHeaderSearchPaths(getUserHeaderSearchPaths());
+ } else {
+ commonBuilder.addUserHeaderSearchPaths(getUserHeaderSearchPaths());
+ }
}
- return this;
+ return commonBuilder.build();
}
/**
@@ -235,7 +253,7 @@ final class ProtoSupport {
ImmutableList<Artifact> generatedSources = getGeneratedSources();
CompilationArtifacts.Builder builder =
new CompilationArtifacts.Builder()
- .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
+ .setIntermediateArtifacts(intermediateArtifacts)
.setPchFile(Optional.<Artifact>absent())
.addAdditionalHdrs(getGeneratedHeaders());