in src/com/facebook/buck/apple/AppleTestDescription.java [188:467]
public BuildRule createBuildRule(
BuildRuleCreationContextWithTargetGraph context,
BuildTarget buildTarget,
BuildRuleParams params,
AppleTestDescriptionArg args) {
ActionGraphBuilder graphBuilder = context.getActionGraphBuilder();
args.checkDuplicateSources(graphBuilder.getSourcePathResolver());
ProjectFilesystem projectFilesystem = context.getProjectFilesystem();
CxxPlatformsProvider cxxPlatformsProvider =
getCxxPlatformsProvider(buildTarget.getTargetConfiguration());
if (buildTarget.getFlavors().contains(COMPILE_DEPS)) {
return createCompileDepsRule(
cxxPlatformsProvider, buildTarget, graphBuilder, context, params, args);
}
if (!appleConfig.shouldUseSwiftDelegate()) {
Optional<BuildRule> buildRule =
appleLibraryDescription.createSwiftBuildRule(
buildTarget,
projectFilesystem,
graphBuilder,
context.getCellPathResolver(),
args,
Optional.of(this));
if (buildRule.isPresent()) {
return buildRule.get();
}
}
if (args.getUiTestTargetApp().isPresent() && !args.getIsUiTest()) {
throw new HumanReadableException(
"Invalid configuration for %s with 'ui_test_target_app' specified, but 'is_ui_test' set to false or 'test_host_app' not specified",
buildTarget);
}
AppleDebugFormat debugFormat =
AppleDebugFormat.FLAVOR_DOMAIN
.getValue(buildTarget)
.orElse(appleConfig.getDefaultDebugInfoFormatForTests());
if (buildTarget.getFlavors().contains(debugFormat.getFlavor())) {
buildTarget = buildTarget.withoutFlavors(debugFormat.getFlavor());
}
boolean createBundle =
Sets.intersection(buildTarget.getFlavors().getSet(), AUXILIARY_LIBRARY_FLAVORS).isEmpty();
// Flavors pertaining to the library targets that are generated.
Sets.SetView<Flavor> libraryFlavors =
Sets.difference(buildTarget.getFlavors().getSet(), AUXILIARY_LIBRARY_FLAVORS);
boolean addDefaultPlatform = libraryFlavors.isEmpty();
ImmutableSet.Builder<Flavor> extraFlavorsBuilder = ImmutableSet.builder();
if (createBundle) {
extraFlavorsBuilder.add(LIBRARY_FLAVOR, CxxDescriptionEnhancer.MACH_O_BUNDLE_FLAVOR);
}
extraFlavorsBuilder.add(debugFormat.getFlavor());
if (addDefaultPlatform) {
Flavor defaultCxxFlavor =
args.getDefaultPlatform()
.orElse(cxxPlatformsProvider.getDefaultUnresolvedCxxPlatform().getFlavor());
extraFlavorsBuilder.add(defaultCxxFlavor);
}
FlavorDomain<UnresolvedAppleCxxPlatform> appleCxxPlatformFlavorDomain =
getAppleCxxPlatformsFlavorDomain(buildTarget.getTargetConfiguration());
Optional<MultiarchFileInfo> multiarchFileInfo =
MultiarchFileInfos.create(appleCxxPlatformFlavorDomain, buildTarget);
AppleCxxPlatform appleCxxPlatform;
ImmutableList<CxxPlatform> cxxPlatforms;
TargetConfiguration targetConfiguration = buildTarget.getTargetConfiguration();
if (multiarchFileInfo.isPresent()) {
FlavorDomain<UnresolvedCxxPlatform> cxxPlatformFlavorDomain =
cxxPlatformsProvider.getUnresolvedCxxPlatforms();
ImmutableList.Builder<CxxPlatform> cxxPlatformBuilder = ImmutableList.builder();
for (BuildTarget thinTarget : multiarchFileInfo.get().getThinTargets()) {
cxxPlatformBuilder.add(
cxxPlatformFlavorDomain
.getValue(thinTarget)
.get()
.resolve(graphBuilder, targetConfiguration));
}
cxxPlatforms = cxxPlatformBuilder.build();
appleCxxPlatform =
appleCxxPlatformFlavorDomain
.getValue(multiarchFileInfo.get().getRepresentativePlatformFlavor())
.resolve(graphBuilder);
} else {
CxxPlatform cxxPlatform =
ApplePlatforms.getCxxPlatformForBuildTarget(
cxxPlatformsProvider, buildTarget, args.getDefaultPlatform())
.resolve(graphBuilder, buildTarget.getTargetConfiguration());
cxxPlatforms = ImmutableList.of(cxxPlatform);
appleCxxPlatform =
verifyAppleCxxPlatform(appleCxxPlatformFlavorDomain, cxxPlatform, buildTarget)
.resolve(graphBuilder);
}
Optional<TestHostInfo> testHostWithTargetApp = Optional.empty();
if (args.getTestHostApp().isPresent()) {
testHostWithTargetApp =
Optional.of(
createTestHostInfo(
buildTarget,
args.getIsUiTest(),
graphBuilder,
args.getTestHostApp().get(),
args.getUiTestTargetApp(),
debugFormat,
libraryFlavors,
cxxPlatforms));
}
BuildTarget libraryTarget =
buildTarget
.withAppendedFlavors(extraFlavorsBuilder.build())
.withAppendedFlavors(debugFormat.getFlavor())
.withAppendedFlavors(LinkerMapMode.NO_LINKER_MAP.getFlavor());
BuildRule library =
createTestLibraryRule(
context,
params,
graphBuilder,
args,
testHostWithTargetApp.flatMap(TestHostInfo::getTestHostAppBinarySourcePath),
testHostWithTargetApp.map(TestHostInfo::getBlacklist).orElse(ImmutableSet.of()),
libraryTarget,
RichStream.from(args.getTestHostApp()).toImmutableSortedSet(Ordering.natural()));
if (!createBundle || SwiftLibraryDescription.isSwiftTarget(libraryTarget)) {
return library;
}
String platformName = appleCxxPlatform.getAppleSdk().getApplePlatform().getName();
BuildTarget appleBundleBuildTarget =
buildTarget.withAppendedFlavors(
BUNDLE_FLAVOR,
debugFormat.getFlavor(),
LinkerMapMode.NO_LINKER_MAP.getFlavor(),
AppleDescriptions.NO_INCLUDE_FRAMEWORKS_FLAVOR);
AppleBundle bundle =
AppleBundle.class.cast(
graphBuilder.computeIfAbsent(
appleBundleBuildTarget,
ignored ->
AppleDescriptions.createAppleBundle(
xcodeDescriptions,
getCxxPlatformsProvider(targetConfiguration),
appleCxxPlatformFlavorDomain,
context.getTargetGraph(),
appleBundleBuildTarget,
projectFilesystem,
params.withDeclaredDeps(
ImmutableSortedSet.<BuildRule>naturalOrder()
.add(library)
.addAll(params.getDeclaredDeps().get())
.build()),
graphBuilder,
toolchainProvider.getByName(
CodeSignIdentityStore.DEFAULT_NAME,
targetConfiguration,
CodeSignIdentityStore.class),
toolchainProvider.getByName(
ProvisioningProfileStore.DEFAULT_NAME,
targetConfiguration,
ProvisioningProfileStore.class),
Optional.of(library.getBuildTarget()),
Optional.empty(),
args.getDefaultPlatform(),
args.getExtension(),
Optional.empty(),
args.getInfoPlist(),
args.getInfoPlistSubstitutions(),
args.getDeps(),
args.getTests(),
debugFormat,
appleConfig.useDryRunCodeSigning(),
appleConfig.cacheBundlesAndPackages(),
appleConfig.shouldVerifyBundleResources(),
appleConfig.assetCatalogValidation(),
args.getAssetCatalogsCompilationOptions(),
args.getCodesignFlags(),
args.getCodesignIdentity(),
Optional.empty(),
Optional.empty(),
Optional.empty(),
appleConfig.getCodesignTimeout(),
swiftBuckConfig.getCopyStdlibToFrameworks(),
swiftBuckConfig.getUseLipoThin(),
cxxBuckConfig.shouldCacheStrip(),
appleConfig.useEntitlementsWhenAdhocCodeSigning(),
Predicates.alwaysTrue(),
Optional.empty())));
Optional<SourcePath> xctool =
getXctool(projectFilesystem, params, targetConfiguration, graphBuilder);
if (args.getSpecs().isPresent()) {
UserVerify.verify(
args.getRunner().isPresent(),
"runner should be specified for rules implementing test protocol");
BuildRule runnerRule = graphBuilder.requireRule(args.getRunner().get());
UserVerify.verify(
runnerRule instanceof ExternalTestRunner,
"runner should be an external_test_runner for apple_test");
ExternalTestRunner runner = (ExternalTestRunner) runnerRule;
StringWithMacrosConverter macrosConverter =
StringWithMacrosConverter.of(
buildTarget,
context.getCellPathResolver().getCellNameResolver(),
graphBuilder,
ImmutableList.of(
LocationMacroExpander.INSTANCE, AbsoluteOutputMacroExpander.INSTANCE));
return new AppleTestX(
runner.getBinary(),
TestRunnerSpecCoercer.coerce(args.getSpecs().get(), macrosConverter),
xctool,
appleConfig.getXctoolStutterTimeoutMs(),
appleCxxPlatform.getXctest(),
appleConfig.getXctestPlatformNames().contains(platformName),
platformName,
appleConfig.getXctoolDefaultDestinationSpecifier(),
buildTarget,
projectFilesystem,
params.withDeclaredDeps(ImmutableSortedSet.of(bundle)).withoutExtraDeps(),
bundle,
testHostWithTargetApp.map(TestHostInfo::getTestHostApp),
testHostWithTargetApp.flatMap(TestHostInfo::getUiTestTargetApp),
args.getContacts(),
args.getLabels(),
toolchainProvider.getByName(
AppleDeveloperDirectoryForTestsProvider.DEFAULT_NAME,
targetConfiguration,
AppleDeveloperDirectoryForTestsProvider.class),
args.getIsUiTest(),
args.getSnapshotReferenceImagesPath(),
args.getSnapshotImagesDiffPath(),
appleConfig.useIdb(),
appleConfig.getIdbPath());
}
return new AppleTest(
xctool,
appleConfig.getXctoolStutterTimeoutMs(),
appleCxxPlatform.getXctest(),
appleConfig.getXctestPlatformNames().contains(platformName),
platformName,
appleConfig.getXctoolDefaultDestinationSpecifier(),
Optional.of(args.getDestinationSpecifier()),
buildTarget,
projectFilesystem,
params.withDeclaredDeps(ImmutableSortedSet.of(bundle)).withoutExtraDeps(),
bundle,
testHostWithTargetApp.map(TestHostInfo::getTestHostApp),
testHostWithTargetApp.flatMap(TestHostInfo::getUiTestTargetApp),
args.getContacts(),
args.getLabels(),
args.getRunTestSeparately(),
toolchainProvider.getByName(
AppleDeveloperDirectoryForTestsProvider.DEFAULT_NAME,
targetConfiguration,
AppleDeveloperDirectoryForTestsProvider.class),
appleConfig.getTestLogDirectoryEnvironmentVariable(),
appleConfig.getTestLogLevelEnvironmentVariable(),
appleConfig.getTestLogLevel(),
args.getTestRuleTimeoutMs()
.map(Optional::of)
.orElse(
appleConfig
.getDelegate()
.getView(TestBuckConfig.class)
.getDefaultTestRuleTimeoutMs()),
args.getIsUiTest(),
args.getSnapshotReferenceImagesPath(),
args.getSnapshotImagesDiffPath(),
args.getEnv(),
appleConfig.useIdb(),
appleConfig.getIdbPath());
}