diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java index d178517614a9d1..bfca36f45fae26 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java @@ -48,6 +48,18 @@ public class ObjcCommandLineOptions extends FragmentOptions { + "devicetypes' on the machine the simulator will be run on.") public String iosSimulatorDevice; + @Option( + name = "ios_device", + defaultValue = "null", + documentationCategory = OptionDocumentationCategory.TESTING, + effectTags = {OptionEffectTag.TEST_RUNNER}, + help = + "The identifier, ECID, serial number, UDID, user-provided name, or DNS name of " + + "the device for running an iOS application. " + + "You can get a list of devices by running 'xcrun devicectl list " + + "devices'.") + public String iosDevice; + @Option( name = "ios_memleaks", defaultValue = "false", diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java index 8e803eba7e8d64..5f3e2677443f8c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java @@ -53,6 +53,7 @@ public class ObjcConfiguration extends Fragment implements ObjcConfigurationApi private final DottedVersion iosSimulatorVersion; private final String iosSimulatorDevice; + private final String iosDevice; private final boolean runMemleaks; private final CompilationMode compilationMode; private final ImmutableList fastbuildOptions; @@ -70,6 +71,7 @@ public ObjcConfiguration(BuildOptions buildOptions) { this.iosSimulatorDevice = objcOptions.iosSimulatorDevice; this.iosSimulatorVersion = DottedVersion.maybeUnwrap(objcOptions.iosSimulatorVersion); + this.iosDevice = objcOptions.iosDevice; this.runMemleaks = objcOptions.runMemleaks; this.compilationMode = Preconditions.checkNotNull(options.compilationMode, "compilationMode"); this.fastbuildOptions = ImmutableList.copyOf(objcOptions.fastbuildOptions); @@ -98,6 +100,14 @@ public DottedVersion getIosSimulatorVersion() { return iosSimulatorVersion; } + /** + * Returns the device when running an application on a physical device. + */ + @Override + public String getIosDevice() { + return iosDevice; + } + @Override public boolean runMemleaks() { return runMemleaks; diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ObjcConfigurationApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ObjcConfigurationApi.java index bcbcb596d910e1..537ef45e7f0c67 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ObjcConfigurationApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ObjcConfigurationApi.java @@ -48,6 +48,14 @@ public interface ObjcConfigurationApi extends StarlarkValue { @Nullable DottedVersionApi getIosSimulatorVersion(); + @StarlarkMethod( + name = "ios_device", + structField = true, + allowReturnNones = true, + doc = "The device identifier to use when running an iOS application.") + @Nullable + String getIosDevice(); + @StarlarkMethod( name = "run_memleaks", structField = true, diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkTest.java index baec12578d2d95..9c2a15f74e4c2a 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcStarlarkTest.java @@ -808,6 +808,61 @@ def swift_binary_impl(ctx): assertThat(signingCertificateName).isEqualTo("'Apple Developer'"); } + @Test + public void testStarlarkCanAccessObjcConfigurationForDevice() throws Exception { + scratch.file("examples/rule/BUILD"); + scratch.file( + "examples/rule/objc_rules.bzl", + """ + load("//myinfo:myinfo.bzl", "MyInfo") + + def swift_binary_impl(ctx): + compilation_mode_copts = ctx.fragments.objc.copts_for_current_compilation_mode + ios_device = ctx.fragments.objc.ios_device + signing_certificate_name = ctx.fragments.objc.signing_certificate_name + return MyInfo( + compilation_mode_copts = compilation_mode_copts, + ios_device = ios_device, + signing_certificate_name = signing_certificate_name, + ) + + swift_binary = rule( + implementation = swift_binary_impl, + fragments = ["objc"], + ) + """); + + scratch.file("examples/objc_starlark/a.m"); + scratch.file( + "examples/objc_starlark/BUILD", + """ + load("//examples/rule:objc_rules.bzl", "swift_binary") + + package(default_visibility = ["//visibility:public"]) + + swift_binary( + name = "my_target", + ) + """); + + useConfiguration( + "--compilation_mode=opt", + "--ios_multi_cpus=arm64", + "--ios_device='11111111-1111-1111-1111-11111111111'", + "--ios_signing_cert_name='Apple Developer'"); + ConfiguredTarget starlarkTarget = getConfiguredTarget("//examples/objc_starlark:my_target"); + StructImpl myInfo = getMyInfoFromTarget(starlarkTarget); + + @SuppressWarnings("unchecked") + List compilationModeCopts = (List) myInfo.getValue("compilation_mode_copts"); + Object iosDevice = myInfo.getValue("ios_device"); + Object signingCertificateName = myInfo.getValue("signing_certificate_name"); + + assertThat(compilationModeCopts).containsExactlyElementsIn(ObjcConfiguration.OPT_COPTS); + assertThat(iosDevice).isEqualTo("'11111111-1111-1111-1111-11111111111'"); + assertThat(signingCertificateName).isEqualTo("'Apple Developer'"); + } + @Test public void testSigningCertificateNameCanReturnNone() throws Exception { scratch.file("examples/rule/BUILD");