aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/objc
diff options
context:
space:
mode:
authorGravatar Cal Peyser <cpeyser@google.com>2016-04-12 18:30:26 +0000
committerGravatar Lukacs Berki <lberki@google.com>2016-04-13 08:09:00 +0000
commitbbf59ed1be85354457ad1d8123cc1973aa3ba298 (patch)
tree35fc9dee2613582b3e980874b34e02d337f4a871 /src/main/java/com/google/devtools/build/lib/rules/objc
parent3231e78fc1f79b72b618627e32c3c5cd6d754444 (diff)
Introduces experimental_objc_library. This rule builds objc code with the c++ rule implementation backend and an OSX crosstool.
-- MOS_MIGRATED_REVID=119660101
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/objc')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java83
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibraryRule.java53
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java76
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java69
4 files changed, 279 insertions, 2 deletions
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
new file mode 100644
index 0000000000..4b214acd76
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java
@@ -0,0 +1,83 @@
+// 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 com.google.common.collect.Sets;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.cpp.CcLibraryHelper;
+import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
+import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider;
+import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
+
+import java.util.Collection;
+
+/**
+ * Implementation for experimental_objc_library.
+ */
+public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory {
+
+ @Override
+ public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException {
+
+ CompilationArtifacts compilationArtifacts =
+ CompilationSupport.compilationArtifacts(ruleContext);
+ CompilationAttributes compilationAttributes = new CompilationAttributes(ruleContext);
+
+ ObjcCommon common = common(ruleContext, compilationAttributes, compilationArtifacts);
+
+ CcToolchainProvider toolchain =
+ ruleContext
+ .getPrerequisite(":cc_toolchain", Mode.TARGET)
+ .getProvider(CcToolchainProvider.class);
+ FeatureConfiguration featureConfiguration = toolchain.getFeatures().getFeatureConfiguration();
+
+ Collection<Artifact> sources = Sets.newHashSet(compilationArtifacts.getSrcs());
+ Collection<Artifact> privateHdrs = Sets.newHashSet(compilationArtifacts.getPrivateHdrs());
+ Collection<Artifact> publicHdrs = Sets.newHashSet(compilationAttributes.hdrs());
+
+ CcLibraryHelper helper =
+ new CcLibraryHelper(ruleContext, ObjcCppSemantics.INSTANCE, featureConfiguration)
+ .addSources(sources)
+ .addSources(privateHdrs)
+ .enableCompileProviders()
+ .addPublicHeaders(publicHdrs)
+ .addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET));
+
+ CcLibraryHelper.Info info = helper.build();
+
+ NestedSetBuilder<Artifact> filesToBuild =
+ NestedSetBuilder.<Artifact>stableOrder().addAll(common.getCompiledArchive().asSet());
+
+ return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
+ .addProviders(info.getProviders())
+ .build();
+ }
+
+ private ObjcCommon common(
+ RuleContext ruleContext,
+ CompilationAttributes compilationAttributes,
+ CompilationArtifacts compilationArtifacts) {
+ return new ObjcCommon.Builder(ruleContext)
+ .setCompilationAttributes(compilationAttributes)
+ .setCompilationArtifacts(compilationArtifacts)
+ .addDepObjcProviders(ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class))
+ .build();
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibraryRule.java
new file mode 100644
index 0000000000..77c70f65de
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibraryRule.java
@@ -0,0 +1,53 @@
+// 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 com.google.devtools.build.lib.analysis.BaseRuleClasses;
+import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.RuleClass.Builder;
+import com.google.devtools.build.lib.packages.RuleClass.PackageNameConstraint;
+import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
+import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
+
+/**
+ * Rule definition for experimental_objc_library.
+ */
+public class ExperimentalObjcLibraryRule implements RuleDefinition {
+ @Override
+ public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
+ return builder
+ .requiresConfigurationFragments(
+ ObjcConfiguration.class, AppleConfiguration.class, CppConfiguration.class)
+ // experimental_objc_library should only occur in bazel test code. We use the /objc
+ // directory for tests.
+ .setValidityPredicate(new PackageNameConstraint(1, "objc"))
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("experimental_objc_library")
+ .factoryClass(ExperimentalObjcLibrary.class)
+ .ancestors(
+ BaseRuleClasses.BaseRule.class,
+ ObjcRuleClasses.LinkingRule.class,
+ ObjcRuleClasses.AlwaysLinkRule.class,
+ ObjcRuleClasses.CrosstoolRule.class)
+ .build();
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
new file mode 100644
index 0000000000..30afe9dcc4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
@@ -0,0 +1,76 @@
+// 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 com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.rules.cpp.CppCompilationContext.Builder;
+import com.google.devtools.build.lib.rules.cpp.CppCompileActionBuilder;
+import com.google.devtools.build.lib.rules.cpp.CppCompileActionContext;
+import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
+import com.google.devtools.build.lib.rules.cpp.CppConfiguration.HeadersCheckingMode;
+import com.google.devtools.build.lib.rules.cpp.CppHelper;
+import com.google.devtools.build.lib.rules.cpp.CppSemantics;
+import com.google.devtools.build.lib.vfs.PathFragment;
+
+/**
+ * CppSemantics for objc builds.
+ */
+public class ObjcCppSemantics implements CppSemantics {
+
+ // We make CppSemantics a singleton object for efficiency and consistency, since we expect
+ // any instance to be identical.
+ public static final CppSemantics INSTANCE = new ObjcCppSemantics();
+
+ @Override
+ public PathFragment getEffectiveSourcePath(Artifact source) {
+ return source.getRootRelativePath();
+ }
+
+ @Override
+ public void finalizeCompileActionBuilder(
+ RuleContext ruleContext, CppCompileActionBuilder actionBuilder) {
+ actionBuilder.setCppConfiguration(ruleContext.getFragment(CppConfiguration.class));
+ actionBuilder.setActionContext(CppCompileActionContext.class);
+ // Because Bazel does not support include scanning, we need the entire crosstool filegroup,
+ // including header files, as opposed to just the "compile" filegroup.
+ actionBuilder.addTransitiveMandatoryInputs(CppHelper.getToolchain(ruleContext).getCrosstool());
+ actionBuilder.setShouldScanIncludes(false);
+ }
+
+
+ @Override
+ public void setupCompilationContext(RuleContext ruleContext, Builder contextBuilder) {
+ // For objc builds, no extra setup is required.
+ }
+
+ @Override
+ public HeadersCheckingMode determineHeadersCheckingMode(RuleContext ruleContext) {
+ // Currently, objc builds do not enforce strict deps. To begin enforcing strict deps in objc,
+ // switch this flag to STRICT.
+ return HeadersCheckingMode.WARN;
+ }
+
+ @Override
+ public boolean needsIncludeScanning(RuleContext ruleContext) {
+ return false;
+ }
+
+ @Override
+ public Root getGreppedIncludesDirectory(RuleContext ruleContext) {
+ return null;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
index ef9e07911a..634c535156 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
@@ -53,6 +53,7 @@ import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.AppleToolchain;
import com.google.devtools.build.lib.rules.apple.AppleToolchain.RequiresXcodeConfigRule;
import com.google.devtools.build.lib.rules.apple.Platform;
+import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.FileTypeSet;
@@ -125,12 +126,50 @@ public class ObjcRuleClasses {
return !ASSEMBLY_SOURCES.matches(sourceArtifact.getFilename());
}
-
@VisibleForTesting
static final Iterable<SdkFramework> AUTOMATIC_SDK_FRAMEWORKS = ImmutableList.of(
new SdkFramework("Foundation"), new SdkFramework("UIKit"));
/**
+ * Label of a filegroup that contains all crosstool and grte files for all configurations,
+ * as specified on the command-line.
+ *
+ * <p> Since this is the loading-phase default for the :cc_toolchain attribute of rules
+ * using the crosstool, it must contain in its transitive closure the computer value
+ * of that attribute under the default configuration.
+ */
+ public static final String CROSSTOOL_LABEL = "//tools/defaults:crosstool";
+
+ /**
+ * Late-bound attribute giving the CcToolchain for CROSSTOOL_LABEL.
+ *
+ * TODO(cpeyser): Use AppleCcToolchain instead of CcToolchain once released.
+ */
+ public static final LateBoundLabel<BuildConfiguration> APPLE_TOOLCHAIN =
+ new LateBoundLabel<BuildConfiguration>(CROSSTOOL_LABEL, CppConfiguration.class) {
+ @Override
+ public Label getDefault(
+ Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
+ return configuration.getFragment(CppConfiguration.class).getCcToolchainRuleLabel();
+ }
+ };
+
+ /**
+ * A null value for the lipo context colletor. Objc builds do not use a lipo context collector.
+ */
+ // TODO(b/28084560): Allow :lipo_context_collector not to be set instead of having a null
+ // instance.
+ public static final LateBoundLabel<BuildConfiguration> NULL_LIPO_CONTEXT_COLLECTOR =
+ new LateBoundLabel<BuildConfiguration>() {
+ @Override
+ public Label getDefault(
+ Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
+ return null;
+ }
+ };
+
+
+ /**
* Creates a new spawn action builder with apple environment variables set that are typically
* needed by the apple toolchain. This should be used to start to build spawn actions that, in
* order to run, require both a darwin architecture and a collection of environment variables
@@ -510,6 +549,31 @@ public class ObjcRuleClasses {
}
/**
+ * Common attributes for {@code objc_*} rules that depend on a crosstool.
+ */
+ public static class CrosstoolRule implements RuleDefinition {
+
+ @Override
+ public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
+ return builder
+ .add(attr(":cc_toolchain", LABEL).value(APPLE_TOOLCHAIN))
+ .add(
+ attr(":lipo_context_collector", LABEL)
+ .value(NULL_LIPO_CONTEXT_COLLECTOR)
+ .skipPrereqValidatorCheck())
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("$objc_crosstool_rule")
+ .type(RuleClassType.ABSTRACT)
+ .build();
+ }
+ }
+
+ /**
* Common attributes for {@code objc_*} rules that can be input to compilation (i.e. can be
* dependencies of other compiling rules).
*/
@@ -592,7 +656,8 @@ public class ObjcRuleClasses {
"cc_library",
"cc_inc_library",
"ios_framework",
- "swift_library");
+ "swift_library",
+ "experimental_objc_library");
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {