aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar allevato <allevato@google.com>2017-06-24 00:00:45 +0200
committerGravatar Marcel Hlopko <hlopko@google.com>2017-06-26 18:35:25 +0200
commit4bb735376958c3198fa664ca5247c93d9a3efcfb (patch)
tree4af3d349bd0b323c9dcbf7a753ea253ddfee8362 /src
parentaacacfa05038884e2b13898c8152d7d4c12d4e03 (diff)
Add apple_stub_binary rule.
This rule will be used by the Skylark bundling rules for product types that use stub binaries copied out of the SDK instead of user-built binaries. RELNOTES: None. PiperOrigin-RevId: 159998782
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java21
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java198
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinaryRule.java95
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java69
6 files changed, 366 insertions, 42 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 530a677674..ff1542b565 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
@@ -121,6 +121,7 @@ import com.google.devtools.build.lib.rules.java.proto.JavaProtoSkylarkCommon;
import com.google.devtools.build.lib.rules.objc.AppleBinaryRule;
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.AppleWatch1ExtensionRule;
import com.google.devtools.build.lib.rules.objc.AppleWatch2ExtensionRule;
import com.google.devtools.build.lib.rules.objc.AppleWatchExtensionBinaryRule;
@@ -563,6 +564,7 @@ public class BazelRuleClassProvider {
builder.addNativeAspectClass(objcProtoAspect);
builder.addRuleDefinition(new AppleBinaryRule(objcProtoAspect));
builder.addRuleDefinition(new AppleStaticLibraryRule(objcProtoAspect));
+ builder.addRuleDefinition(new AppleStubBinaryRule());
builder.addRuleDefinition(new ObjcProtoLibraryRule(objcProtoAspect));
builder.addRuleDefinition(new AppleCcToolchainRule());
@@ -588,6 +590,7 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new ObjcRuleClasses.SimulatorRule());
builder.addRuleDefinition(new ObjcRuleClasses.CompilingRule());
builder.addRuleDefinition(new ObjcRuleClasses.LinkingRule(objcProtoAspect));
+ builder.addRuleDefinition(new ObjcRuleClasses.PlatformRule());
builder.addRuleDefinition(new ObjcRuleClasses.MultiArchPlatformRule());
builder.addRuleDefinition(new ObjcRuleClasses.ResourcesRule());
builder.addRuleDefinition(new ObjcRuleClasses.AlwaysLinkRule());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java
index 372aa6f851..bfe8193cce 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java
@@ -16,7 +16,6 @@ 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.ImplicitOutputsFunction.fromTemplates;
import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
import static com.google.devtools.build.lib.syntax.Type.STRING;
@@ -26,7 +25,6 @@ import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
-import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
@@ -52,12 +50,6 @@ public class AppleBinaryRule implements RuleDefinition {
}
/**
- * Template for the fat binary output (using Apple's "lipo" tool to combine binaries of
- * multiple architectures).
- */
- private static final SafeImplicitOutputsFunction LIPOBIN = fromTemplates("%{name}_lipobin");
-
- /**
* There are 3 classes of fully linked binaries in Mach: executable, dynamic library, and
* loadable bundle.
*
@@ -89,7 +81,9 @@ public class AppleBinaryRule implements RuleDefinition {
new MultiArchSplitTransitionProvider();
return builder
.requiresConfigurationFragments(
- ObjcConfiguration.class, J2ObjcConfiguration.class, AppleConfiguration.class,
+ ObjcConfiguration.class,
+ J2ObjcConfiguration.class,
+ AppleConfiguration.class,
CppConfiguration.class)
.add(
attr("$is_executable", BOOLEAN)
@@ -123,8 +117,10 @@ public class AppleBinaryRule implements RuleDefinition {
This attribute is deprecated and will be removed soon. It currently has no effect.
"Extension-safe" link options may be added using the <code>linkopts</code> attribute.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
- .add(attr(EXTENSION_SAFE_ATTR_NAME, BOOLEAN).value(false)
- .nonconfigurable("Determines the configuration transition on deps"))
+ .add(
+ attr(EXTENSION_SAFE_ATTR_NAME, BOOLEAN)
+ .value(false)
+ .nonconfigurable("Determines the configuration transition on deps"))
.add(
attr(BUNDLE_LOADER_ATTR_NAME, LABEL)
.direct_compile_time_input()
@@ -143,7 +139,8 @@ public class AppleBinaryRule implements RuleDefinition {
binary. All transitive dependencies and <code>srcs</code> are linked.</li>
</ul>
<!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS -->*/
- .setImplicitOutputsFunction(ImplicitOutputsFunction.fromFunctions(LIPOBIN))
+ .setImplicitOutputsFunction(
+ ImplicitOutputsFunction.fromFunctions(ObjcRuleClasses.LIPOBIN_OUTPUT))
.cfg(AppleCrosstoolTransition.APPLE_CROSSTOOL_TRANSITION)
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java
new file mode 100644
index 0000000000..537cb9e561
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java
@@ -0,0 +1,198 @@
+// Copyright 2017 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.MULTI_ARCH_LINKED_BINARIES;
+import static com.google.devtools.build.lib.syntax.Type.STRING;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfigurationMakeVariableContext;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.FilesToRunProvider;
+import com.google.devtools.build.lib.analysis.MakeVariableExpander;
+import com.google.devtools.build.lib.analysis.MakeVariableExpander.ExpansionException;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
+import com.google.devtools.build.lib.rules.apple.AppleToolchain;
+import com.google.devtools.build.lib.rules.apple.Platform;
+import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
+import com.google.devtools.build.lib.util.StringUtil;
+import com.google.devtools.build.lib.vfs.PathFragment;
+
+/** Implementation for the "apple_stub_binary" rule. */
+public class AppleStubBinary implements RuleConfiguredTargetFactory {
+
+ /** Provides substitutions for the make variables that can be used in an xcenv_based_path */
+ private static class XcenvBasedPathVariableContext extends ConfigurationMakeVariableContext {
+ private final RuleContext ruleContext;
+
+ /** The platform used to build $(PLATFORM_DIR). */
+ private final Platform platform;
+
+ /** The complete set of variables that may be used in paths. */
+ public static final ImmutableList<String> DEFINED_VARS =
+ ImmutableList.of("$(SDKROOT)", "$(PLATFORM_DIR)");
+
+ public XcenvBasedPathVariableContext(RuleContext ruleContext, Platform platform) {
+ super(
+ ImmutableMap.<String, String>of(),
+ ruleContext.getRule().getPackage(),
+ ruleContext.getConfiguration());
+ this.ruleContext = ruleContext;
+ this.platform = platform;
+ }
+
+ /** Throws an exception if the given path is not rooted at a defined Make variable. */
+ public void validatePathRoot(String path) throws RuleErrorException {
+ for (String var : DEFINED_VARS) {
+ if (path.startsWith(var)) {
+ return;
+ }
+ }
+
+ throw ruleContext.throwWithAttributeError(
+ AppleStubBinaryRule.XCENV_BASED_PATH_ATTR,
+ String.format(
+ PATH_INCORRECTLY_ROOTED_ERROR_FORMAT,
+ StringUtil.joinEnglishList(XcenvBasedPathVariableContext.DEFINED_VARS, "or")));
+ }
+
+ @Override
+ public String lookupMakeVariable(String var) throws ExpansionException {
+ if (var.equals("SDKROOT")) {
+ return "__BAZEL_XCODE_SDKROOT__";
+ }
+ if (var.equals("PLATFORM_DIR")) {
+ return AppleToolchain.platformDir(platform.getNameInPlist());
+ }
+ // Intentionally do not call super, because we only want to allow these specific variables and
+ // discard any that might be inherited from toolchains and other contexts.
+ throw new MakeVariableExpander.ExpansionException("$(" + var + ") not defined");
+ }
+ }
+
+ @VisibleForTesting
+ public static final String PATH_INCORRECTLY_ROOTED_ERROR_FORMAT =
+ "The stub binary path must be rooted at %s";
+
+ @VisibleForTesting
+ public static final String PATH_NOT_NORMALIZED_ERROR =
+ "The stub binary path must be normalized (i.e., not contain \".\" or \"..\")";
+
+ @Override
+ public final ConfiguredTarget create(RuleContext ruleContext)
+ throws InterruptedException, RuleErrorException {
+ MultiArchSplitTransitionProvider.validateMinimumOs(ruleContext);
+ PlatformType platformType = MultiArchSplitTransitionProvider.getPlatformType(ruleContext);
+
+ AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
+
+ Platform platform = appleConfiguration.getMultiArchPlatform(platformType);
+ ImmutableListMultimap<BuildConfiguration, ObjcProvider> configurationToDepsMap =
+ ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT, ObjcProvider.class);
+
+ Artifact outputArtifact =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext).combinedArchitectureBinary();
+
+ registerActions(ruleContext, appleConfiguration, platform, outputArtifact);
+
+ NestedSetBuilder<Artifact> filesToBuild =
+ NestedSetBuilder.<Artifact>stableOrder().add(outputArtifact);
+ RuleConfiguredTargetBuilder targetBuilder =
+ ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build());
+
+ ObjcProvider.Builder objcProviderBuilder = new ObjcProvider.Builder();
+ for (ObjcProvider depProvider : configurationToDepsMap.values()) {
+ objcProviderBuilder.addTransitiveAndPropagate(depProvider);
+ }
+ objcProviderBuilder.add(MULTI_ARCH_LINKED_BINARIES, outputArtifact);
+
+ ObjcProvider objcProvider = objcProviderBuilder.build();
+ // TODO(cparsons): Stop propagating ObjcProvider directly from this rule.
+ targetBuilder.addProvider(ObjcProvider.class, objcProvider);
+
+ targetBuilder.addNativeDeclaredProvider(
+ new AppleExecutableBinaryProvider(outputArtifact, objcProvider));
+
+ return targetBuilder.build();
+ }
+
+ private static FilesToRunProvider xcrunwrapper(RuleContext ruleContext) {
+ return ruleContext.getExecutablePrerequisite("$xcrunwrapper", Mode.HOST);
+ }
+
+ /** Registers the actions that copy the stub binary to the target's output. */
+ private static void registerActions(
+ RuleContext ruleContext,
+ AppleConfiguration appleConfiguration,
+ Platform platform,
+ Artifact outputBinary)
+ throws RuleErrorException {
+ CustomCommandLine copyCommandLine =
+ new CustomCommandLine.Builder()
+ .add("/bin/cp")
+ .add(resolveXcenvBasedPath(ruleContext, platform))
+ .addExecPaths(ImmutableList.of(outputBinary))
+ .build();
+
+ ruleContext.registerAction(
+ ObjcRuleClasses.spawnAppleEnvActionBuilder(appleConfiguration, platform)
+ .setExecutable(xcrunwrapper(ruleContext))
+ .setCommandLine(copyCommandLine)
+ .setMnemonic("CopyStubExecutable")
+ .addOutput(outputBinary)
+ .disableSandboxing()
+ .build(ruleContext));
+ }
+
+ /**
+ * Returns the value of the xcenv_based_path attribute, emitting an error if its format is
+ * invalid.
+ *
+ * @param ruleContext the rule context
+ * @param platform the Apple platform
+ * @return the path string, if it was valid
+ * @throws RuleErrorException If the path string was invalid because it was not rooted at one of
+ * the allowed environment variables or it was not normalized
+ */
+ private static String resolveXcenvBasedPath(RuleContext ruleContext, Platform platform)
+ throws RuleErrorException {
+ String pathString =
+ ruleContext.attributes().get(AppleStubBinaryRule.XCENV_BASED_PATH_ATTR, STRING);
+ XcenvBasedPathVariableContext makeVariableContext =
+ new XcenvBasedPathVariableContext(ruleContext, platform);
+
+ makeVariableContext.validatePathRoot(pathString);
+
+ PathFragment pathFragment = PathFragment.create(pathString);
+ if (!pathFragment.isNormalized()) {
+ throw ruleContext.throwWithAttributeError(
+ AppleStubBinaryRule.XCENV_BASED_PATH_ATTR, PATH_NOT_NORMALIZED_ERROR);
+ }
+
+ return ruleContext.expandMakeVariables(
+ AppleStubBinaryRule.XCENV_BASED_PATH_ATTR, pathString, makeVariableContext);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinaryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinaryRule.java
new file mode 100644
index 0000000000..f2e2c59a2d
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinaryRule.java
@@ -0,0 +1,95 @@
+// Copyright 2017 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_LIST;
+import static com.google.devtools.build.lib.syntax.Type.STRING;
+
+import com.google.common.collect.ImmutableList;
+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.TransitiveInfoProvider;
+import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.RuleClass.Builder;
+import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
+
+/** Rule definition for apple_stub_binary. */
+public class AppleStubBinaryRule implements RuleDefinition {
+
+ public static final String XCENV_BASED_PATH_ATTR = "xcenv_based_path";
+
+ @Override
+ public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
+ MultiArchSplitTransitionProvider splitTransitionProvider =
+ new MultiArchSplitTransitionProvider();
+ return builder
+ .requiresConfigurationFragments(ObjcConfiguration.class, AppleConfiguration.class)
+ /* <!-- #BLAZE_RULE(apple_stub_binary).ATTRIBUTE(xcenv_based_path) -->
+ The path to the stub executable within an Xcode platform or SDK bundle. This path must be
+ rooted at either <code>$(SDKROOT)</code> or <code>$(PLATFORM_DIR)</code> (written with
+ parentheses, as they are "Make" variables, not shell variables).
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(attr(XCENV_BASED_PATH_ATTR, STRING))
+ /* <!-- #BLAZE_RULE(apple_stub_binary).ATTRIBUTE(deps) -->
+ The list of targets whose resources will be included in the final bundle.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(
+ attr("deps", LABEL_LIST)
+ .direct_compile_time_input()
+ .mandatoryNativeProviders(
+ ImmutableList.<Class<? extends TransitiveInfoProvider>>of(ObjcProvider.class))
+ .allowedFileTypes()
+ .cfg(splitTransitionProvider))
+ /*<!-- #BLAZE_RULE(apple_stub_binary).IMPLICIT_OUTPUTS -->
+ <ul>
+ <li><code><var>name</var></code>: the stub executable copied from the Xcode
+ platform/SDK location.</li>
+ </ul>
+ <!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS -->*/
+ .setImplicitOutputsFunction(
+ ImplicitOutputsFunction.fromFunctions(ObjcRuleClasses.LIPOBIN_OUTPUT))
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("apple_stub_binary")
+ .factoryClass(AppleStubBinary.class)
+ .ancestors(
+ BaseRuleClasses.BaseRule.class,
+ ObjcRuleClasses.PlatformRule.class,
+ ObjcRuleClasses.XcrunRule.class)
+ .build();
+ }
+}
+
+/*<!-- #BLAZE_RULE (NAME = apple_stub_binary, TYPE = BINARY, FAMILY = Objective-C) -->
+
+<p>This rule copies a stub executable (such as that used by a watchOS application or an iMessage
+sticker pack) from a location in an Xcode platform or SDK bundle to the output.</p>
+
+<p>This rule is meant to be used internally by the Apple bundling rules and does has limited use
+outside of that. Its purpose is to provide target uniformity across all Apple bundles whether they
+contain a user binary or a stub binary and to ensure that the platform transition is still present
+for those stubs so that platform selection works as expected in downstream resource dependencies.
+</p>
+
+${IMPLICIT_OUTPUTS}
+
+<!-- #END_BLAZE_RULE -->*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
index 49f2dcaeaa..8c72933334 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
@@ -33,7 +33,7 @@ import com.google.devtools.build.lib.rules.apple.AppleConfiguration.Configuratio
import com.google.devtools.build.lib.rules.apple.DottedVersion;
import com.google.devtools.build.lib.rules.apple.Platform;
import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
-import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.MultiArchPlatformRule;
+import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.PlatformRule;
import java.util.List;
/**
@@ -63,11 +63,12 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
*/
public static PlatformType getPlatformType(RuleContext ruleContext) throws RuleErrorException {
String attributeValue =
- ruleContext.attributes().get(MultiArchPlatformRule.PLATFORM_TYPE_ATTR_NAME, STRING);
+ ruleContext.attributes().get(PlatformRule.PLATFORM_TYPE_ATTR_NAME, STRING);
try {
return getPlatformType(attributeValue);
} catch (IllegalArgumentException exception) {
- throw ruleContext.throwWithAttributeError(MultiArchPlatformRule.PLATFORM_TYPE_ATTR_NAME,
+ throw ruleContext.throwWithAttributeError(
+ PlatformRule.PLATFORM_TYPE_ATTR_NAME,
String.format(UNSUPPORTED_PLATFORM_TYPE_ERROR_FORMAT, attributeValue));
}
}
@@ -79,18 +80,19 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
* an invalid value
*/
public static void validateMinimumOs(RuleContext ruleContext) throws RuleErrorException {
- String attributeValue =
- ruleContext.attributes().get(MultiArchPlatformRule.MINIMUM_OS_VERSION, STRING);
+ String attributeValue = ruleContext.attributes().get(PlatformRule.MINIMUM_OS_VERSION, STRING);
// TODO(b/37096178): This should be a mandatory attribute.
if (!Strings.isNullOrEmpty(attributeValue)) {
try {
DottedVersion minimumOsVersion = DottedVersion.fromString(attributeValue);
if (minimumOsVersion.hasAlphabeticCharacters() || minimumOsVersion.numComponents() > 2) {
- throw ruleContext.throwWithAttributeError(MultiArchPlatformRule.MINIMUM_OS_VERSION,
+ throw ruleContext.throwWithAttributeError(
+ PlatformRule.MINIMUM_OS_VERSION,
String.format(INVALID_VERSION_STRING_ERROR_FORMAT, attributeValue));
}
} catch (IllegalArgumentException exception) {
- throw ruleContext.throwWithAttributeError(MultiArchPlatformRule.MINIMUM_OS_VERSION,
+ throw ruleContext.throwWithAttributeError(
+ PlatformRule.MINIMUM_OS_VERSION,
String.format(INVALID_VERSION_STRING_ERROR_FORMAT, attributeValue));
}
}
@@ -116,10 +118,8 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider
@Override
public SplitTransition<?> apply(Rule fromRule) {
NonconfigurableAttributeMapper attrMapper = NonconfigurableAttributeMapper.of(fromRule);
- String platformTypeString =
- attrMapper.get(MultiArchPlatformRule.PLATFORM_TYPE_ATTR_NAME, STRING);
- String minimumOsVersionString =
- attrMapper.get(MultiArchPlatformRule.MINIMUM_OS_VERSION, STRING);
+ String platformTypeString = attrMapper.get(PlatformRule.PLATFORM_TYPE_ATTR_NAME, STRING);
+ String minimumOsVersionString = attrMapper.get(PlatformRule.MINIMUM_OS_VERSION, STRING);
PlatformType platformType;
Optional<DottedVersion> minimumOsVersion;
try {
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 eef0a42b8c..163704f760 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
@@ -19,6 +19,7 @@ import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTran
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
+import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;
import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
import static com.google.devtools.build.lib.syntax.Type.STRING;
import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
@@ -44,6 +45,7 @@ import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
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.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
@@ -830,6 +832,12 @@ public class ObjcRuleClasses {
static final String PROTOBUF_WELL_KNOWN_TYPES = "$protobuf_well_known_types";
/**
+ * Template for the fat binary output (using Apple's "lipo" tool to combine binaries of multiple
+ * architectures).
+ */
+ static final SafeImplicitOutputsFunction LIPOBIN_OUTPUT = fromTemplates("%{name}_lipobin");
+
+ /**
* Common attributes for {@code objc_*} rules that link sources and dependencies.
*/
public static class LinkingRule implements RuleDefinition {
@@ -884,16 +892,16 @@ public class ObjcRuleClasses {
}
/**
- * Common attributes for apple rules that build multi-architecture outputs for a given platform
- * type (such as ios or watchos).
+ * Common attributes for apple rules that produce outputs for a given platform type (such as ios
+ * or watchos).
*/
- public static class MultiArchPlatformRule implements RuleDefinition {
+ public static class PlatformRule implements RuleDefinition {
/**
* Attribute name for apple platform type (e.g. ios or watchos).
*/
static final String PLATFORM_TYPE_ATTR_NAME = "platform_type";
-
+
/**
* Attribute name for the minimum OS version (e.g. "7.3").
*/
@@ -901,16 +909,8 @@ public class ObjcRuleClasses {
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
- MultiArchSplitTransitionProvider splitTransitionProvider =
- new MultiArchSplitTransitionProvider();
return builder
- // This is currently a hack to obtain all child configurations regardless of the attribute
- // values of this rule -- this rule does not currently use the actual info provided by
- // this attribute.
- .add(attr(CHILD_CONFIG_ATTR, LABEL)
- .cfg(splitTransitionProvider)
- .value(ObjcRuleClasses.APPLE_TOOLCHAIN))
- /* <!-- #BLAZE_RULE($apple_multiarch_rule).ATTRIBUTE(platform_type) -->
+ /* <!-- #BLAZE_RULE($apple_platform_rule).ATTRIBUTE(platform_type) -->
The type of platform for which to create artifacts in this rule.
This dictates which Apple platform SDK is used for compilation/linking and which flag is
@@ -935,13 +935,14 @@ public class ObjcRuleClasses {
</ul>
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
// TODO(b/37635370): Remove the "ios" default and make this mandatory.
- .add(attr(PLATFORM_TYPE_ATTR_NAME, STRING)
- .value(PlatformType.IOS.toString())
- .nonconfigurable("Determines the configuration transition on deps"))
- /* <!-- #BLAZE_RULE($apple_multiarch_rule).ATTRIBUTE(minimum_os) -->
+ .add(
+ attr(PLATFORM_TYPE_ATTR_NAME, STRING)
+ .value(PlatformType.IOS.toString())
+ .nonconfigurable("Determines the configuration transition on deps"))
+ /* <!-- #BLAZE_RULE($apple_platform_rule).ATTRIBUTE(minimum_os) -->
The minimum OS version that this target and its dependencies should be built for.
- This should be a dotted version string such as "7.3".
+ This should be a dotted version string such as "7.3".
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
// TODO(b/37096178): This should be a mandatory attribute.
.add(
@@ -953,9 +954,39 @@ public class ObjcRuleClasses {
@Override
public Metadata getMetadata() {
return RuleDefinition.Metadata.builder()
+ .name("$apple_platform_rule")
+ .type(RuleClassType.ABSTRACT)
+ .build();
+ }
+ }
+
+ /**
+ * Common attributes for apple rules that build multi-architecture outputs for a given platform
+ * type (such as ios or watchos).
+ */
+ public static class MultiArchPlatformRule implements RuleDefinition {
+
+ @Override
+ public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
+ MultiArchSplitTransitionProvider splitTransitionProvider =
+ new MultiArchSplitTransitionProvider();
+ return builder
+ // This is currently a hack to obtain all child configurations regardless of the attribute
+ // values of this rule -- this rule does not currently use the actual info provided by
+ // this attribute.
+ .add(
+ attr(CHILD_CONFIG_ATTR, LABEL)
+ .cfg(splitTransitionProvider)
+ .value(ObjcRuleClasses.APPLE_TOOLCHAIN))
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
.name("$apple_multiarch_rule")
.type(RuleClassType.ABSTRACT)
- .ancestors(CrosstoolRule.class)
+ .ancestors(PlatformRule.class, CrosstoolRule.class)
.build();
}
}