aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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());