diff options
author | 2017-11-01 11:34:43 -0400 | |
---|---|---|
committer | 2017-11-02 10:04:01 -0400 | |
commit | 4ad39f1301f29b1024e6c970765ab9721cac8be0 (patch) | |
tree | 8b1753b1dedb62c2739eacd13c58dbd004d17917 /src | |
parent | 64878508ca2e8c104e281e885890359b18899c80 (diff) |
Expose Apple Multi-architecture Split Transition to Skylark.
This omits validation for this transition, which will follow in a future change.
RELNOTES: None.
PiperOrigin-RevId: 174183651
Diffstat (limited to 'src')
4 files changed, 93 insertions, 1 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java index dbbf27fd80..ad927c4801 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet; import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition; import com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTemplate; import com.google.devtools.build.lib.packages.Attribute.SplitTransition; +import com.google.devtools.build.lib.packages.Attribute.SplitTransitionProvider; import com.google.devtools.build.lib.packages.AttributeValueSource; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.Provider; @@ -291,6 +292,8 @@ public final class SkylarkAttr implements SkylarkValue { builder.cfg(ConfigurationTransition.HOST); } else if (trans instanceof SplitTransition<?>) { builder.cfg((SplitTransition<?>) trans); + } else if (trans instanceof SplitTransitionProvider) { + builder.cfg((SplitTransitionProvider) trans); } else if (!trans.equals("target")) { throw new EvalException(ast.getLocation(), "cfg must be either 'data', 'host', or 'target'."); 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 d61b803e60..f9c20db7d6 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 @@ -21,6 +21,7 @@ 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; +import com.google.devtools.build.lib.packages.Attribute.SplitTransitionProvider; import com.google.devtools.build.lib.packages.Info; import com.google.devtools.build.lib.packages.Provider; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; @@ -314,6 +315,31 @@ public class AppleSkylarkCommon { platform, xcodeConfig.getSdkVersionForPlatform(platform)); } + @SkylarkCallable( + name = "multi_arch_split", + doc = "A configuration transition for rule attributes to build dependencies in one or" + + " more Apple platforms. " + + "<p>Use of this transition requires that the 'platform_type' and 'minimum_os_version'" + + " string attributes are defined and mandatory on the rule.</p>" + + "<p>The value of the platform_type attribute will dictate the target architectures " + + " for which dependencies along this configuration transition will be built.</p>" + + "<p>Options are:</p>" + + "<ul>" + + "<li><code>ios</code>: architectures gathered from <code>--ios_multi_cpus</code>.</li>" + + "<li><code>macos</code>: architectures gathered from <code>--macos_cpus</code>.</li>" + + "<li><code>tvos</code>: architectures gathered from <code>--tvos_cpus</code>.</li>" + + "<li><code>watchos</code>: architectures gathered from <code>--watchos_cpus</code>." + + "</li></ul>" + + "<p>minimum_os_version should be a dotted version string such as '7.3', and is used to" + + " set the minimum operating system on the configuration similarly based on platform" + + " type. For example, specifying platform_type 'ios' and minimum_os_version '8.0' will" + + " ensure that dependencies are built with minimum iOS version '8.0'.", + structField = true + ) + public SplitTransitionProvider getMultiArchSplitProvider() { + return new MultiArchSplitTransitionProvider(); + } + @SkylarkSignature( name = "new_objc_provider", objectType = AppleSkylarkCommon.class, 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 7d0e9af46f..394c2202b7 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 @@ -35,6 +35,8 @@ 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.objc.ObjcRuleClasses.PlatformRule; +import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; +import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; import java.util.List; import java.util.stream.Collectors; @@ -42,7 +44,7 @@ import java.util.stream.Collectors; * {@link SplitTransitionProvider} implementation for multi-architecture apple rules which can * accept different apple platform types (such as ios or watchos). */ -public class MultiArchSplitTransitionProvider implements SplitTransitionProvider { +public class MultiArchSplitTransitionProvider implements SplitTransitionProvider, SkylarkValue { @VisibleForTesting static final String UNSUPPORTED_PLATFORM_TYPE_ERROR_FORMAT = @@ -147,6 +149,16 @@ public class MultiArchSplitTransitionProvider implements SplitTransitionProvider return new AppleBinaryTransition(platformType, minimumOsVersion); } + @Override + public boolean isImmutable() { + return true; + } + + @Override + public void repr(SkylarkPrinter printer) { + printer.append("apple_common.multi_arch_split"); + } + /** * Transition that results in one configured target per architecture specified in the * platform-specific cpu flag for a particular platform type (for example, --watchos_cpus diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java index 25c53ac660..2859878b69 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java @@ -20,10 +20,12 @@ import static com.google.devtools.build.lib.rules.objc.BundleableFile.BUNDLE_PAT import static org.junit.Assert.fail; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; import com.google.common.collect.ObjectArrays; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.util.ActionsTestUtil; import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.packages.SkylarkInfo; import com.google.devtools.build.lib.rules.apple.AppleToolchain; import com.google.devtools.build.lib.rules.apple.DottedVersion; import com.google.devtools.build.lib.rules.objc.ObjcCommandLineOptions.ObjcCrosstoolMode; @@ -1257,6 +1259,55 @@ public class ObjcSkylarkTest extends ObjcRuleTestCase { assertThat(skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR)).isNotNull(); } + @Test + public void testMultiArchSplitTransition() throws Exception { + scratch.file("examples/rule/BUILD"); + scratch.file( + "examples/rule/apple_rules.bzl", + "def my_rule_impl(ctx):", + " return_kwargs = {}", + " for cpu_value in ctx.split_attr.deps:", + " for child_target in ctx.split_attr.deps[cpu_value]:", + " return_kwargs[cpu_value] = struct(objc=child_target.objc)", + " return struct(**return_kwargs)", + "my_rule = rule(implementation = my_rule_impl,", + " attrs = {", + " 'deps': attr.label_list(cfg=apple_common.multi_arch_split, providers=[['objc']]),", + " 'platform_type': attr.string(mandatory=True),", + " 'minimum_os_version': attr.string(mandatory=True)},", + " fragments = ['apple'],", + ")"); + scratch.file("examples/apple_skylark/a.cc"); + scratch.file( + "examples/apple_skylark/BUILD", + "package(default_visibility = ['//visibility:public'])", + "load('/examples/rule/apple_rules', 'my_rule')", + "my_rule(", + " name = 'my_target',", + " deps = [':lib'],", + " platform_type = 'ios',", + " minimum_os_version='2.2'", + ")", + "objc_library(", + " name = 'lib',", + " srcs = ['a.m'],", + " hdrs = ['a.h']", + ")"); + + useConfiguration("--ios_multi_cpus=armv7,arm64"); + ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target"); + ObjcProvider armv7Objc = ((SkylarkInfo) skylarkTarget.get("ios_armv7")) + .getValue("objc", ObjcProvider.class); + ObjcProvider arm64Objc = ((SkylarkInfo) skylarkTarget.get("ios_arm64")) + .getValue("objc", ObjcProvider.class); + assertThat(armv7Objc).isNotNull(); + assertThat(arm64Objc).isNotNull(); + assertThat(Iterables.getOnlyElement(armv7Objc.getObjcLibraries()).getExecPathString()) + .contains("ios_armv7"); + assertThat(Iterables.getOnlyElement(arm64Objc.getObjcLibraries()).getExecPathString()) + .contains("ios_arm64"); + } + private void checkSkylarkRunMemleaksWithExpectedValue(boolean expectedValue) throws Exception { scratch.file("examples/rule/BUILD"); scratch.file( |