aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar kaipi <kaipi@google.com>2018-01-25 09:43:38 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-01-25 09:46:24 -0800
commit86fdf0b2495888fc2c3e8c84e0b2f02f566187f9 (patch)
tree1f3021b1cd810712c56d7748a8911c05f80ca68f /src/main/java/com/google
parentada0c370c2a3ea484925bc4e7d927b015bc4ad92 (diff)
Remove ios_test from Bazel. ios_test is an old rule and this removal is part of the final steps of the migration process into Skylark. If you were using ios_test, please take a look at ios_unit_test provided by the github.com/bazelbuild/rules_apple project.
PiperOrigin-RevId: 183251623
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java43
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java288
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java157
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java273
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundling.java395
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java1250
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/Storyboards.java76
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java329
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/XcTestAppProvider.java101
13 files changed, 13 insertions, 2931 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index 0e7782c7f7..76df32e66d 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -135,7 +135,6 @@ import com.google.devtools.build.lib.rules.objc.AppleSkylarkCommon;
import com.google.devtools.build.lib.rules.objc.AppleStaticLibraryRule;
import com.google.devtools.build.lib.rules.objc.AppleStubBinaryRule;
import com.google.devtools.build.lib.rules.objc.IosDeviceRule;
-import com.google.devtools.build.lib.rules.objc.IosTestRule;
import com.google.devtools.build.lib.rules.objc.J2ObjcAspect;
import com.google.devtools.build.lib.rules.objc.J2ObjcCommandLineOptions;
import com.google.devtools.build.lib.rules.objc.J2ObjcConfiguration;
@@ -552,7 +551,6 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new AppleCcToolchainRule());
builder.addRuleDefinition(new AppleToolchain.RequiresXcodeConfigRule(toolsRepository));
builder.addRuleDefinition(new IosDeviceRule());
- builder.addRuleDefinition(new IosTestRule());
builder.addRuleDefinition(new ObjcBundleRule());
builder.addRuleDefinition(new ObjcBundleLibraryRule());
builder.addRuleDefinition(new ObjcFrameworkRule());
@@ -561,8 +559,6 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new ObjcRuleClasses.CoptsRule());
builder.addRuleDefinition(new ObjcRuleClasses.BundlingRule());
builder.addRuleDefinition(new ObjcRuleClasses.DylibDependingRule(objcProtoAspect));
- builder.addRuleDefinition(new ObjcRuleClasses.ReleaseBundlingRule());
- builder.addRuleDefinition(new ObjcRuleClasses.SimulatorRule());
builder.addRuleDefinition(new ObjcRuleClasses.CompilingRule());
builder.addRuleDefinition(new ObjcRuleClasses.LinkingRule(objcProtoAspect));
builder.addRuleDefinition(new ObjcRuleClasses.PlatformRule());
@@ -574,8 +570,6 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new ObjcRuleClasses.ResourceToolsRule());
builder.addRuleDefinition(new ObjcRuleClasses.XcrunRule());
builder.addRuleDefinition(new ObjcRuleClasses.LibtoolRule());
- builder.addRuleDefinition(new ObjcRuleClasses.IpaRule());
- builder.addRuleDefinition(new ObjcRuleClasses.ReleaseBundlingToolsRule());
builder.addRuleDefinition(new ObjcRuleClasses.CrosstoolRule());
builder.addRuleDefinition(new XcodeConfigRule());
builder.addRuleDefinition(new XcodeConfigAliasRule());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
index ff81e4cac2..d72a550377 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
@@ -404,49 +404,6 @@ public class AppleSkylarkCommon {
};
@SkylarkSignature(
- name = "new_xctest_app_provider",
- objectType = AppleSkylarkCommon.class,
- returnType = XcTestAppProvider.class,
- doc = "Creates a new XcTestAppProvider instance.",
- parameters = {
- @Param(name = "self", type = AppleSkylarkCommon.class, doc = "The apple_common instance."),
- @Param(
- name = "bundle_loader",
- type = Artifact.class,
- named = true,
- positional = false,
- doc = "The bundle loader for the test. Corresponds to the binary inside the test IPA."
- ),
- @Param(
- name = "ipa",
- type = Artifact.class,
- named = true,
- positional = false,
- doc = "The test IPA."
- ),
- @Param(
- name = "objc_provider",
- type = ObjcProvider.class,
- named = true,
- positional = false,
- doc = "An ObjcProvider that should be included by tests using this test bundle."
- )
- }
- )
- public static final BuiltinFunction NEW_XCTEST_APP_PROVIDER =
- new BuiltinFunction("new_xctest_app_provider") {
- @SuppressWarnings("unused")
- // This method is registered statically for skylark, and never called directly.
- public XcTestAppProvider invoke(
- AppleSkylarkCommon self,
- Artifact bundleLoader,
- Artifact ipa,
- ObjcProvider objcProvider) {
- return new XcTestAppProvider(bundleLoader, ipa, objcProvider);
- }
- };
-
- @SkylarkSignature(
name = "new_dynamic_framework_provider",
objectType = AppleSkylarkCommon.class,
returnType = AppleDynamicFrameworkInfo.class,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java
index 36ad180077..082ba3fbdd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java
@@ -116,8 +116,7 @@ public class AppleStaticLibraryRule implements RuleDefinition {
return RuleDefinition.Metadata.builder()
.name("apple_static_library")
.factoryClass(AppleStaticLibrary.class)
- .ancestors(BaseRuleClasses.BaseRule.class, ObjcRuleClasses.MultiArchPlatformRule.class,
- ObjcRuleClasses.SimulatorRule.class)
+ .ancestors(BaseRuleClasses.BaseRule.class, ObjcRuleClasses.MultiArchPlatformRule.class)
.build();
}
}
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 6eadae643e..6f574abe67 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
@@ -977,7 +977,7 @@ public class CompilationSupport {
INSTRUMENTATION_SPEC,
new ObjcCoverageMetadataCollector(),
oFiles.build(),
- getGcovForObjectiveCIfNeeded(),
+ NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER),
// The COVERAGE_GCOV_PATH environment variable is added in TestSupport#getExtraProviders()
NestedSetBuilder.<Pair<String, String>>emptySet(Order.COMPILE_ORDER),
!isTestRule);
@@ -1721,15 +1721,6 @@ public class CompilationSupport {
.build(ruleContext));
}
- private NestedSet<Artifact> getGcovForObjectiveCIfNeeded() {
- if (ruleContext.getConfiguration().isCodeCoverageEnabled()
- && ruleContext.attributes().has(IosTest.OBJC_GCOV_ATTR, BuildType.LABEL)) {
- return PrerequisiteArtifacts.nestedSet(ruleContext, IosTest.OBJC_GCOV_ATTR, Mode.HOST);
- } else {
- return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
- }
- }
-
private CompilationSupport registerGenerateUmbrellaHeaderAction(
Artifact umbrellaHeader, Iterable<Artifact> publicHeaders) {
ruleContext.registerAction(
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
deleted file mode 100644
index bb888f0f90..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
+++ /dev/null
@@ -1,288 +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 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;
-import com.google.devtools.build.lib.actions.ExecutionRequirements;
-import com.google.devtools.build.lib.analysis.ConfiguredTarget;
-import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
-import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
-import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.Runfiles;
-import com.google.devtools.build.lib.analysis.RunfilesProvider;
-import com.google.devtools.build.lib.analysis.RunfilesSupport;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
-import com.google.devtools.build.lib.analysis.test.ExecutionInfo;
-import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider;
-import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
-import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType;
-import com.google.devtools.build.lib.rules.apple.XcodeConfig;
-import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
-import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes;
-import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary;
-import com.google.devtools.build.lib.rules.proto.ProtoSourcesProvider;
-
-/** Implementation for {@code ios_test} rule in Bazel. */
-public final class IosTest implements RuleConfiguredTargetFactory {
-
- private static final ImmutableList<SdkFramework> AUTOMATIC_SDK_FRAMEWORKS_FOR_XCTEST =
- ImmutableList.of(new SdkFramework("XCTest"));
-
- // Attributes for IosTest rules.
- // Documentation on usage is in {@link IosTestRule@}.
- static final String OBJC_GCOV_ATTR = "$objc_gcov";
- static final String DEVICE_ARG_ATTR = "ios_device_arg";
- static final String IS_XCTEST_ATTR = "xctest";
- static final String MEMLEAKS_DEP_ATTR = "$memleaks_dep";
- static final String MEMLEAKS_PLUGIN_ATTR = "$memleaks_plugin";
- static final String PLUGINS_ATTR = "plugins";
- static final String TARGET_DEVICE = "target_device";
- static final String TEST_RUNNER_ATTR = "$test_runner";
- static final String TEST_TARGET_DEVICE_ATTR = "ios_test_target_device";
- static final String TEST_TEMPLATE_ATTR = "$test_template";
- static final String XCTEST_APP_ATTR = "xctest_app";
- static final String MCOV_TOOL_ATTR = ":mcov";
-
- @VisibleForTesting
- public static final String REQUIRES_SOURCE_ERROR =
- "ios_test requires at least one source file in srcs or non_arc_srcs";
-
- @VisibleForTesting
- public static final String NO_MULTI_CPUS_ERROR =
- "ios_test cannot be built for multiple CPUs at the same time";
-
- /**
- * {@inheritDoc}
- *
- * <p>Creates a target, including registering actions, just as {@link #create(RuleContext)} does.
- * The difference between {@link #create(RuleContext)} and this method is that this method does
- * only what is needed to support tests on the environment besides build the app and test {@code
- * .ipa}s. The {@link #create(RuleContext)} method delegates to this method.
- */
- @Override
- public final ConfiguredTarget create(RuleContext ruleContext)
- throws InterruptedException, RuleErrorException {
- ruleContext.ruleWarning(
- "This rule is deprecated. Please use the new Apple build rules "
- + "(https://github.com/bazelbuild/rules_apple) to build Apple targets.");
-
- Iterable<ObjcProtoProvider> objcProtoProviders =
- ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProtoProvider.SKYLARK_CONSTRUCTOR);
-
- ProtobufSupport protoSupport =
- new ProtobufSupport(
- ruleContext,
- ruleContext.getConfiguration(),
- ImmutableList.<ProtoSourcesProvider>of(),
- objcProtoProviders,
- ProtobufSupport.getTransitivePortableProtoFilters(objcProtoProviders))
- .registerGenerationActions()
- .registerCompilationActions();
- Optional<ObjcProvider> protosObjcProvider = protoSupport.getObjcProvider();
-
- ObjcCommon common = common(ruleContext, protosObjcProvider);
-
- if (!common.getCompilationArtifacts().get().getArchive().isPresent()) {
- ruleContext.ruleError(REQUIRES_SOURCE_ERROR);
- }
-
- if (!ruleContext.getFragment(AppleConfiguration.class).getIosMultiCpus().isEmpty()) {
- ruleContext.ruleError(NO_MULTI_CPUS_ERROR);
- }
-
- NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
- addResourceFilesToBuild(ruleContext, common.getObjcProvider(), filesToBuild);
-
- ExtraLinkArgs extraLinkArgs;
- Iterable<Artifact> extraLinkInputs;
- String bundleFormat;
- XcTestAppProvider testApp = xcTestAppProvider(ruleContext);
- Artifact bundleLoader = testApp.getBundleLoader();
-
- // -bundle causes this binary to be linked as a bundle and not require an entry point
- // (i.e. main())
- // -bundle_loader causes the code in this test to have access to the symbols in the test rig,
- // or more specifically, the flag causes ld to consider the given binary when checking for
- // missing symbols.
- // -rpath @loader_path/Frameworks allows test bundles to load dylibs from the app's
- // Frameworks directory.
- extraLinkArgs =
- new ExtraLinkArgs(
- "-bundle",
- "-bundle_loader",
- bundleLoader.getExecPathString(),
- "-Xlinker",
- "-rpath",
- "-Xlinker",
- "@loader_path/Frameworks");
-
- extraLinkInputs = ImmutableList.of(bundleLoader);
- bundleFormat = ReleaseBundlingSupport.XCTEST_BUNDLE_DIR_FORMAT;
-
- filesToBuild.add(testApp.getIpa());
-
- J2ObjcMappingFileProvider j2ObjcMappingFileProvider =
- J2ObjcMappingFileProvider.union(
- ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcMappingFileProvider.class));
- J2ObjcEntryClassProvider j2ObjcEntryClassProvider =
- new J2ObjcEntryClassProvider.Builder()
- .addTransitive(
- ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcEntryClassProvider.class))
- .build();
-
- CompilationSupport compilationSupport =
- new CompilationSupport.Builder().setRuleContext(ruleContext).setIsTestRule().build();
-
- compilationSupport
- .registerLinkActions(
- common.getObjcProvider(),
- j2ObjcMappingFileProvider,
- j2ObjcEntryClassProvider,
- extraLinkArgs,
- extraLinkInputs,
- DsymOutputType.TEST)
- .registerCompileAndArchiveActions(common)
- .registerFullyLinkAction(
- common.getObjcProvider(),
- ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB))
- .validateAttributes();
-
- AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
- new ReleaseBundlingSupport(
- ruleContext,
- common.getObjcProvider(),
- LinkedBinary.LOCAL_AND_DEPENDENCIES,
- bundleFormat,
- XcodeConfig.getMinimumOsForPlatformType(ruleContext, PlatformType.IOS),
- appleConfiguration.getMultiArchPlatform(PlatformType.IOS))
- .registerActions(DsymOutputType.TEST)
- .addFilesToBuild(filesToBuild, Optional.of(DsymOutputType.TEST))
- .validateResources()
- .validateAttributes();
-
- new ResourceSupport(ruleContext).validateAttributes();
-
- NestedSet<Artifact> filesToBuildSet = filesToBuild.build();
-
- Runfiles.Builder runfilesBuilder =
- new Runfiles.Builder(
- ruleContext.getWorkspaceName(),
- ruleContext.getConfiguration().legacyExternalRunfiles())
- .addRunfiles(ruleContext, RunfilesProvider.DEFAULT_RUNFILES);
-
- NestedSetBuilder<Artifact> filesToBuildBuilder =
- NestedSetBuilder.<Artifact>stableOrder().addTransitive(filesToBuildSet);
-
- InstrumentedFilesProvider instrumentedFilesProvider =
- new CompilationSupport.Builder()
- .setRuleContext(ruleContext)
- .build()
- .getInstrumentedFilesProvider(common);
-
- TestSupport testSupport =
- new TestSupport(ruleContext)
- .registerTestRunnerActions()
- .addRunfiles(runfilesBuilder, instrumentedFilesProvider)
- .addFilesToBuild(filesToBuildBuilder);
-
- Artifact executable = testSupport.generatedTestScript();
-
- Runfiles runfiles = runfilesBuilder.build();
- RunfilesSupport runfilesSupport =
- RunfilesSupport.withExecutable(ruleContext, runfiles, executable);
-
- ImmutableMap.Builder<String, String> execInfoMapBuilder = new ImmutableMap.Builder<>();
- execInfoMapBuilder.put(ExecutionRequirements.REQUIRES_DARWIN, "");
- if (ruleContext.getFragment(ObjcConfiguration.class).runMemleaks()) {
- execInfoMapBuilder.put("nosandbox", "");
- }
-
- return new RuleConfiguredTargetBuilder(ruleContext)
- .setFilesToBuild(filesToBuildBuilder.build())
- .addProvider(RunfilesProvider.simple(runfiles))
- .addNativeDeclaredProvider(new ExecutionInfo(execInfoMapBuilder.build()))
- .addNativeDeclaredProviders(testSupport.getExtraProviders())
- .addProvider(InstrumentedFilesProvider.class, instrumentedFilesProvider)
- .setRunfilesSupport(runfilesSupport, executable)
- .build();
- }
-
- private void addResourceFilesToBuild(
- RuleContext ruleContext, ObjcProvider objcProvider, NestedSetBuilder<Artifact> filesToBuild) {
- IntermediateArtifacts intermediateArtifacts =
- ObjcRuleClasses.intermediateArtifacts(ruleContext);
-
- Iterable<Xcdatamodel> xcdatamodels =
- Xcdatamodels.xcdatamodels(intermediateArtifacts, objcProvider.get(XCDATAMODEL));
- filesToBuild.addAll(Xcdatamodel.outputZips(xcdatamodels));
-
- for (Artifact storyboard : objcProvider.get(STORYBOARD)) {
- filesToBuild.add(intermediateArtifacts.compiledStoryboardZip(storyboard));
- }
- }
-
- /** Constructs an {@link ObjcCommon} instance based on the attributes. */
- private ObjcCommon common(RuleContext ruleContext, Optional<ObjcProvider> protosObjcProvider) {
- CompilationArtifacts compilationArtifacts =
- CompilationSupport.compilationArtifacts(ruleContext);
-
- ObjcCommon.Builder builder =
- new ObjcCommon.Builder(ruleContext)
- .setCompilationAttributes(
- CompilationAttributes.Builder.fromRuleContext(ruleContext).build())
- .setCompilationArtifacts(compilationArtifacts)
- .setResourceAttributes(new ResourceAttributes(ruleContext))
- .addDefines(ruleContext.getExpander().withDataLocations().tokenized("defines"))
- .addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET))
- .addRuntimeDeps(ruleContext.getPrerequisites("runtime_deps", Mode.TARGET))
- .addDeps(ruleContext.getPrerequisites("bundles", Mode.TARGET))
- .addDepObjcProviders(protosObjcProvider.asSet())
- .addNonPropagatedDepObjcProviders(
- ruleContext.getPrerequisites(
- "non_propagated_deps", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR))
- .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
- .setHasModuleMap();
-
- builder
- .addExtraSdkFrameworks(AUTOMATIC_SDK_FRAMEWORKS_FOR_XCTEST)
- .addDepObjcProviders(ImmutableList.of(xcTestAppProvider(ruleContext).getObjcProvider()));
-
- // Add the memleaks library if the --ios_memleaks flag is true. The library pauses the test
- // after all tests have been executed so that leaks can be run.
- ObjcConfiguration config = ruleContext.getFragment(ObjcConfiguration.class);
- if (config.runMemleaks()) {
- builder.addDepObjcProviders(
- ruleContext.getPrerequisites(
- MEMLEAKS_DEP_ATTR, Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR));
- }
-
- return builder.build();
- }
-
- /** Returns the {@link XcTestAppProvider} of the {@code xctest_app} attribute. */
- protected static XcTestAppProvider xcTestAppProvider(RuleContext ruleContext) {
- return ruleContext.getPrerequisite(
- XCTEST_APP_ATTR, Mode.TARGET, XcTestAppProvider.SKYLARK_CONSTRUCTOR);
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
deleted file mode 100644
index 892da8535c..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
+++ /dev/null
@@ -1,157 +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 static com.google.devtools.build.lib.packages.Attribute.attr;
-import static com.google.devtools.build.lib.packages.BuildType.LABEL;
-import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
-import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
-import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
-
-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.analysis.config.BuildConfiguration;
-import com.google.devtools.build.lib.analysis.config.HostTransition;
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
-import com.google.devtools.build.lib.packages.RuleClass;
-import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
-import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
-import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
-import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule;
-import com.google.devtools.build.lib.util.FileType;
-
-/**
- * Rule definition for {@code ios_test} rule in Bazel.
- */
-public class IosTestRule implements RuleDefinition {
-
- @Override
- public RuleClass build(RuleClass.Builder builder, final RuleDefinitionEnvironment env) {
- final Label mcov = env.getToolsLabel("//tools/objc:mcov");
- return builder
- .requiresConfigurationFragments(
- ObjcConfiguration.class,
- J2ObjcConfiguration.class,
- AppleConfiguration.class,
- CppConfiguration.class)
- /*<!-- #BLAZE_RULE(ios_test).IMPLICIT_OUTPUTS -->
- <ul>
- <li><code><var>name</var>.ipa</code>: the test bundle as an
- <code>.ipa</code> file
- </ul>
- <!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS -->*/
- .setImplicitOutputsFunction(ReleaseBundlingSupport.IPA)
- /* <!-- #BLAZE_RULE(ios_test).ATTRIBUTE(target_device) -->
- The device against which to run the test.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(
- attr(IosTest.TARGET_DEVICE, LABEL)
- .allowedFileTypes()
- .allowedRuleClasses("ios_device")
- .value(env.getToolsLabel("//tools/objc/sim_devices:default")))
- /* <!-- #BLAZE_RULE(ios_test).ATTRIBUTE(xctest) -->
- Deprecated. Does not affect how the test is built.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(attr(IosTest.IS_XCTEST_ATTR, BOOLEAN).value(true))
- /* <!-- #BLAZE_RULE(ios_test).ATTRIBUTE(xctest_app) -->
- An <code>ios_application</code> target that contains the app bundle to test against with
- XCTest. This attribute is only valid if <code>xctest</code> is true.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(
- attr(IosTest.XCTEST_APP_ATTR, LABEL)
- .value(env.getLabel("//tools/objc:xctest_app"))
- .allowedFileTypes()
- .mandatoryProviders(XcTestAppProvider.SKYLARK_CONSTRUCTOR.id()))
- .override(
- attr(BundlingRule.INFOPLIST_ATTR, LABEL)
- .value(env.getLabel("//tools/objc:xctest_infoplist"))
- .allowedFileTypes(ObjcRuleClasses.PLIST_TYPE))
- /* <!-- #BLAZE_RULE(ios_test).ATTRIBUTE(ios_test_target_device) -->
- The device against how to run the test. If this attribute is defined, the test will run on
- the lab device. Otherwise, the test will run on simulator.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(
- attr(IosTest.TEST_TARGET_DEVICE_ATTR, LABEL)
- .allowedFileTypes()
- .allowedRuleClasses("ios_lab_device"))
- /* <!-- #BLAZE_RULE(ios_test).ATTRIBUTE(ios_device_arg) -->
- Extra arguments to pass to the <code>ios_test_target_device</code>'s binary. They should be
- in the form KEY=VALUE or simply KEY (check your device's documentation for allowed
- parameters).
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(attr(IosTest.DEVICE_ARG_ATTR, STRING_LIST))
- /* <!-- #BLAZE_RULE(ios_test).ATTRIBUTE(plugins) -->
- Plugins to pass to the test runner.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(attr(IosTest.PLUGINS_ATTR, LABEL_LIST).allowedFileTypes(FileType.of("_deploy.jar")))
- .add(
- attr(IosTest.TEST_TEMPLATE_ATTR, LABEL)
- .value(env.getToolsLabel("//tools/objc:ios_test.sh.bazel_template")))
- .add(
- attr(IosTest.TEST_RUNNER_ATTR, LABEL)
- .value(env.getToolsLabel("//tools/objc:testrunner")))
- .add(
- attr(IosTest.MEMLEAKS_DEP_ATTR, LABEL)
- .value(env.getToolsLabel("//tools/objc/memleaks:memleaks")))
- .add(
- attr(IosTest.MEMLEAKS_PLUGIN_ATTR, LABEL)
- .value(env.getToolsLabel("//tools/objc:memleaks_plugin")))
- .add(
- attr(IosTest.OBJC_GCOV_ATTR, LABEL)
- .cfg(HostTransition.INSTANCE)
- .value(env.getToolsLabel("//tools/objc:gcov")))
- // TODO(b/65746853): provide a way to do this without passing the entire configuration
- .add(
- attr(IosTest.MCOV_TOOL_ATTR, LABEL)
- .cfg(HostTransition.INSTANCE)
- .value(
- LateBoundDefault.fromTargetConfiguration(
- BuildConfiguration.class,
- mcov,
- (rule, attributes, configuration) ->
- configuration.isCodeCoverageEnabled() ? mcov : null)))
- .cfg(AppleCrosstoolTransition.APPLE_CROSSTOOL_TRANSITION)
- .build();
- }
-
- @Override
- public Metadata getMetadata() {
- return RuleDefinition.Metadata.builder()
- .name("ios_test")
- .type(RuleClassType.TEST)
- .ancestors(
- BaseRuleClasses.BaseRule.class,
- BaseRuleClasses.TestBaseRule.class,
- ObjcRuleClasses.ReleaseBundlingRule.class,
- ObjcRuleClasses.LinkingRule.class,
- ObjcRuleClasses.SimulatorRule.class)
- .factoryClass(IosTest.class)
- .build();
- }
-}
-
-/*<!-- #BLAZE_RULE (NAME = ios_test, TYPE = TEST, FAMILY = Objective-C) -->
-
-<p><strong>This rule is deprecated.</strong> Please use the new Apple build rules
-(<a href="https://github.com/bazelbuild/rules_apple">https://github.com/bazelbuild/rules_apple</a>)
-to build Apple targets.</p>
-
-<p>This rule provides a way to build iOS unit tests written in the XCTest test framework
-on both iOS simulator and real devices.
-</p>
-
-<!-- #END_BLAZE_RULE -->*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
index 1a30d4b889..328b212045 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
@@ -17,6 +17,7 @@ package com.google.devtools.build.lib.rules.objc;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.NESTED_BUNDLE;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.FAMILIES_ATTR;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
@@ -24,6 +25,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
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.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType;
import com.google.devtools.build.lib.rules.apple.XcodeConfig;
@@ -39,6 +41,14 @@ import java.util.List;
*/
public class ObjcBundleLibrary implements RuleConfiguredTargetFactory {
+ @VisibleForTesting
+ static final String INVALID_FAMILIES_ERROR =
+ "Expected one or two strings from the list 'iphone', 'ipad'";
+
+ @VisibleForTesting
+ static final String NO_ASSET_CATALOG_ERROR_FORMAT =
+ "a value was specified (%s), but this app does not have any asset catalogs";
+
@Override
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException {
@@ -93,7 +103,7 @@ public class ObjcBundleLibrary implements RuleConfiguredTargetFactory {
}
if (families.isEmpty()) {
- ruleContext.attributeError(FAMILIES_ATTR, ReleaseBundling.INVALID_FAMILIES_ERROR);
+ ruleContext.attributeError(FAMILIES_ATTR, INVALID_FAMILIES_ERROR);
}
return new Bundling.Builder()
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 20f8757863..c43821c084 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
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.rules.objc;
-import static com.google.devtools.build.lib.packages.Attribute.ANY_RULE;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
@@ -40,9 +39,7 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.HostTransition;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
-import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.RuleClass;
@@ -51,7 +48,6 @@ import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.ApplePlatform;
-import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType;
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.XcodeConfigProvider;
@@ -1159,275 +1155,6 @@ public class ObjcRuleClasses {
}
/**
- * Common attributes for {@code objc_*} rules that create a bundle meant for release (e.g.
- * application or extension).
- */
- public static class ReleaseBundlingRule implements RuleDefinition {
- static final String APP_ICON_ATTR = "app_icon";
- static final String BUNDLE_ID_ATTR = "bundle_id";
- static final String DEFAULT_PROVISIONING_PROFILE_ATTR = ":default_provisioning_profile";
- static final String ENTITLEMENTS_ATTR = "entitlements";
- static final String EXTRA_ENTITLEMENTS_ATTR = ":extra_entitlements";
- static final String DEBUG_ENTITLEMENTS_ATTR = "$device_debug_entitlements";
- static final String LAUNCH_IMAGE_ATTR = "launch_image";
- static final String LAUNCH_STORYBOARD_ATTR = "launch_storyboard";
- static final String PROVISIONING_PROFILE_ATTR = "provisioning_profile";
-
- @Override
- public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
- return builder
- /* <!-- #BLAZE_RULE($objc_release_bundling_rule).ATTRIBUTE(entitlements) -->
- The entitlements file required for device builds of this application.
-
- See
- <a href="https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/AboutEntitlements.html">the apple documentation</a>
- for more information. If absent, the default entitlements from the
- provisioning profile will be used.
- <p>
- The following variables are substituted: <code>$(CFBundleIdentifier)</code> with the
- bundle id and <code>$(AppIdentifierPrefix)</code> with the value of the
- <code>ApplicationIdentifierPrefix</code> key from this target's provisioning profile (or
- the default provisioning profile, if none is specified).
- <p>
- Bazel does not currently support adding entitlements to simulator builds. This
- means that if you rely on behavior which must be specified in entitlements (like App
- Groups) it will only work on a device. You can work around this by inlining the
- entitlements into your binary. e.g.
- <pre><code>
- #if TARGET_OS_SIMULATOR
- __asm(&quot;.section __TEXT,__entitlements&quot;);
- __asm(&quot;.ascii \&quot;&quot;
- &quot;&lt;?xml version=\\\&quot;1.0\\\&quot; encoding=\\\&quot;UTF-8\\\&quot;?&gt;\n&quot;
- &quot;&lt;!DOCTYPE plist PUBLIC \\\&quot;-//Apple//DTD PLIST 1.0//EN\\\&quot; &quot;
- &quot;\\\&quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd\\\&quot;&gt;&quot;
- &quot;&lt;plist version=\\\&quot;1.0\\\&quot;&gt;&quot;
- &quot;&lt;dict&gt;&quot;
- &quot;&lt;key&gt;com.apple.security.application-groups&lt;/key&gt;&quot;
- &quot;&lt;array&gt;&quot;
- &quot;&lt;string&gt;group.com.your.company&lt;/string&gt;&quot;
- &quot;&lt;/array&gt;&quot;
- &quot;&lt;/dict&gt;&quot;
- &quot;&lt;/plist&gt;&quot;
- &quot;\&quot;
- #endif
- </code></pre>
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(attr(ENTITLEMENTS_ATTR, LABEL).allowedFileTypes(ENTITLEMENTS_TYPE))
- .add(
- attr(EXTRA_ENTITLEMENTS_ATTR, LABEL)
- .singleArtifact()
- .cfg(HostTransition.INSTANCE)
- .value(
- LateBoundDefault.fromTargetConfiguration(
- ObjcConfiguration.class,
- null,
- (rule, attributes, objcConfig) -> objcConfig.getExtraEntitlements()))
- .allowedFileTypes(ENTITLEMENTS_TYPE))
- .add(
- attr(DEBUG_ENTITLEMENTS_ATTR, LABEL)
- .singleArtifact()
- .cfg(HostTransition.INSTANCE)
- .value(env.getToolsLabel("//tools/objc:device_debug_entitlements.plist")))
- /* <!-- #BLAZE_RULE($objc_release_bundling_rule).ATTRIBUTE(provisioning_profile) -->
- The provisioning profile (.mobileprovision file) to use when bundling
- the application.
-
- This is only used for non-simulator builds.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(
- attr(PROVISIONING_PROFILE_ATTR, LABEL)
- .singleArtifact()
- .allowedFileTypes(FileType.of(".mobileprovision")))
- // Will be used if provisioning_profile is null.
- .add(
- attr(DEFAULT_PROVISIONING_PROFILE_ATTR, LABEL)
- .singleArtifact()
- .allowedFileTypes(FileType.of(".mobileprovision"))
- .value(
- LateBoundDefault.fromTargetConfiguration(
- AppleConfiguration.class,
- null,
- (rule, attributes, appleConfig) -> {
- if (appleConfig.getMultiArchPlatform(PlatformType.IOS)
- != ApplePlatform.IOS_DEVICE) {
- return null;
- }
- if (attributes.isAttributeValueExplicitlySpecified(
- PROVISIONING_PROFILE_ATTR)) {
- return null;
- }
- return appleConfig.getDefaultProvisioningProfileLabel();
- })))
- /* <!-- #BLAZE_RULE($objc_release_bundling_rule).ATTRIBUTE(app_icon) -->
- The name of the application icon.
-
- The icon should be in one of the asset catalogs of this target or
- a (transitive) dependency. In a new project, this is initialized
- to "AppIcon" by Xcode.
- <p>
- If the application icon is not in an asset catalog, do not use this
- attribute. Instead, add a CFBundleIcons entry to the Info.plist file.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(attr(APP_ICON_ATTR, STRING))
- /* <!-- #BLAZE_RULE($objc_release_bundling_rule).ATTRIBUTE(launch_image) -->
- The name of the launch image.
-
- The icon should be in one of the asset catalogs of this target or
- a (transitive) dependency. In a new project, this is initialized
- to "LaunchImage" by Xcode.
- <p>
- If the launch image is not in an asset catalog, do not use this
- attribute. Instead, add an appropriately-named image resource to the
- bundle.
- <p>
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(attr(LAUNCH_IMAGE_ATTR, STRING))
- /* <!-- #BLAZE_RULE($objc_release_bundling_rule).ATTRIBUTE(launch_storyboard) -->
- The location of the launch storyboard (.xib or .storyboard).
-
- The provided storyboard will be compiled to the appropriate format
- (.nib or .storyboardc respectively) and placed in the root of the
- final package. If the storyboard's immediate containing directory is
- named *.lproj (e.g. en.lproj, Base.lproj), it will be placed under a
- directory of that name in the final bundle. This allows for
- localizable UI.
- <p>
- The generated storyboard is registered in the final bundle's
- <code>Info.plist</code> under the key
- <code>UILaunchStoryboardName</code>.
- <p>
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(
- attr(LAUNCH_STORYBOARD_ATTR, LABEL)
- .direct_compile_time_input()
- .allowedFileTypes(FileTypeSet.of(XIB_TYPE, STORYBOARD_TYPE)))
- /* <!-- #BLAZE_RULE($objc_release_bundling_rule).ATTRIBUTE(bundle_id) -->
- The bundle ID (reverse-DNS path followed by app name) of the binary.
-
- If specified, it will override the bundle ID specified in the associated plist file. If
- no bundle ID is specified on either this attribute or in the plist file, a junk value
- will be used.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(
- attr(BUNDLE_ID_ATTR, STRING)
- .value(
- new Attribute.ComputedDefault() {
- @Override
- public Object getDefault(AttributeMap rule) {
- // For tests and similar, we don't want to force people to explicitly
- // specify throw-away data.
- return "example." + rule.getName();
- }
- }))
- .build();
- }
- @Override
- public Metadata getMetadata() {
- return RuleDefinition.Metadata.builder()
- .name("$objc_release_bundling_rule")
- .type(RuleClassType.ABSTRACT)
- .ancestors(BundlingRule.class, ReleaseBundlingToolsRule.class)
- .build();
- }
- }
-
- /**
- * Common attributes for rules that require tools to create a bundle meant for
- * release (e.g. application or extension). Specifically, for rules which use the
- * {@link ReleaseBundlingSupport} helper class.
- */
- public static class ReleaseBundlingToolsRule implements RuleDefinition {
- @Override
- public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
- return builder
- .add(
- attr("$bundlemerge", LABEL)
- .cfg(HostTransition.INSTANCE)
- .exec()
- .value(env.getToolsLabel("//tools/objc:bundlemerge")))
- .add(
- attr("$environment_plist", LABEL)
- .cfg(HostTransition.INSTANCE)
- .exec()
- .value(env.getToolsLabel("//tools/objc:environment_plist")))
- .add(
- attr("$swiftstdlibtoolwrapper", LABEL)
- .cfg(HostTransition.INSTANCE)
- .exec()
- .value(env.getToolsLabel("//tools/objc:swiftstdlibtoolwrapper")))
- .build();
- }
- @Override
- public Metadata getMetadata() {
- return RuleDefinition.Metadata.builder()
- .name("$release_bundling_tools_rule")
- .type(RuleClassType.ABSTRACT)
- .build();
- }
- }
-
- /**
- * Common attributes for {@code objc_*} rules that create a signed IPA.
- */
- public static class IpaRule implements RuleDefinition {
- @Override
- public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
- return builder
- /* <!-- #BLAZE_RULE($objc_ipa_rule).ATTRIBUTE(ipa_post_processor) -->
- A tool that edits this target's IPA output after it is assembled but before it is
- (optionally) signed.
- <p>
- The tool is invoked with a single positional argument which represents the path to a
- directory containing the unzipped contents of the IPA. The only entry in this directory
- will be the <code>Payload</code> root directory of the IPA (for an ios_application) or
- the <code>PlugIns</code> root directory (for an ios_extension). Any changes made by the
- tool must be made in this directory, whose contents will be (optionally) signed and then
- zipped up as the final IPA after the tool terminates.
- <p>
- The tool's execution must be hermetic given these inputs to ensure that its result can be
- safely cached.
- <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
- .add(
- attr("ipa_post_processor", LABEL)
- .allowedRuleClasses(ANY_RULE)
- .allowedFileTypes(FileTypeSet.ANY_FILE)
- .exec())
- .build();
- }
-
- @Override
- public Metadata getMetadata() {
- return RuleDefinition.Metadata.builder()
- .name("$objc_ipa_rule")
- .type(RuleClassType.ABSTRACT)
- .build();
- }
- }
-
- /**
- * Common attributes for {@code objc_*} rules that use the iOS simulator.
- */
- public static class SimulatorRule implements RuleDefinition {
- static final String STD_REDIRECT_DYLIB_ATTR = "$std_redirect_dylib";
-
- @Override
- public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
- return builder
- // Needed to run the binary in the simulator.
- .add(attr(STD_REDIRECT_DYLIB_ATTR, LABEL).cfg(HostTransition.INSTANCE).exec()
- .value(env.getToolsLabel("//tools/objc:StdRedirect.dylib")))
- .build();
- }
- @Override
- public Metadata getMetadata() {
- return RuleDefinition.Metadata.builder()
- .name("$objc_simulator_rule")
- .type(RuleClassType.ABSTRACT)
- .build();
- }
- }
-
- /**
* Common attributes for {@code objc_*} rules that need to call xcrun.
*/
public static class XcrunRule implements RuleDefinition {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundling.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundling.java
deleted file mode 100644
index 509661d421..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundling.java
+++ /dev/null
@@ -1,395 +0,0 @@
-// 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.ObjcRuleClasses.BundlingRule.FAMILIES_ATTR;
-import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.APP_ICON_ATTR;
-import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.BUNDLE_ID_ATTR;
-import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.DEFAULT_PROVISIONING_PROFILE_ATTR;
-import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.LAUNCH_IMAGE_ATTR;
-import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.LAUNCH_STORYBOARD_ATTR;
-import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.PROVISIONING_PROFILE_ATTR;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableSet;
-import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
-import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.rules.objc.TargetDeviceFamily.InvalidFamilyNameException;
-import com.google.devtools.build.lib.rules.objc.TargetDeviceFamily.RepeatedFamilyNameException;
-import com.google.devtools.build.lib.syntax.Type;
-import java.util.List;
-
-/**
- * Contains information regarding the creation of a released bundle such as an application or
- * extension. The information which generally includes app icons, launch image, targeted devices and
- * other data for potential signing is used to create a releasable bundle out of the bundle created
- * using {@link Bundling} object.
- *
- * @deprecated The native bundling rules have been deprecated. This class will be removed in the
- * future.
- */
-@Deprecated
-@Immutable
-final class ReleaseBundling {
- static final class Builder {
- private Artifact ipaArtifact;
- private String bundleId;
- private String primaryBundleId;
- private String fallbackBundleId;
- private String appIcon;
- private String launchImage;
- private Artifact launchStoryboard;
- private Artifact provisioningProfile;
- private String provisioningProfileAttributeName;
- private final NestedSetBuilder<Artifact> infoplistInputs = NestedSetBuilder.stableOrder();
- private Iterable<Artifact> infoPlistsFromRule;
- private ImmutableSet<TargetDeviceFamily> families;
- private IntermediateArtifacts intermediateArtifacts;
- private String artifactPrefix;
- private Artifact entitlements;
- private Artifact extraEntitlements;
-
- public Builder setIpaArtifact(Artifact ipaArtifact) {
- this.ipaArtifact = ipaArtifact;
- return this;
- }
-
- public Builder setBundleId(String bundleId) {
- this.bundleId = bundleId;
- return this;
- }
-
- public Builder setPrimaryBundleId(String primaryId) {
- this.primaryBundleId = primaryId;
- return this;
- }
-
- public Builder setFallbackBundleId(String fallbackId) {
- this.fallbackBundleId = fallbackId;
- return this;
- }
-
- public Builder setAppIcon(String appIcon) {
- this.appIcon = appIcon;
- return this;
- }
-
- public Builder setLaunchImage(String launchImage) {
- this.launchImage = launchImage;
- return this;
- }
-
- public Builder setLaunchStoryboard(Artifact launchStoryboard) {
- this.launchStoryboard = launchStoryboard;
- return this;
- }
-
- public Builder setProvisioningProfile(Artifact provisioningProfile) {
- this.provisioningProfile = provisioningProfile;
- return this;
- }
-
- public Builder setProvisioningProfileAttributeName(String provisioningProfileAttributeName) {
- this.provisioningProfileAttributeName = provisioningProfileAttributeName;
- return this;
- }
-
- public Builder addInfoplistInput(Artifact infoPlist) {
- this.infoplistInputs.add(infoPlist);
- return this;
- }
-
- public Builder addInfoplistInputs(Iterable<Artifact> infoplists) {
- this.infoplistInputs.addAll(infoplists);
- return this;
- }
-
- public Builder setInfoPlistsFromRule(Iterable<Artifact> infoPlistsFromRule) {
- this.infoPlistsFromRule = infoPlistsFromRule;
- return this;
- }
-
- public Builder setIntermediateArtifacts(IntermediateArtifacts intermediateArtifacts) {
- this.intermediateArtifacts = intermediateArtifacts;
- return this;
- }
-
- public Builder setTargetDeviceFamilies(ImmutableSet<TargetDeviceFamily> families) {
- this.families = families;
- return this;
- }
-
- public Builder setArtifactPrefix(String artifactPrefix) {
- this.artifactPrefix = artifactPrefix;
- return this;
- }
-
- public Builder setEntitlements(Artifact entitlements) {
- this.entitlements = entitlements;
- return this;
- }
-
- public ReleaseBundling build() {
- Preconditions.checkNotNull(intermediateArtifacts, "intermediateArtifacts");
- Preconditions.checkNotNull(families, FAMILIES_ATTR);
- return new ReleaseBundling(
- ipaArtifact,
- bundleId,
- primaryBundleId,
- fallbackBundleId,
- appIcon,
- launchImage,
- launchStoryboard,
- provisioningProfile,
- provisioningProfileAttributeName,
- infoplistInputs.build(),
- infoPlistsFromRule,
- families,
- intermediateArtifacts,
- artifactPrefix,
- entitlements,
- extraEntitlements);
- }
- }
-
- /**
- * Returns a {@link ReleaseBundling} object constructed using the information available in given
- * context.
- */
- public static ReleaseBundling releaseBundling(RuleContext ruleContext)
- throws InterruptedException {
- Preconditions.checkState(!Strings.isNullOrEmpty(
- ruleContext.attributes().get(BUNDLE_ID_ATTR, Type.STRING)),
- "requires a bundle_id value");
- String primaryBundleId = null;
- String fallbackBundleId = null;
- Artifact provisioningProfile;
-
- if (ruleContext.attributes().isAttributeValueExplicitlySpecified(BUNDLE_ID_ATTR)) {
- primaryBundleId = ruleContext.attributes().get(BUNDLE_ID_ATTR, Type.STRING);
- } else {
- fallbackBundleId = ruleContext.attributes().get(BUNDLE_ID_ATTR, Type.STRING);
- }
-
- Artifact explicitProvisioningProfile =
- ruleContext.getPrerequisiteArtifact(PROVISIONING_PROFILE_ATTR, Mode.TARGET);
- if (explicitProvisioningProfile != null) {
- provisioningProfile = explicitProvisioningProfile;
- } else {
- provisioningProfile = ruleContext.getPrerequisiteArtifact(DEFAULT_PROVISIONING_PROFILE_ATTR,
- Mode.TARGET);
- }
-
- ImmutableSet<TargetDeviceFamily> families = null;
- List<String> rawFamilies = ruleContext.attributes().get(FAMILIES_ATTR, Type.STRING_LIST);
- try {
- families = ImmutableSet.copyOf(TargetDeviceFamily.fromNamesInRule(rawFamilies));
- } catch (InvalidFamilyNameException | RepeatedFamilyNameException e) {
- families = ImmutableSet.of();
- }
-
- if (families.isEmpty()) {
- ruleContext.attributeError(FAMILIES_ATTR, INVALID_FAMILIES_ERROR);
- }
-
- return new ReleaseBundling.Builder()
- .setIpaArtifact(ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA))
- .setBundleId(ruleContext.attributes().get(BUNDLE_ID_ATTR, Type.STRING))
- .setPrimaryBundleId(primaryBundleId)
- .setFallbackBundleId(fallbackBundleId)
- .setAppIcon(Strings.emptyToNull(ruleContext.attributes().get(APP_ICON_ATTR, Type.STRING)))
- .setLaunchImage(Strings.emptyToNull(
- ruleContext.attributes().get(LAUNCH_IMAGE_ATTR, Type.STRING)))
- .setLaunchStoryboard(
- ruleContext.getPrerequisiteArtifact(LAUNCH_STORYBOARD_ATTR, Mode.TARGET))
- .setProvisioningProfile(provisioningProfile)
- .setProvisioningProfileAttributeName(PROVISIONING_PROFILE_ATTR)
- .setTargetDeviceFamilies(families)
- .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
- .setEntitlements(ruleContext.getPrerequisiteArtifact("entitlements", Mode.TARGET))
- .build();
- }
-
- @VisibleForTesting
- static final String INVALID_FAMILIES_ERROR =
- "Expected one or two strings from the list 'iphone', 'ipad'";
- private final Artifact ipaArtifact;
- private final String bundleId;
- private final String fallbackBundleId;
- private final String primaryBundleId;
- private final String appIcon;
- private final String launchImage;
- private final Artifact launchStoryboard;
- private final Artifact provisioningProfile;
- private final String provisioningProfileAttributeName;
- private final NestedSet<Artifact> infoplistInputs;
- private final ImmutableSet<TargetDeviceFamily> families;
- private final IntermediateArtifacts intermediateArtifacts;
- private final Iterable<Artifact> infoPlistsFromRule;
- private final String artifactPrefix;
- private final Artifact entitlements;
-
- private ReleaseBundling(
- Artifact ipaArtifact,
- String bundleId,
- String primaryBundleId,
- String fallbackBundleId,
- String appIcon,
- String launchImage,
- Artifact launchStoryboard,
- Artifact provisioningProfile,
- String provisioningProfileAttributeName,
- NestedSet<Artifact> infoplistInputs,
- Iterable<Artifact> infoPlistsFromRule,
- ImmutableSet<TargetDeviceFamily> families,
- IntermediateArtifacts intermediateArtifacts,
- String artifactPrefix,
- Artifact entitlements,
- Artifact extraEntitlements) {
- this.ipaArtifact = Preconditions.checkNotNull(ipaArtifact);
- this.bundleId = bundleId;
- this.primaryBundleId = primaryBundleId;
- this.fallbackBundleId = fallbackBundleId;
- this.appIcon = appIcon;
- this.launchImage = launchImage;
- this.launchStoryboard = launchStoryboard;
- this.provisioningProfile = provisioningProfile;
- this.provisioningProfileAttributeName =
- Preconditions.checkNotNull(provisioningProfileAttributeName);
- this.infoplistInputs = Preconditions.checkNotNull(infoplistInputs);
- this.infoPlistsFromRule = infoPlistsFromRule;
- this.families = Preconditions.checkNotNull(families);
- this.intermediateArtifacts = Preconditions.checkNotNull(intermediateArtifacts);
- this.artifactPrefix = artifactPrefix;
- this.entitlements = entitlements;
- }
-
- /**
- * Returns the {@link Artifact} containing the final ipa bundle.
- */
- public Artifact getIpaArtifact() {
- return ipaArtifact;
- }
-
- /**
- * Returns the identifier of this bundle.
- */
- public String getBundleId() {
- return bundleId;
- }
-
- /**
- * Returns primary bundle ID to use, can be null.
- */
- public String getPrimaryBundleId() {
- return primaryBundleId;
- }
-
- /**
- * Returns fallback bundle ID to use when primary isn't set.
- */
- public String getFallbackBundleId() {
- return fallbackBundleId;
- }
-
- /**
- * Returns the app icon name for this bundle, can be null.
- */
- public String getAppIcon() {
- return appIcon;
- }
-
- /**
- * Returns the launch image name for this bundle, can be null.
- */
- public String getLaunchImage() {
- return launchImage;
- }
-
- /**
- * Returns an {@link Artifact} containing launch storyboard for this bundle, can be null.
- */
- public Artifact getLaunchStoryboard() {
- return launchStoryboard;
- }
-
- /**
- * Returns an {@link Artifact} containing provisioning profile used to sign this bundle,
- * can be null.
- */
- public Artifact getProvisioningProfile() {
- return provisioningProfile;
- }
-
- /**
- * Returns the list of plists to be merged to final bundle.
- */
- public NestedSet<Artifact> getInfoplistInputs() {
- return infoplistInputs;
- }
-
- /**
- * Returns the list of {@link TargetDeviceFamily} values this bundle is targeting.
- * If empty, the default values specified by {@link FAMILIES_ATTR} will be used.
- */
- public ImmutableSet<TargetDeviceFamily> getTargetDeviceFamilies() {
- return families;
- }
-
- /**
- * Returns {@link IntermediateArtifacts} used to create this bundle.
- */
- public IntermediateArtifacts getIntermediateArtifacts() {
- return intermediateArtifacts;
- }
-
- /**
- * Returns the name of the attribute which is used to specifiy the provisioning profile.
- */
- public String getProvisioningProfileAttrName() {
- return provisioningProfileAttributeName;
- }
-
- /**
- * Adds any info plists specified in the given rule's {@code infoplists} attribute as inputs to
- * this bundle's {@code Info.plist} (which is merged from any such added plists plus some
- * additional information).
- */
- public Iterable<Artifact> getInfoPlistsFromRule() {
- return infoPlistsFromRule;
- }
-
- /**
- * Returns the prefix to be added to all generated artifact names, can be null. This is useful
- * to disambiguate artifacts for multiple bundles created with different names withing same rule.
- */
- public String getArtifactPrefix() {
- return artifactPrefix;
- }
-
- /**
- * Returns an {@link Artifact} containing the entitlements used to sign this bundle for
- * non-simulator builds; can be null.
- */
- public Artifact getEntitlements() {
- return entitlements;
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
deleted file mode 100644
index b73b8cbe4c..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
+++ /dev/null
@@ -1,1250 +0,0 @@
-// Copyright 2015 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.common.base.Preconditions.checkNotNull;
-import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_SWIFT;
-import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.APP_ICON_ATTR;
-import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.DEBUG_ENTITLEMENTS_ATTR;
-import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.EXTRA_ENTITLEMENTS_ATTR;
-
-import com.dd.plist.NSArray;
-import com.dd.plist.NSDictionary;
-import com.dd.plist.NSObject;
-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.common.collect.Iterables;
-import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.analysis.BuildInfo;
-import com.google.devtools.build.lib.analysis.FilesToRunProvider;
-import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.Runfiles;
-import com.google.devtools.build.lib.analysis.RunfilesSupport;
-import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
-import com.google.devtools.build.lib.analysis.actions.BinaryFileWriteAction;
-import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
-import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
-import com.google.devtools.build.lib.analysis.actions.SpawnAction;
-import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
-import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
-import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
-import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.collect.nestedset.Order;
-import com.google.devtools.build.lib.packages.BuildType;
-import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
-import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
-import com.google.devtools.build.lib.rules.apple.ApplePlatform;
-import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType;
-import com.google.devtools.build.lib.rules.apple.DottedVersion;
-import com.google.devtools.build.lib.rules.apple.XcodeConfig;
-import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
-import com.google.devtools.build.lib.rules.objc.BundleSupport.ExtraActoolArgs;
-import com.google.devtools.build.lib.rules.objc.Bundling.Builder;
-import com.google.devtools.build.lib.shell.ShellUtils;
-import java.util.List;
-import java.util.Map.Entry;
-import javax.annotation.Nullable;
-
-/**
- * Support for released bundles, such as an application or extension. Such a bundle is generally
- * composed of a top-level {@link BundleSupport bundle}, potentially signed, as well as some debug
- * information, if {@link ObjcConfiguration#generateDsym() requested}.
- *
- * <p>Contains actions, validation logic and provider value generation.
- *
- * <p>Methods on this class can be called in any order without impacting the result.
- *
- * @deprecated The native bundling rules have been deprecated. This class will be removed in the
- * future.
- */
-@Deprecated
-public final class ReleaseBundlingSupport {
-
- /**
- * Template for the containing application folder.
- */
- public static final SafeImplicitOutputsFunction IPA = fromTemplates("%{name}.ipa");
-
- @VisibleForTesting
- static final String NO_ASSET_CATALOG_ERROR_FORMAT =
- "a value was specified (%s), but this app does not have any asset catalogs";
- @VisibleForTesting
- static final String DEVICE_NO_PROVISIONING_PROFILE =
- "Provisioning profile must be set for device build";
-
- @VisibleForTesting
- static final String PROVISIONING_PROFILE_BUNDLE_FILE = "embedded.mobileprovision";
- @VisibleForTesting
- static final String APP_BUNDLE_DIR_FORMAT = "Payload/%s.app";
- @VisibleForTesting
- static final String XCTEST_BUNDLE_DIR_FORMAT = "Payload/%s.xctest";
- @VisibleForTesting
- static final String EXTENSION_BUNDLE_DIR_FORMAT = "PlugIns/%s.appex";
- @VisibleForTesting
- static final String FRAMEWORK_BUNDLE_DIR_FORMAT = "Frameworks/%s.framework";
-
- /**
- * Command string for "sed" that tries to extract the application version number from a larger
- * string. For example, from "foo_1.2.3_RC00" this would extract "1.2.3". This regex looks for
- * versions of the format "x.y" or "x.y.z", which may be preceded and/or followed by other text,
- * such as a project name or release candidate number.
- *
- * <p>This command also preserves double quotes around the string, if any.
- */
- private static final String EXTRACT_VERSION_NUMBER_SED_COMMAND =
- "s#\\(\"\\)\\{0,1\\}\\(.*_\\)\\{0,1\\}\\([0-9][0-9]*\\(\\.[0-9][0-9]*\\)\\{1,2\\}\\)"
- + "\\(_[^\"]*\\)\\{0,1\\}\\(\"\\)\\{0,1\\}#\\1\\3\\6#";
-
- private final Attributes attributes;
- private final BundleSupport bundleSupport;
- private final RuleContext ruleContext;
- private final Bundling bundling;
- private final ObjcProvider objcProvider;
- private final LinkedBinary linkedBinary;
- private final IntermediateArtifacts intermediateArtifacts;
- private final ReleaseBundling releaseBundling;
- private final ApplePlatform platform;
-
- /**
- * Indicator as to whether this rule generates a binary directly or whether only dependencies
- * should be considered.
- */
- enum LinkedBinary {
- /**
- * This rule generates its own binary which should be included as well as dependency-generated
- * binaries.
- */
- LOCAL_AND_DEPENDENCIES,
-
- /**
- * This rule does not generate its own binary, only consider binaries from dependencies.
- */
- DEPENDENCIES_ONLY
- }
-
- /**
- * Creates a new release bundling support within the given rule context.
- *
- * @param ruleContext context for the application-generating rule
- * @param objcProvider provider containing all dependencies' information as well as some of this
- * rule's
- * @param linkedBinary whether to look for a linked binary from this rule and dependencies or just
- * the latter
- * @param bundleDirFormat format string representing the bundle's directory with a single
- * placeholder for the target name (e.g. {@code "Payload/%s.app"})
- * @param bundleName name of the bundle, used with bundleDirFormat
- * @param bundleMinimumOsVersion the minimum OS version this bundle's plist should be generated
- * for (<b>not</b> the minimum OS version its binary is compiled with, that needs to be set
- * through the configuration)
- * @param releaseBundling the {@link ReleaseBundling} containing information for creating a
- * releaseable bundle.
- * @param platform the platform that bundles will be created for using this support
- */
- ReleaseBundlingSupport(
- RuleContext ruleContext,
- ObjcProvider objcProvider,
- LinkedBinary linkedBinary,
- String bundleDirFormat,
- String bundleName,
- DottedVersion bundleMinimumOsVersion,
- ReleaseBundling releaseBundling,
- ApplePlatform platform) {
- this.platform = platform;
- this.linkedBinary = linkedBinary;
- this.attributes = new Attributes(ruleContext);
- this.ruleContext = ruleContext;
- this.objcProvider = objcProvider;
- this.releaseBundling = releaseBundling;
- this.intermediateArtifacts = releaseBundling.getIntermediateArtifacts();
- this.bundling = bundling(ruleContext, objcProvider, bundleDirFormat, bundleName,
- bundleMinimumOsVersion);
- // TODO(cparsons): Take the rule configuration as a param instead of inferring.
- bundleSupport = new BundleSupport(ruleContext,
- ruleContext.getFragment(AppleConfiguration.class), platform,
- bundling, extraActoolArgs());
- }
-
- /**
- * Creates a new application support within the given rule context.
- *
- * @param ruleContext context for the application-generating rule
- * @param objcProvider provider containing all dependencies' information as well as some of this
- * rule's
- * @param linkedBinary whether to look for a linked binary from this rule and dependencies or just
- * the latter
- * @param bundleDirFormat format string representing the bundle's directory with a single
- * placeholder for the target name (e.g. {@code "Payload/%s.app"})
- * @param bundleName name of the bundle, used with bundleDirFormat
- * @param platform the platform that bundles will be created for using this support
- */
- ReleaseBundlingSupport(
- RuleContext ruleContext,
- ObjcProvider objcProvider,
- LinkedBinary linkedBinary,
- String bundleDirFormat,
- String bundleName,
- DottedVersion bundleMinimumOsVersion,
- ApplePlatform platform)
- throws InterruptedException {
- this(
- ruleContext,
- objcProvider,
- linkedBinary,
- bundleDirFormat,
- bundleName,
- bundleMinimumOsVersion,
- ReleaseBundling.releaseBundling(ruleContext),
- platform);
- }
-
- /**
- * Creates a new application support within the given rule context.
- *
- * <p>{@code bundleName} defaults to label name
- *
- * @param ruleContext context for the application-generating rule
- * @param objcProvider provider containing all dependencies' information as well as some of this
- * rule's
- * @param linkedBinary whether to look for a linked binary from this rule and dependencies or just
- * the latter
- * @param bundleDirFormat format string representing the bundle's directory with a single
- * placeholder for the target name (e.g. {@code "Payload/%s.app"})
- * @param bundleMinimumOsVersion the minimum OS version this bundle's plist should be generated
- * for (<b>not</b> the minimum OS version its binary is compiled with, that needs to be set
- * through the configuration)
- * @param platform the platform that bundles will be created for using this support
- * @throws InterruptedException
- */
- ReleaseBundlingSupport(
- RuleContext ruleContext,
- ObjcProvider objcProvider,
- LinkedBinary linkedBinary,
- String bundleDirFormat,
- DottedVersion bundleMinimumOsVersion,
- ApplePlatform platform)
- throws InterruptedException {
- this(ruleContext, objcProvider, linkedBinary, bundleDirFormat, ruleContext.getLabel().getName(),
- bundleMinimumOsVersion, platform);
- }
-
- /**
- * Validates application-related attributes set on this rule and registers any errors with the
- * rule context.
- *
- * @return this application support
- */
- ReleaseBundlingSupport validateAttributes() {
- // No asset catalogs. That means you cannot specify app_icon or
- // launch_image attributes, since they must not exist. However, we don't
- // run actool in this case, which means it does not do validity checks,
- // and we MUST raise our own error somehow...
- if (!objcProvider.hasAssetCatalogs()) {
- if (releaseBundling.getAppIcon() != null) {
- ruleContext.attributeError(APP_ICON_ATTR,
- String.format(NO_ASSET_CATALOG_ERROR_FORMAT, releaseBundling.getAppIcon()));
- }
- if (releaseBundling.getLaunchImage() != null) {
- ruleContext.attributeError("launch_image",
- String.format(NO_ASSET_CATALOG_ERROR_FORMAT, releaseBundling.getLaunchImage()));
- }
- }
-
- if (releaseBundling.getProvisioningProfile() == null && platform.isDevice()) {
- ruleContext.attributeError(releaseBundling.getProvisioningProfileAttrName(),
- DEVICE_NO_PROVISIONING_PROFILE);
- }
-
- return this;
- }
-
- /**
- * Validates that resources defined in this rule and its dependencies and written to this bundle
- * are legal.
- *
- * @return this release bundling support
- */
- ReleaseBundlingSupport validateResources() {
- bundleSupport
- .validatePlatform()
- .validateResources(objcProvider);
- return this;
- }
-
- /**
- * Registers actions required to build an application. This includes any
- * {@link BundleSupport#registerActions(ObjcProvider) bundle} and bundle merge actions, signing
- * this application if appropriate and combining several single-architecture binaries into one
- * multi-architecture binary.
- *
- * @param dsymOutputType the file type of the dSYM bundle to be generated
- *
- * @return this application support
- */
- ReleaseBundlingSupport registerActions(DsymOutputType dsymOutputType)
- throws InterruptedException {
- bundleSupport.registerActions(objcProvider);
-
- Artifact combinedArchBinary = prepareCombinedArchitecturesArtifact();
- registerCopyDsymFilesAction(dsymOutputType);
- registerCopyDsymPlistAction(dsymOutputType);
- registerCopyLinkmapFilesAction();
- registerSwiftStdlibActionsIfNecessary(combinedArchBinary);
- registerSwiftSupportActionsIfNecessary(combinedArchBinary);
-
- registerEmbedLabelPlistAction();
- registerEnvironmentPlistAction();
- registerAutomaticPlistAction();
-
- if (releaseBundling.getLaunchStoryboard() != null) {
- registerLaunchStoryboardPlistAction();
- }
-
- registerBundleMergeActions();
- registerPostProcessAndSigningActions();
-
- return this;
- }
-
- private void registerEmbedLabelPlistAction() throws InterruptedException {
- Artifact buildInfo = Iterables.getOnlyElement(
- ruleContext.getBuildInfo(ObjcBuildInfoFactory.KEY));
- String generatedVersionPlistPath = getGeneratedVersionPlist().getShellEscapedExecPathString();
- String shellCommand = "VERSION=\"$("
- + "grep \"^" + BuildInfo.BUILD_EMBED_LABEL + "\" "
- + buildInfo.getShellEscapedExecPathString()
- + " | cut -d' ' -f2- | sed -e '" + EXTRACT_VERSION_NUMBER_SED_COMMAND + "' | "
- + "sed -e 's#\"#\\\"#g')\" && "
- + "cat >" + generatedVersionPlistPath + " <<EOF\n"
- + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
- + "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
- + "<plist version=\"1.0\">\n"
- + "<dict>\n"
- + "EOF\n"
-
- + "if [[ -n \"${VERSION}\" ]]; then\n"
- + " for KEY in CFBundleVersion CFBundleShortVersionString; do\n"
- + " echo \" <key>${KEY}</key>\n\" >> "
- + generatedVersionPlistPath + "\n"
- + " echo \" <string>${VERSION}</string>\n\" >> "
- + generatedVersionPlistPath + "\n"
- + " done\n"
- + "fi\n"
-
- + "cat >>" + generatedVersionPlistPath + " <<EOF\n"
- + "</dict>\n"
- + "</plist>\n"
- + "EOF\n";
- ruleContext.registerAction(new SpawnAction.Builder()
- .setMnemonic("ObjcVersionPlist")
- .setShellCommand(shellCommand)
- .addInput(buildInfo)
- .addOutput(getGeneratedVersionPlist())
- .build(ruleContext));
- }
-
- private void registerLaunchStoryboardPlistAction() {
- String launchStoryboard = releaseBundling.getLaunchStoryboard().getFilename();
- String launchStoryboardName = launchStoryboard.substring(0, launchStoryboard.lastIndexOf('.'));
- NSDictionary result = new NSDictionary();
- result.put("UILaunchStoryboardName", launchStoryboardName);
- String contents = result.toGnuStepASCIIPropertyList();
- ruleContext.registerAction(
- FileWriteAction.create(ruleContext, getLaunchStoryboardPlist(), contents, false));
- }
-
- private void registerEnvironmentPlistAction() {
- // Generates a .plist that contains environment values (such as the SDK used to build, the Xcode
- // version, etc), which are parsed from various .plist files of the OS, namely Xcodes' and
- // Platforms' plists.
- // The resulting file is meant to be merged with the final bundle.
- String platformWithVersion =
- String.format(
- "%s%s",
- platform.getLowerCaseNameInPlist(),
- XcodeConfig.getSdkVersionForPlatform(ruleContext, platform));
- ruleContext.registerAction(
- ObjcRuleClasses.spawnAppleEnvActionBuilder(
- XcodeConfigProvider.fromRuleContext(ruleContext), platform)
- .setMnemonic("EnvironmentPlist")
- .setExecutable(attributes.environmentPlist())
- .addOutput(getGeneratedEnvironmentPlist())
- .addCommandLine(
- CustomCommandLine.builder()
- .add("--platform", platformWithVersion)
- .addExecPath("--output", getGeneratedEnvironmentPlist())
- .build())
- .build(ruleContext));
- }
-
- private void registerAutomaticPlistAction() {
- ruleContext.registerAction(
- FileWriteAction.create(
- ruleContext,
- getGeneratedAutomaticPlist(),
- automaticEntries().toGnuStepASCIIPropertyList(),
- /*makeExecutable=*/ false));
- }
-
- /**
- * Returns a map containing entries that should be added to the merged plist. These are usually
- * generated by Xcode automatically during the build process.
- */
- private NSDictionary automaticEntries() {
- List<Integer> uiDeviceFamily =
- TargetDeviceFamily.UI_DEVICE_FAMILY_VALUES.get(bundleSupport.targetDeviceFamilies());
- NSDictionary result = new NSDictionary();
-
- if (uiDeviceFamily != null) {
- result.put("UIDeviceFamily", uiDeviceFamily.toArray());
- }
- result.put("DTPlatformName", platform.getLowerCaseNameInPlist());
- result.put(
- "DTSDKName",
- platform.getLowerCaseNameInPlist()
- + XcodeConfig.getSdkVersionForPlatform(ruleContext, platform));
- result.put("CFBundleSupportedPlatforms", new NSArray(NSObject.wrap(platform.getNameInPlist())));
- result.put("MinimumOSVersion", bundling.getMinimumOsVersion().toString());
-
- return result;
- }
-
- /**
- * Registers all actions necessary to create a processed and signed IPA from the initial merged
- * IPA.
- *
- * <p>Includes user-provided actions to process IPA contents (via {@code ipa_post_processor}),
- * and signing actions if the IPA is being built for device architectures. If signing is necessary
- * also includes entitlements generation and processing actions.
- *
- * <p>Note that multiple "actions" on the IPA contents may be run in a single blaze action to
- * avoid excessive zipping/unzipping of IPA contents.
- */
- private void registerPostProcessAndSigningActions() {
- Artifact processedIpa = releaseBundling.getIpaArtifact();
- Artifact unprocessedIpa = intermediateArtifacts.unprocessedIpa();
-
- NestedSetBuilder<Artifact> inputs =
- NestedSetBuilder.<Artifact>stableOrder().add(unprocessedIpa);
-
- String actionCommandLine =
- "set -e && "
- + "t=$(mktemp -d \"${TMPDIR:-/tmp}/signing_intermediate.XXXXXX\") && "
- + "trap \"rm -rf ${t}\" EXIT && "
- // Get an absolute path since we need to cd into the temp directory for zip.
- + "signed_ipa=${PWD}/"
- + processedIpa.getShellEscapedExecPathString()
- + " && "
- + "/usr/bin/unzip -qq "
- + unprocessedIpa.getShellEscapedExecPathString()
- + " -d ${t} && ";
-
- FilesToRunProvider processor = attributes.ipaPostProcessor();
- if (processor != null) {
- actionCommandLine += processor.getExecutable().getShellEscapedExecPathString() + " ${t} && ";
- }
-
- if (platform.isDevice()) {
- actionCommandLine += deviceSigningCommandLine();
-
- registerEntitlementsActions();
- inputs.add(releaseBundling.getProvisioningProfile())
- .add(intermediateArtifacts.entitlements());
- } else {
- actionCommandLine += simulatorSigningCommandLine();
- }
-
- actionCommandLine += "cd ${t} && /usr/bin/zip -q -r \"${signed_ipa}\" .";
-
- SpawnAction.Builder processAction =
- ObjcRuleClasses.spawnBashOnDarwinActionBuilder(actionCommandLine)
- .setEnvironment(
- ObjcRuleClasses.appleToolchainEnvironment(
- XcodeConfigProvider.fromRuleContext(ruleContext), platform))
- .setMnemonic("ObjcProcessIpa")
- .setProgressMessage("Processing iOS IPA: %s", ruleContext.getLabel())
- .disableSandboxing()
- .addTransitiveInputs(inputs.build())
- .addOutput(processedIpa);
-
- if (processor != null) {
- processAction.addTool(processor);
- }
-
- ruleContext.registerAction(processAction.build(ruleContext));
- }
-
- private String deviceSigningCommandLine() {
- StringBuilder codesignCommandLineBuilder = new StringBuilder();
- for (String dir : getDirsToSign()) {
- codesignCommandLineBuilder.append(deviceCodesignCommand("${t}/" + dir)).append(" && ");
- }
- return codesignCommandLineBuilder.toString();
- }
-
- private String simulatorSigningCommandLine() {
- StringBuilder codesignCommandLineBuilder = new StringBuilder();
- for (String dir : getDirsToSign()) {
- codesignCommandLineBuilder
- .append("/usr/bin/codesign --force --sign \"-\" ${t}/")
- .append(dir)
- .append(" && ");
- }
- return codesignCommandLineBuilder.toString();
- }
-
- private ImmutableList<String> getDirsToSign() {
- // The order here is important. The innermost code must signed first.
- ImmutableList.Builder<String> dirsToSign = new ImmutableList.Builder<>();
- String bundleDir = ShellUtils.shellEscape(bundling.getBundleDir());
-
- // Explicitly sign the frameworks (raw .dylib files and .framework directories in Frameworks/).
- // Unfortunately the --deep option on codesign doesn't do this automatically.
- if (objcProvider.is(USES_SWIFT)
- || !objcProvider.get(ObjcProvider.DYNAMIC_FRAMEWORK_FILE).isEmpty()) {
- dirsToSign.add(bundleDir + "/Frameworks/*");
- }
- dirsToSign.add(bundleDir);
-
- return dirsToSign.build();
- }
-
- /**
- * Creates entitlement actions such that an entitlements file is generated in
- * {@link IntermediateArtifacts#entitlements()} which can be used for signing in this bundle.
- *
- * <p>Entitlements are generated based on a plist-format entitlements file passed to this bundle's
- * {@code entitlements} attribute or, if that is not set, entitlements extracted from the provided
- * mobile provisioning profile. The team prefix is extracted from the provisioning profile and
- * the following substitutions performed (assuming the prefix extracted was {@code PREFIX}):
- * <ol>
- * <li>"PREFIX.*" -> "PREFIX.BUNDLE_ID" (where BUNDLE_ID is this bundle's id)
- * <li>"$(AppIdentifierPrefix)" -> "PREFIX."
- * <li>"$(CFBundleIdentifier)" -> "BUNDLE_ID" (where BUNDLE_ID is this bundle's id)
- * </ol>
- *
- * <p>Finally, if an entitlements file was provided via {@code --extra_entitlements} it is merged
- * into the substituted entitlements.
- */
- private void registerEntitlementsActions() {
- Artifact teamPrefixFile =
- intermediateArtifacts.appendExtensionForEntitlementArtifact(".team_prefix_file");
- registerExtractTeamPrefixAction(teamPrefixFile);
-
- Artifact entitlementsNeedingSubstitution = releaseBundling.getEntitlements();
- if (entitlementsNeedingSubstitution == null) {
- entitlementsNeedingSubstitution =
- intermediateArtifacts.appendExtensionForEntitlementArtifact(
- ".entitlements_with_variables");
- registerExtractEntitlementsAction(entitlementsNeedingSubstitution);
- }
-
- Artifact substitutedEntitlements = intermediateArtifacts.entitlements();
- if (attributes.extraEntitlements() != null || includeDebugEntitlements()) {
- substitutedEntitlements =
- intermediateArtifacts.appendExtensionForEntitlementArtifact(".substituted");
-
- NestedSetBuilder<Artifact> entitlements =
- NestedSetBuilder.<Artifact>stableOrder().add(substitutedEntitlements);
- if (attributes.extraEntitlements() != null) {
- entitlements.add(attributes.extraEntitlements());
- }
- if (includeDebugEntitlements()) {
- entitlements.add(attributes.deviceDebugEntitlements());
- }
-
- registerMergeEntitlementsAction(entitlements.build());
- }
-
- registerEntitlementsVariableSubstitutionAction(
- entitlementsNeedingSubstitution, teamPrefixFile, substitutedEntitlements);
- }
-
- private boolean includeDebugEntitlements() {
- return attributes.deviceDebugEntitlements() != null
- && ObjcRuleClasses.objcConfiguration(ruleContext).useDeviceDebugEntitlements();
- }
-
- private void registerMergeEntitlementsAction(NestedSet<Artifact> entitlements) {
- PlMergeControlBytes controlBytes =
- PlMergeControlBytes.fromPlists(
- entitlements,
- intermediateArtifacts.entitlements(),
- PlMergeControlBytes.OutputFormat.XML);
-
- Artifact plMergeControlArtifact = ObjcRuleClasses.artifactByAppendingToBaseName(ruleContext,
- artifactName(".merge-entitlements-control"));
-
- ruleContext.registerAction(
- new BinaryFileWriteAction(
- ruleContext.getActionOwner(),
- plMergeControlArtifact,
- controlBytes,
- /*makeExecutable=*/ false));
-
- ruleContext.registerAction(
- new SpawnAction.Builder()
- .setMnemonic("MergeEntitlementsFiles")
- .setExecutable(attributes.plmerge())
- .addTransitiveInputs(entitlements)
- .addOutput(intermediateArtifacts.entitlements())
- .addInput(plMergeControlArtifact)
- .addCommandLine(
- CustomCommandLine.builder()
- .addExecPath("--control", plMergeControlArtifact)
- .build())
- .build(ruleContext));
- }
-
- /**
- * Adds any files to the given nested set builder that should be built if this application is the
- * top level target in a blaze invocation.
- *
- * @param filesToBuild a collection of files to be built, where new artifacts to be built are
- * going to be placed
- * @param dsymOutputType the file type of the dSYM bundle to be built, or absent if no
- * dSYM should be built for this bundle. A dSYM bundle will only be created if both this
- * is present and the configuration values dictate dSYM is enabled
- *
- * @return this application support
- */
- ReleaseBundlingSupport addFilesToBuild(
- NestedSetBuilder<Artifact> filesToBuild, Optional<DsymOutputType> dsymOutputType) {
- NestedSetBuilder<Artifact> debugSymbolBuilder = NestedSetBuilder.<Artifact>stableOrder();
-
- for (Artifact linkmapFile : getLinkmapFiles().values()) {
- filesToBuild.add(linkmapFile);
- }
-
- if (ObjcRuleClasses.objcConfiguration(ruleContext).generateDsym()
- && dsymOutputType.isPresent()) {
- filesToBuild.addAll(getDsymFiles(dsymOutputType.get()).values());
-
- // TODO(bazel-team): Remove the 'if' when the objc_binary rule does not generate a bundle any
- // more. The reason this 'if' is here is because the plist is obtained from the ObjcProvider.
- // Since objc_binary is the rule that adds this file to the provider, and not before, when
- // running this the provider does not have the plist yet. This gets called again when running
- // the *_application targets, and since they depend on objc_binaries, the provider has the
- // files configured. When objc_binary stops bundling ipas as output, the bundling methods will
- // only get called by *_application rules, with the plist configured in the provider.
- Artifact cpuPlist = getAnyCpuSpecificDsymPlist();
- if (cpuPlist != null) {
- filesToBuild.add(intermediateArtifacts.dsymPlist(dsymOutputType.get()));
- }
-
- if (linkedBinary == LinkedBinary.LOCAL_AND_DEPENDENCIES) {
- debugSymbolBuilder
- .add(intermediateArtifacts.dsymPlist(dsymOutputType.get()))
- .add(intermediateArtifacts.dsymSymbol(dsymOutputType.get()));
- }
- }
-
- filesToBuild
- .add(releaseBundling.getIpaArtifact())
- .addTransitive(debugSymbolBuilder.build())
- .addTransitive(objcProvider.get(ObjcProvider.EXPORTED_DEBUG_ARTIFACTS));
-
- return this;
- }
-
- /**
- * Adds dSYM artifacts (plist, arch-speficic binaries) to the {@link ObjcProvider} for export.
- */
- public void addExportedDebugArtifacts(
- ObjcProvider.Builder objcBuilder, DsymOutputType dsymOutputType) {
- if (ObjcRuleClasses.objcConfiguration(ruleContext).generateDsym()) {
- objcBuilder
- .addAll(ObjcProvider.EXPORTED_DEBUG_ARTIFACTS, getDsymFiles(dsymOutputType).values())
- .add(
- ObjcProvider.EXPORTED_DEBUG_ARTIFACTS,
- intermediateArtifacts.dsymPlist(dsymOutputType));
- }
- }
-
- /**
- * Registers an action to generate a runner script based on a template.
- */
- ReleaseBundlingSupport registerGenerateRunnerScriptAction(Artifact runnerScript,
- Artifact ipaInput) {
- ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
- String escapedSimDevice = ShellUtils.shellEscape(objcConfiguration.getIosSimulatorDevice());
- String escapedSdkVersion =
- ShellUtils.shellEscape(objcConfiguration.getIosSimulatorVersion().toString());
- ImmutableList<Substitution> substitutions = ImmutableList.of(
- Substitution.of("%app_name%", ruleContext.getLabel().getName()),
- Substitution.of("%ipa_file%", ipaInput.getRunfilesPathString()),
- Substitution.of("%sim_device%", escapedSimDevice),
- Substitution.of("%sdk_version%", escapedSdkVersion),
- Substitution.of("%std_redirect_dylib_path%",
- attributes.stdRedirectDylib().getRunfilesPathString()));
-
- ruleContext.registerAction(
- new TemplateExpansionAction(ruleContext.getActionOwner(), attributes.runnerScriptTemplate(),
- runnerScript, substitutions, true));
- return this;
- }
-
- /**
- * Returns a {@link RunfilesSupport} that uses the provided runner script as the executable.
- */
- RunfilesSupport runfilesSupport(Artifact runnerScript) {
- Runfiles runfiles = new Runfiles.Builder(
- ruleContext.getWorkspaceName(), ruleContext.getConfiguration().legacyExternalRunfiles())
- .addArtifact(releaseBundling.getIpaArtifact())
- .addArtifact(runnerScript)
- .addArtifact(attributes.stdRedirectDylib())
- .build();
- return RunfilesSupport.withExecutable(ruleContext, runfiles, runnerScript);
- }
-
- private ExtraActoolArgs extraActoolArgs() {
- ImmutableList.Builder<String> extraArgs = ImmutableList.builder();
- if (releaseBundling.getAppIcon() != null) {
- extraArgs.add("--app-icon", releaseBundling.getAppIcon());
- }
- if (releaseBundling.getLaunchImage() != null) {
- extraArgs.add("--launch-image", releaseBundling.getLaunchImage());
- }
- return new ExtraActoolArgs(extraArgs.build());
- }
-
- private Bundling bundling(
- RuleContext ruleContext,
- ObjcProvider objcProvider,
- String bundleDirFormat,
- String bundleName,
- DottedVersion minimumOsVersion) {
- ImmutableList<BundleableFile> extraBundleFiles;
- AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
- if (platform.isDevice()) {
- extraBundleFiles = ImmutableList.of(new BundleableFile(
- releaseBundling.getProvisioningProfile(), PROVISIONING_PROFILE_BUNDLE_FILE));
- } else {
- extraBundleFiles = ImmutableList.of();
- }
-
- Bundling.Builder bundling =
- new Builder()
- .setName(bundleName)
- .setExecutableName(bundleName)
- // Architecture that determines which nested bundles are kept.
- .setArchitecture(appleConfiguration.getDependencySingleArchitecture())
- .setBundleDirFormat(bundleDirFormat)
- .addExtraBundleFiles(extraBundleFiles)
- .setObjcProvider(objcProvider)
- .setIntermediateArtifacts(intermediateArtifacts)
- .setPrimaryBundleId(releaseBundling.getPrimaryBundleId())
- .setFallbackBundleId(releaseBundling.getFallbackBundleId())
- .setMinimumOsVersion(minimumOsVersion)
- .setArtifactPrefix(releaseBundling.getArtifactPrefix())
- .setTargetDeviceFamilies(releaseBundling.getTargetDeviceFamilies());
-
- // Add plists from rule first.
- if (releaseBundling.getInfoPlistsFromRule() != null) {
- bundling.addInfoplistInputs(releaseBundling.getInfoPlistsFromRule());
- } else {
- bundling.addInfoplistInputFromRule(ruleContext);
- }
-
- // Add generated plists next so that generated values can override the default values in the
- // plists from rule.
- bundling.setAutomaticEntriesInfoplistInput(getGeneratedAutomaticPlist())
- .addInfoplistInput(getGeneratedVersionPlist())
- .addInfoplistInput(getGeneratedEnvironmentPlist())
- .addInfoplistInputs(releaseBundling.getInfoplistInputs());
-
- if (releaseBundling.getLaunchStoryboard() != null) {
- bundling.addInfoplistInput(getLaunchStoryboardPlist());
- }
-
- return bundling.build();
- }
-
- private Artifact prepareCombinedArchitecturesArtifact() {
- Artifact dependentMultiArchBinary = attributes.dependentMultiArchBinary();
- if (dependentMultiArchBinary != null) {
- return dependentMultiArchBinary;
- }
-
- Artifact resultingLinkedBinary = intermediateArtifacts.combinedArchitectureBinary();
-
- new LipoSupport(ruleContext).registerCombineArchitecturesAction(linkedBinaries(),
- resultingLinkedBinary, platform);
- return resultingLinkedBinary;
- }
-
- private NestedSet<Artifact> linkedBinaries() {
- NestedSetBuilder<Artifact> linkedBinariesBuilder = NestedSetBuilder.<Artifact>stableOrder()
- .addTransitive(attributes.dependentLinkedBinaries());
- if (linkedBinary == LinkedBinary.LOCAL_AND_DEPENDENCIES) {
- linkedBinariesBuilder.add(intermediateArtifacts.strippedSingleArchitectureBinary());
- }
- return linkedBinariesBuilder.build();
- }
-
- private void registerBundleMergeActions() {
- Artifact bundleMergeControlArtifact = ObjcRuleClasses.artifactByAppendingToBaseName(ruleContext,
- artifactName(".ipa-control"));
-
- BundleMergeControlBytes controlBytes =
- new BundleMergeControlBytes(
- bundling,
- intermediateArtifacts.unprocessedIpa(),
- XcodeConfig.getSdkVersionForPlatform(ruleContext, ApplePlatform.IOS_DEVICE),
- ruleContext.getFragment(AppleConfiguration.class)
- .getMultiArchPlatform(PlatformType.IOS));
-
- ruleContext.registerAction(
- new BinaryFileWriteAction(
- ruleContext.getActionOwner(), bundleMergeControlArtifact, controlBytes,
- /*makeExecutable=*/false));
-
- ruleContext.registerAction(
- new SpawnAction.Builder()
- .setMnemonic("IosBundle")
- .setProgressMessage("Bundling iOS application: %s", ruleContext.getLabel())
- .setExecutable(attributes.bundleMergeExecutable())
- .addInput(bundleMergeControlArtifact)
- .addTransitiveInputs(bundling.getBundleContentArtifacts())
- .addOutput(intermediateArtifacts.unprocessedIpa())
- .addCommandLine(
- CustomCommandLine.builder().addExecPath(bundleMergeControlArtifact).build())
- .build(ruleContext));
- }
-
- private void registerCopyLinkmapFilesAction() {
- for (Entry<Artifact, Artifact> linkmapFile : getLinkmapFiles().entrySet()) {
- ruleContext.registerAction(
- new SymlinkAction(ruleContext.getActionOwner(), linkmapFile.getKey(),
- linkmapFile.getValue(), String.format("Copying Linkmap %s",
- linkmapFile.getValue().prettyPrint())));
- }
- }
-
- /**
- * Registers the actions that copy the debug symbol files from the CPU-specific binaries that are
- * part of this application. The only one step executed is that he dsym files have to be renamed
- * to include their corresponding CPU architecture as a suffix.
- *
- * @param dsymOutputType the file type of the dSYM bundle to be copied
- */
- private void registerCopyDsymFilesAction(DsymOutputType dsymOutputType) {
- for (Entry<Artifact, Artifact> dsymFiles : getDsymFiles(dsymOutputType).entrySet()) {
- ruleContext.registerAction(
- new SymlinkAction(
- ruleContext.getActionOwner(),
- dsymFiles.getKey(),
- dsymFiles.getValue(),
- "Symlinking dSYM files"));
- }
- }
-
- /**
- * Registers the action that copies the debug symbol plist from the binary.
- *
- * @param dsymOutputType the file type of the dSYM bundle to be copied
- */
- private void registerCopyDsymPlistAction(DsymOutputType dsymOutputType) {
- Artifact dsymPlist = getAnyCpuSpecificDsymPlist();
- if (dsymPlist != null) {
- ruleContext.registerAction(
- new SymlinkAction(
- ruleContext.getActionOwner(),
- dsymPlist,
- intermediateArtifacts.dsymPlist(dsymOutputType),
- "Symlinking dSYM plist"));
- }
- }
-
- /**
- * Returns a map of input dsym artifacts from the CPU-specific binaries built for this
- * ios_application to the new output dsym artifacts.
- *
- * @param dsymOutputType the file type of the dSYM bundle to be generated
- */
- private ImmutableMap<Artifact, Artifact> getDsymFiles(DsymOutputType dsymOutputType) {
- ImmutableMap.Builder<Artifact, Artifact> results = ImmutableMap.builder();
- for (Entry<String, Artifact> dsymFile : attributes.cpuSpecificDsymFiles().entrySet()) {
- Artifact destDsym = intermediateArtifacts.dsymSymbol(dsymOutputType, dsymFile.getKey());
- results.put(dsymFile.getValue(), destDsym);
- }
- return results.build();
- }
-
- /**
- * Returns any available CPU specific dSYM plist file.
- */
- @Nullable
- private Artifact getAnyCpuSpecificDsymPlist() {
- for (Artifact dsymPlist : attributes.cpuSpecificDsymPlists().values()) {
- // The plist files generated by the dsym tool are all equal, and don't really have any
- // useful information. For now, just retrieving any one is OK, but ideally all of them should
- // be merged.
- return dsymPlist;
- }
- return null;
- }
-
- /**
- * Returns a map of input linkmap artifacts from the CPU-specific binaries built for this
- * ios_application to the new output linkmap artifacts.
- */
- private ImmutableMap<Artifact, Artifact> getLinkmapFiles() {
- ImmutableMap.Builder<Artifact, Artifact> results = ImmutableMap.builder();
- for (Entry<String, Artifact> linkmapFile : attributes.cpuSpecificLinkmapFiles().entrySet()) {
- Artifact destLinkMap = intermediateArtifacts.linkmap(linkmapFile.getKey());
- results.put(linkmapFile.getValue(), destLinkMap);
- }
- return results.build();
- }
-
- private void registerExtractTeamPrefixAction(Artifact teamPrefixFile) {
- String shellCommand = "set -e && "
- + "PLIST=$(mktemp -t teamprefix.plist) && trap \"rm ${PLIST}\" EXIT && "
- + extractPlistCommand(releaseBundling.getProvisioningProfile()) + " > ${PLIST} && "
- + "/usr/libexec/PlistBuddy -c 'Print ApplicationIdentifierPrefix:0' ${PLIST} > "
- + teamPrefixFile.getShellEscapedExecPathString();
- ruleContext.registerAction(
- ObjcRuleClasses.spawnBashOnDarwinActionBuilder(shellCommand)
- .setMnemonic("ExtractIosTeamPrefix")
- .disableSandboxing()
- .addInput(releaseBundling.getProvisioningProfile())
- .addOutput(teamPrefixFile)
- .build(ruleContext));
- }
-
- private ReleaseBundlingSupport registerExtractEntitlementsAction(Artifact entitlements) {
- // See Apple Glossary (http://goo.gl/EkhXOb)
- // An Application Identifier is constructed as: TeamID.BundleID
- // TeamID is extracted from the provisioning profile.
- // BundleID consists of a reverse-DNS string to identify the app, where the last component
- // is the application name, and is specified as an attribute.
- String shellCommand = "set -e && "
- + "PLIST=$(mktemp -t entitlements.plist) && trap \"rm ${PLIST}\" EXIT && "
- + extractPlistCommand(releaseBundling.getProvisioningProfile()) + " > ${PLIST} && "
- + "/usr/libexec/PlistBuddy -x -c 'Print Entitlements' ${PLIST} > "
- + entitlements.getShellEscapedExecPathString();
- ruleContext.registerAction(
- ObjcRuleClasses.spawnBashOnDarwinActionBuilder(shellCommand)
- .setMnemonic("ExtractIosEntitlements")
- .disableSandboxing()
- .setProgressMessage("Extracting entitlements: %s", ruleContext.getLabel())
- .addInput(releaseBundling.getProvisioningProfile())
- .addOutput(entitlements)
- .build(ruleContext));
-
- return this;
- }
-
- private void registerEntitlementsVariableSubstitutionAction(
- Artifact inputEntitlements, Artifact prefix, Artifact substitutedEntitlements) {
- String escapedBundleId = ShellUtils.shellEscape(releaseBundling.getBundleId());
- String shellCommand =
- "set -e && "
- + "PREFIX=\"$(cat "
- + prefix.getShellEscapedExecPathString()
- + ")\" && "
- + "sed "
- // Replace .* from default entitlements file with bundle ID where suitable.
- + "-e \"s#${PREFIX}\\.\\*#${PREFIX}."
- + escapedBundleId
- + "#g\" "
-
- // Replace some variables that people put in their own entitlements files
- + "-e \"s#\\$(AppIdentifierPrefix)#${PREFIX}.#g\" "
- + "-e \"s#\\$(CFBundleIdentifier)#"
- + escapedBundleId
- + "#g\" "
- + inputEntitlements.getShellEscapedExecPathString()
- + " > "
- + substitutedEntitlements.getShellEscapedExecPathString();
- ruleContext.registerAction(
- new SpawnAction.Builder()
- .setMnemonic("SubstituteIosEntitlements")
- .setShellCommand(shellCommand)
- .addInput(inputEntitlements)
- .addInput(prefix)
- .addOutput(substitutedEntitlements)
- .build(ruleContext));
- }
-
- /** Registers an action to copy Swift standard library dylibs into app bundle. */
- private void registerSwiftStdlibActionsIfNecessary(Artifact combinedArchBinary) {
- if (!objcProvider.is(USES_SWIFT)) {
- return;
- }
-
-
- CustomCommandLine.Builder commandLine = CustomCommandLine.builder();
-
- commandLine
- .add("--output_zip_path")
- .addPath(intermediateArtifacts.swiftFrameworksFileZip().getExecPath())
- .add("--bundle_path")
- .add("Frameworks")
- .add("--platform")
- .addDynamicString(platform.getLowerCaseNameInPlist())
- .addExecPath("--scan-executable", combinedArchBinary);
-
- ruleContext.registerAction(
- ObjcRuleClasses.spawnAppleEnvActionBuilder(
- XcodeConfigProvider.fromRuleContext(ruleContext), platform)
- .setMnemonic("SwiftStdlibCopy")
- .setExecutable(attributes.swiftStdlibToolWrapper())
- .addCommandLine(commandLine.build())
- .addOutput(intermediateArtifacts.swiftFrameworksFileZip())
- .addInput(combinedArchBinary)
- .build(ruleContext));
- }
-
- /** Registers an action to copy Swift standard library dylibs into SwiftSupport root directory. */
- private void registerSwiftSupportActionsIfNecessary(Artifact combinedArchBinary) {
- if (!objcProvider.is(USES_SWIFT)) {
- return;
- }
-
-
- CustomCommandLine.Builder commandLine = CustomCommandLine.builder();
- commandLine
- .add("--output_zip_path")
- .addPath(intermediateArtifacts.swiftSupportZip().getExecPath())
- .add("--bundle_path")
- .addDynamicString("SwiftSupport/" + platform.getLowerCaseNameInPlist())
- .add("--platform")
- .addDynamicString(platform.getLowerCaseNameInPlist())
- .addExecPath("--scan-executable", combinedArchBinary);
-
- ruleContext.registerAction(
- ObjcRuleClasses.spawnAppleEnvActionBuilder(
- XcodeConfigProvider.fromRuleContext(ruleContext), platform)
- .setMnemonic("SwiftCopySwiftSupport")
- .setExecutable(attributes.swiftStdlibToolWrapper())
- .addCommandLine(commandLine.build())
- .addOutput(intermediateArtifacts.swiftSupportZip())
- .addInput(combinedArchBinary)
- .build(ruleContext));
- }
-
- private String extractPlistCommand(Artifact provisioningProfile) {
- return "security cms -D -i " + ShellUtils.shellEscape(provisioningProfile.getExecPathString());
- }
-
- private String deviceCodesignCommand(String appDir) {
- String signingCertName = ObjcRuleClasses.objcConfiguration(ruleContext).getSigningCertName();
- Artifact entitlements = intermediateArtifacts.entitlements();
-
- final String identity;
- if (signingCertName != null) {
- identity = '"' + signingCertName + '"';
- } else {
- // Extracts an identity hash from the configured provisioning profile. Note that this will use
- // the first certificate identity in the profile, regardless of how many identities are
- // configured in it (DeveloperCertificates:0).
- identity =
- "$(PLIST=$(mktemp -t cert.plist) && trap \"rm ${PLIST}\" EXIT && "
- + extractPlistCommand(releaseBundling.getProvisioningProfile())
- + " > ${PLIST} && "
- + "/usr/libexec/PlistBuddy -c 'Print DeveloperCertificates:0' ${PLIST} | "
- + "openssl x509 -inform DER -noout -fingerprint | "
- + "cut -d= -f2 | sed -e 's#:##g')";
- }
-
- return String.format(
- "/usr/bin/codesign --force --sign %s --entitlements %s %s",
- identity,
- entitlements.getShellEscapedExecPathString(),
- appDir);
- }
-
- private Artifact getGeneratedVersionPlist() {
- return ruleContext.getRelatedArtifact(
- ruleContext.getUniqueDirectory("plists"), artifactName("-version.plist"));
- }
-
- private Artifact getGeneratedEnvironmentPlist() {
- return ruleContext.getRelatedArtifact(
- ruleContext.getUniqueDirectory("plists"), artifactName("-environment.plist"));
- }
-
- private Artifact getGeneratedAutomaticPlist() {
- return ruleContext.getRelatedArtifact(
- ruleContext.getUniqueDirectory("plists"), artifactName("-automatic.plist"));
- }
-
- private Artifact getLaunchStoryboardPlist() {
- return ruleContext.getRelatedArtifact(
- ruleContext.getUniqueDirectory("plists"), artifactName("-launchstoryboard.plist"));
- }
-
- /**
- * Returns artifact name prefixed with prefix given in {@link ReleaseBundling} if available.
- * This helps in creating unique artifact name when multiple bundles are created with a different
- * name than the target name.
- */
- private String artifactName(String artifactName) {
- if (releaseBundling.getArtifactPrefix() != null) {
- return String.format("-%s%s", releaseBundling.getArtifactPrefix(), artifactName);
- }
- return artifactName;
- }
-
- /**
- * Logic to access attributes to access tools required by application support.
- * Attributes are required and guaranteed to return a value or throw unless they are annotated
- * with {@link Nullable} in which case they can return {@code null} if no value is defined.
- */
- private static class Attributes {
- private final RuleContext ruleContext;
-
- private Attributes(RuleContext ruleContext) {
- this.ruleContext = ruleContext;
- }
-
- /**
- * Returns this target's user-specified {@code ipa_post_processor} or null if not present.
- */
- @Nullable
- FilesToRunProvider ipaPostProcessor() {
- if (!ruleContext.attributes().has("ipa_post_processor", BuildType.LABEL)) {
- return null;
- }
- return ruleContext.getExecutablePrerequisite("ipa_post_processor", Mode.TARGET);
- }
-
- /**
- * Returns the multi-arch binary provided by the label under the "binary" attribute of the
- * current rule, or null if there is no such binary available.
- */
- @Nullable Artifact dependentMultiArchBinary() {
- if (ruleContext.attributes().getAttributeDefinition("binary") == null) {
- return null;
- }
-
- for (ObjcProvider provider
- : ruleContext.getPrerequisites(
- "binary", Mode.DONT_CHECK, ObjcProvider.SKYLARK_CONSTRUCTOR)) {
- if (!provider.get(ObjcProvider.MULTI_ARCH_LINKED_BINARIES).isEmpty()) {
- return Iterables.getOnlyElement(provider.get(ObjcProvider.MULTI_ARCH_LINKED_BINARIES));
- }
- }
- return null;
- }
-
- NestedSet<? extends Artifact> dependentLinkedBinaries() {
- if (ruleContext.attributes().getAttributeDefinition("binary") == null) {
- return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
- }
-
- NestedSetBuilder<Artifact> linkedBinaries = NestedSetBuilder.stableOrder();
- for (ObjcProvider provider
- : ruleContext.getPrerequisites(
- "binary", Mode.DONT_CHECK, ObjcProvider.SKYLARK_CONSTRUCTOR)) {
- linkedBinaries.addTransitive(provider.get(ObjcProvider.LINKED_BINARY));
- }
-
- return linkedBinaries.build();
- }
-
- FilesToRunProvider bundleMergeExecutable() {
- return checkNotNull(ruleContext.getExecutablePrerequisite("$bundlemerge", Mode.HOST));
- }
-
- /**
- * Returns a reference to the plmerge executable.
- */
- FilesToRunProvider plmerge() {
- return ruleContext.getExecutablePrerequisite("$plmerge", Mode.HOST);
- }
-
- Artifact stdRedirectDylib() {
- return checkNotNull(ruleContext.getPrerequisiteArtifact("$std_redirect_dylib", Mode.HOST));
- }
-
- Artifact runnerScriptTemplate() {
- return checkNotNull(
- ruleContext.getPrerequisiteArtifact("$runner_script_template", Mode.HOST));
- }
-
- /** Returns the location of the swiftstdlibtoolwrapper. */
- FilesToRunProvider swiftStdlibToolWrapper() {
- return ruleContext.getExecutablePrerequisite("$swiftstdlibtoolwrapper", Mode.HOST);
- }
-
- /**
- * Returns the location of the environment_plist.
- */
- FilesToRunProvider environmentPlist() {
- return ruleContext.getExecutablePrerequisite("$environment_plist", Mode.HOST);
- }
-
- /**
- * Returns a plist specified by the user via {@code --extra_entitlements} or {@code null}.
- */
- @Nullable
- Artifact extraEntitlements() {
- if (ruleContext.attributes().getAttributeDefinition(EXTRA_ENTITLEMENTS_ATTR) == null) {
- return null;
- }
- return ruleContext.getPrerequisiteArtifact(EXTRA_ENTITLEMENTS_ATTR, Mode.HOST);
- }
-
- /**
- * Returns a plist containing entitlements that allow the signed IPA to be debugged.
- */
- @Nullable
- Artifact deviceDebugEntitlements() {
- if (ruleContext.attributes().getAttributeDefinition(DEBUG_ENTITLEMENTS_ATTR) == null) {
- return null;
- }
- return ruleContext.getPrerequisiteArtifact(DEBUG_ENTITLEMENTS_ATTR, Mode.HOST);
- }
-
- ImmutableMap<String, Artifact> cpuSpecificDsymFiles() {
- return cpuSpecificArtifacts(ObjcProvider.DEBUG_SYMBOLS);
- }
-
- ImmutableMap<String, Artifact> cpuSpecificDsymPlists() {
- return cpuSpecificArtifacts(ObjcProvider.DEBUG_SYMBOLS_PLIST);
- }
-
- ImmutableMap<String, Artifact> cpuSpecificLinkmapFiles() {
- return cpuSpecificArtifacts(ObjcProvider.LINKMAP_FILE);
- }
-
- ImmutableMap<String, Artifact> cpuSpecificArtifacts(ObjcProvider.Key<Artifact> key) {
- ImmutableMap.Builder<String, Artifact> results = ImmutableMap.builder();
- if (ruleContext.attributes().has("binary", BuildType.LABEL)) {
- for (TransitiveInfoCollection prerequisite
- : ruleContext.getPrerequisites("binary", Mode.DONT_CHECK)) {
- ObjcProvider prerequisiteProvider = prerequisite.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
- if (prerequisiteProvider != null) {
- Artifact sourceArtifact = Iterables.getOnlyElement(prerequisiteProvider.get(key), null);
- if (sourceArtifact != null) {
- String cpu =
- prerequisite.getConfiguration().getFragment(AppleConfiguration.class).getIosCpu();
- results.put(cpu, sourceArtifact);
- }
- }
- }
- }
- return results.build();
- }
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/Storyboards.java b/src/main/java/com/google/devtools/build/lib/rules/objc/Storyboards.java
deleted file mode 100644
index cfa4d6c65a..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/Storyboards.java
+++ /dev/null
@@ -1,76 +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.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.collect.nestedset.Order;
-
-/**
- * Contains information about storyboards for a single target. This does not include information
- * about the transitive closure. A storyboard:
- * <ul>
- * <li>Is a single file with an extension of {@code .storyboard} in its uncompiled, checked-in
- * form.
- * <li>Can be in a localized {@code .lproj} directory, including {@code Base.lproj}.
- * <li>Compiles with {@code ibtool} to a directory with extension {@code .storyboardc} (note the
- * added "c")
- * </ul>
- *
- * <p>The {@link NestedSet}s stored in this class are only one level deep, and do not include the
- * storyboards in the transitive closure. This is to facilitate structural sharing between copies
- * of the sequences - the output zips can be added transitively to the inputs of the merge bundle
- * action, as well as to the files to build set, and only one instance of the sequence exists for
- * each set.
- */
-final class Storyboards {
- private final NestedSet<Artifact> outputZips;
- private final NestedSet<Artifact> inputs;
-
- private Storyboards(NestedSet<Artifact> outputZips, NestedSet<Artifact> inputs) {
- this.outputZips = outputZips;
- this.inputs = inputs;
- }
-
- public NestedSet<Artifact> getOutputZips() {
- return outputZips;
- }
-
- public NestedSet<Artifact> getInputs() {
- return inputs;
- }
-
- static Storyboards empty() {
- return new Storyboards(
- NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER),
- NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER));
- }
-
- /**
- * Generates a set of new instances given the raw storyboard inputs.
- * @param inputs the {@code .storyboard} files.
- * @param intermediateArtifacts the object used to determine the output zip {@link Artifact}s.
- */
- static Storyboards fromInputs(
- Iterable<Artifact> inputs, IntermediateArtifacts intermediateArtifacts) {
- NestedSetBuilder<Artifact> outputZips = NestedSetBuilder.stableOrder();
- for (Artifact input : inputs) {
- outputZips.add(intermediateArtifacts.compiledStoryboardZip(input));
- }
- return new Storyboards(outputZips.build(), NestedSetBuilder.wrap(Order.STABLE_ORDER, inputs));
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
deleted file mode 100644
index 6969bee9f6..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
+++ /dev/null
@@ -1,329 +0,0 @@
-// Copyright 2015 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.base.Joiner;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.analysis.FileProvider;
-import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts;
-import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.Runfiles.Builder;
-import com.google.devtools.build.lib.analysis.RunfilesProvider;
-import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
-import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
-import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider;
-import com.google.devtools.build.lib.analysis.test.TestEnvironmentInfo;
-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.Info;
-import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
-import com.google.devtools.build.lib.rules.apple.DottedVersion;
-import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.SimulatorRule;
-import com.google.devtools.build.lib.syntax.Type;
-import com.google.devtools.build.lib.util.FileType;
-import java.util.List;
-import javax.annotation.Nullable;
-
-/**
- * Support for running XcTests.
- */
-public class TestSupport {
- private final RuleContext ruleContext;
-
- public TestSupport(RuleContext ruleContext) {
- this.ruleContext = ruleContext;
- }
-
- /**
- * Registers actions to create all files needed in order to actually run the test.
- *
- * @throws InterruptedException
- */
- public TestSupport registerTestRunnerActions() throws InterruptedException {
- registerTestScriptSubstitutionAction();
- return this;
- }
-
- /**
- * Returns the script which should be run in order to actually run the tests.
- */
- public Artifact generatedTestScript() {
- return ObjcRuleClasses.artifactByAppendingToBaseName(ruleContext, "_test_script");
- }
-
- private void registerTestScriptSubstitutionAction() throws InterruptedException {
- // testBundleIpa is the bundle actually containing the tests.
- Artifact testBundleIpa = testBundleIpa();
-
- String runMemleaks =
- ruleContext.getFragment(ObjcConfiguration.class).runMemleaks() ? "true" : "false";
-
- // TODO(ulfjack): This is missing the action environment, and the inherited parts from both. Is
- // that intentional? We should either fix it, or clearly document why we're doing that.
- ImmutableMap<String, String> testEnv =
- ruleContext.getConfiguration().getTestActionEnvironment().getFixedEnv();
-
- // The substitutions below are common for simulator and lab device.
- ImmutableList.Builder<Substitution> substitutions =
- new ImmutableList.Builder<Substitution>()
- .add(Substitution.of("%(memleaks)s", runMemleaks))
- .add(Substitution.of("%(test_app_ipa)s", testBundleIpa.getRootRelativePathString()))
- .add(Substitution.of("%(test_app_name)s", baseNameWithoutIpa(testBundleIpa)))
- .add(Substitution.of("%(test_bundle_path)s", testBundleIpa.getRootRelativePathString()))
- .add(
- Substitution.of("%(plugin_jars)s", Artifact.joinRootRelativePaths(":", plugins())));
-
- substitutions.add(Substitution.ofSpaceSeparatedMap("%(test_env)s", testEnv));
-
- // testHarnessIpa is the app being tested in the case where testBundleIpa is a .xctest bundle.
- Optional<Artifact> testHarnessIpa = testHarnessIpa();
- if (testHarnessIpa.isPresent()) {
- substitutions
- .add(Substitution.of("%(xctest_app_ipa)s",
- testHarnessIpa.get().getRootRelativePathString()))
- .add(Substitution.of("%(xctest_app_name)s", baseNameWithoutIpa(testHarnessIpa.get())))
- .add(Substitution.of("%(test_host_path)s",
- testHarnessIpa.get().getRootRelativePathString()));
- } else {
- substitutions
- .add(Substitution.of("%(xctest_app_ipa)s", ""))
- .add(Substitution.of("%(xctest_app_name)s", ""))
- .add(Substitution.of("%(test_host_path)s", ""));
- }
-
- substitutions.add(Substitution.of("%(test_type)s", "XCTEST"));
-
- Artifact template;
- if (!runWithLabDevice()) {
- substitutions.addAll(substitutionsForSimulator());
- template = ruleContext.getPrerequisiteArtifact(IosTest.TEST_TEMPLATE_ATTR, Mode.TARGET);
- } else {
- substitutions.addAll(substitutionsForLabDevice());
- template = testTemplateForLabDevice();
- }
-
- ruleContext.registerAction(
- new TemplateExpansionAction(
- ruleContext.getActionOwner(),
- template,
- generatedTestScript(),
- substitutions.build(),
- /* makeExecutable= */ true));
- }
-
- private boolean runWithLabDevice() {
- return iosLabDeviceSubstitutions() != null;
- }
-
- /**
- * Gets the substitutions for simulator.
- */
- private ImmutableList<Substitution> substitutionsForSimulator() {
- ImmutableList.Builder<Substitution> substitutions = new ImmutableList.Builder<Substitution>()
- .add(Substitution.of("%(std_redirect_dylib_path)s",
- stdRedirectDylib().getRunfilesPathString()))
- .addAll(deviceSubstitutions().getSubstitutionsForTestRunnerScript());
-
- Optional<Artifact> testRunner = testRunner();
- if (testRunner.isPresent()) {
- substitutions.add(
- Substitution.of("%(testrunner_binary)s", testRunner.get().getRunfilesPathString()));
- }
- return substitutions.build();
- }
-
- private IosTestSubstitutionProvider deviceSubstitutions() {
- return ruleContext.getPrerequisite(
- IosTest.TARGET_DEVICE, Mode.TARGET, IosTestSubstitutionProvider.class);
- }
-
- /*
- * The IPA of the bundle that contains the tests. Typically will be a .xctest bundle, but in the
- * case where the xctest attribute is false, it will be a .app bundle.
- */
- private Artifact testBundleIpa() throws InterruptedException {
- return ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA);
- }
-
- /*
- * The IPA of the testHarness in the case where the testBundleIpa is an .xctest bundle.
- */
- private Optional<Artifact> testHarnessIpa() {
- FileProvider fileProvider =
- ruleContext.getPrerequisite(IosTest.XCTEST_APP_ATTR, Mode.TARGET, FileProvider.class);
- if (fileProvider == null) {
- return Optional.absent();
- }
- List<Artifact> files =
- Artifact.filterFiles(fileProvider.getFilesToBuild(), FileType.of(".ipa"));
- if (files.size() == 0) {
- return Optional.absent();
- } else if (files.size() == 1) {
- return Optional.of(Iterables.getOnlyElement(files));
- } else {
- throw new IllegalStateException("Expected 0 or 1 files in xctest_app, got: " + files);
- }
- }
-
- private Artifact stdRedirectDylib() {
- return ruleContext.getPrerequisiteArtifact(SimulatorRule.STD_REDIRECT_DYLIB_ATTR, Mode.HOST);
- }
-
- /**
- * Gets the binary of the testrunner attribute, if there is one.
- */
- private Optional<Artifact> testRunner() {
- return Optional.fromNullable(
- ruleContext.getPrerequisiteArtifact(IosTest.TEST_RUNNER_ATTR, Mode.TARGET));
- }
-
- /**
- * Gets the substitutions for lab device.
- */
- private ImmutableList<Substitution> substitutionsForLabDevice() {
- return new ImmutableList.Builder<Substitution>()
- .addAll(iosLabDeviceSubstitutions().getSubstitutionsForTestRunnerScript())
- .add(Substitution.of("%(ios_device_arg)s", Joiner.on(" ").join(iosDeviceArgs()))).build();
- }
-
- /**
- * Gets the test template for lab devices.
- */
- private Artifact testTemplateForLabDevice() {
- return ruleContext
- .getPrerequisite(
- IosTest.TEST_TARGET_DEVICE_ATTR, Mode.TARGET, LabDeviceTemplateProvider.class)
- .getLabDeviceTemplate();
- }
-
- @Nullable
- private IosTestSubstitutionProvider iosLabDeviceSubstitutions() {
- return ruleContext.getPrerequisite(
- IosTest.TEST_TARGET_DEVICE_ATTR, Mode.TARGET, IosTestSubstitutionProvider.class);
- }
-
- private List<String> iosDeviceArgs() {
- return ruleContext.attributes().get(IosTest.DEVICE_ARG_ATTR, Type.STRING_LIST);
- }
-
- /**
- * Adds all files needed to run this test to the passed Runfiles builder.
- */
- public TestSupport addRunfiles(
- Builder runfilesBuilder, InstrumentedFilesProvider instrumentedFilesProvider)
- throws InterruptedException {
- runfilesBuilder
- .addArtifact(testBundleIpa())
- .addArtifacts(testHarnessIpa().asSet())
- .addArtifact(generatedTestScript())
- .addTransitiveArtifacts(plugins());
- if (!runWithLabDevice()) {
- runfilesBuilder
- .addArtifact(stdRedirectDylib())
- .addTransitiveArtifacts(deviceRunfiles())
- .addArtifacts(testRunner().asSet());
- } else {
- runfilesBuilder.addTransitiveArtifacts(labDeviceRunfiles());
- }
-
- if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
- runfilesBuilder.addArtifact(ruleContext.getHostPrerequisiteArtifact(IosTest.MCOV_TOOL_ATTR));
- runfilesBuilder.addTransitiveArtifacts(instrumentedFilesProvider.getInstrumentedFiles());
- }
-
- return this;
- }
-
- /**
- * Returns any additional providers that need to be exported to the rule context to the passed
- * builder.
- */
- public Iterable<Info> getExtraProviders() {
- IosDeviceProvider deviceProvider =
- ruleContext.getPrerequisite(
- IosTest.TARGET_DEVICE, Mode.TARGET, IosDeviceProvider.SKYLARK_CONSTRUCTOR);
- DottedVersion xcodeVersion = deviceProvider.getXcodeVersion();
-
- ImmutableMap.Builder<String, String> envBuilder = ImmutableMap.builder();
-
- if (xcodeVersion != null) {
- envBuilder.putAll(AppleConfiguration.getXcodeVersionEnv(xcodeVersion));
- }
-
- if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
- envBuilder.put("COVERAGE_GCOV_PATH",
- ruleContext.getHostPrerequisiteArtifact(IosTest.OBJC_GCOV_ATTR).getExecPathString());
- envBuilder.put("APPLE_COVERAGE", "1");
- }
-
- return ImmutableList.<Info>of(new TestEnvironmentInfo(envBuilder.build()));
- }
-
- /**
- * Jar files for plugins to the test runner. May be empty.
- */
- private NestedSet<Artifact> plugins() {
- NestedSetBuilder<Artifact> pluginArtifacts = NestedSetBuilder.stableOrder();
- pluginArtifacts.addTransitive(
- PrerequisiteArtifacts.nestedSet(ruleContext, IosTest.PLUGINS_ATTR, Mode.TARGET));
- if (ruleContext.getFragment(ObjcConfiguration.class).runMemleaks()) {
- pluginArtifacts.addTransitive(
- PrerequisiteArtifacts.nestedSet(ruleContext, IosTest.MEMLEAKS_PLUGIN_ATTR, Mode.TARGET));
- }
- return pluginArtifacts.build();
- }
-
- /**
- * Runfiles required in order to use the specified target device.
- */
- private NestedSet<Artifact> deviceRunfiles() {
- return ruleContext.getPrerequisite(IosTest.TARGET_DEVICE, Mode.TARGET, RunfilesProvider.class)
- .getDefaultRunfiles().getAllArtifacts();
- }
-
- /**
- * Runfiles required in order to use the specified target device.
- */
- private NestedSet<Artifact> labDeviceRunfiles() {
- return ruleContext
- .getPrerequisite(IosTest.TEST_TARGET_DEVICE_ATTR, Mode.TARGET, RunfilesProvider.class)
- .getDefaultRunfiles().getAllArtifacts();
- }
-
- /**
- * Adds files which must be built in order to run this test to builder.
- */
- public TestSupport addFilesToBuild(NestedSetBuilder<Artifact> builder)
- throws InterruptedException {
- builder.add(testBundleIpa()).addAll(testHarnessIpa().asSet());
- return this;
- }
-
- /**
- * Returns the base name of the artifact, with the .ipa stuffix stripped.
- */
- private static String baseNameWithoutIpa(Artifact artifact) {
- String baseName = artifact.getExecPath().getBaseName();
- Preconditions.checkState(baseName.endsWith(".ipa"),
- "%s should end in .ipa but doesn't", baseName);
- return baseName.substring(0, baseName.length() - 4);
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcTestAppProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcTestAppProvider.java
deleted file mode 100644
index 09bbad98dc..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcTestAppProvider.java
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2015 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.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeInfo;
-import com.google.devtools.build.lib.packages.NativeProvider;
-import com.google.devtools.build.lib.packages.NativeProvider.WithLegacySkylarkName;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
-
-/** Supplies information needed when a dependency serves as an {@code xctest_app}. */
-@Immutable
-@SkylarkModule(
- name = "XcTestAppProvider",
- category = SkylarkModuleCategory.PROVIDER,
- doc =
- "Deprecated. A provider for XCTest apps for testing. This is a legacy provider and should "
- + "not be used."
-)
-public final class XcTestAppProvider extends NativeInfo {
- /**
- * The skylark struct key name for a rule implementation to use when exporting an ObjcProvider.
- */
- public static final String XCTEST_APP_SKYLARK_PROVIDER_NAME = "xctest_app";
-
- public static final NativeProvider<XcTestAppProvider> SKYLARK_CONSTRUCTOR = new Constructor();
-
- private final Artifact bundleLoader;
- private final Artifact ipa;
- private final ObjcProvider objcProvider;
-
- XcTestAppProvider(Artifact bundleLoader, Artifact ipa, ObjcProvider objcProvider) {
- super(SKYLARK_CONSTRUCTOR, getSkylarkFields(bundleLoader, ipa, objcProvider));
- this.bundleLoader = Preconditions.checkNotNull(bundleLoader);
- this.ipa = Preconditions.checkNotNull(ipa);
- this.objcProvider = Preconditions.checkNotNull(objcProvider);
- }
-
- /** The bundle loader, which corresponds to the test app's binary. */
- public Artifact getBundleLoader() {
- return bundleLoader;
- }
-
- /** The test app's IPA. */
- public Artifact getIpa() {
- return ipa;
- }
-
- /**
- * An {@link ObjcProvider} that should be included by any test target that uses this app as its
- * {@code xctest_app}. This is <strong>not</strong> a typical {@link ObjcProvider} - it has
- * certain linker-releated keys omitted, such as {@link ObjcProvider#LIBRARY}, since XcTests have
- * access to symbols in their test rig without linking them into the main test binary.
- */
- public ObjcProvider getObjcProvider() {
- return objcProvider;
- }
-
- private static ImmutableMap<String, Object> getSkylarkFields(
- Artifact bundleLoader, Artifact ipa, ObjcProvider objcProvider) {
- return new ImmutableMap.Builder<String, Object>()
- .put("bundle_loader", bundleLoader)
- .put("ipa", ipa)
- .put("objc", objcProvider)
- .build();
- }
-
- private static class Constructor extends NativeProvider<XcTestAppProvider>
- implements WithLegacySkylarkName {
-
- private Constructor() {
- super(XcTestAppProvider.class, "xctest_app_provider");
- }
-
- @Override
- public String getSkylarkName() {
- return XCTEST_APP_SKYLARK_PROVIDER_NAME;
- }
-
- @Override
- public String getErrorMessageFormatForUnknownField() {
- return "XcTestAppProvider field '%s' could not be instantiated";
- }
- }
-}