in src/com/facebook/buck/apple/AppleBundle.java [363:680]
public ImmutableList<Step> getBuildSteps(
BuildContext context, BuildableContext buildableContext) {
ImmutableList.Builder<Step> stepsBuilder = ImmutableList.builder();
stepsBuilder.addAll(
MakeCleanDirectoryStep.of(
BuildCellRelativePath.fromCellRelativePath(
context.getBuildCellRootPath(), getProjectFilesystem(), bundleRoot)));
Path resourcesDestinationPath = bundleRoot.resolve(this.destinations.getResourcesPath());
if (assetCatalog.isPresent()) {
stepsBuilder.add(
MkdirStep.of(
BuildCellRelativePath.fromCellRelativePath(
context.getBuildCellRootPath(),
getProjectFilesystem(),
resourcesDestinationPath)));
Path bundleDir = assetCatalog.get().getOutputDir();
stepsBuilder.add(
CopyStep.forDirectory(
getProjectFilesystem(),
bundleDir,
resourcesDestinationPath,
CopyStep.DirectoryMode.CONTENTS_ONLY));
}
if (coreDataModel.isPresent()) {
stepsBuilder.add(
MkdirStep.of(
BuildCellRelativePath.fromCellRelativePath(
context.getBuildCellRootPath(),
getProjectFilesystem(),
resourcesDestinationPath)));
stepsBuilder.add(
CopyStep.forDirectory(
getProjectFilesystem(),
context
.getSourcePathResolver()
.getRelativePath(coreDataModel.get().getSourcePathToOutput()),
resourcesDestinationPath,
CopyStep.DirectoryMode.CONTENTS_ONLY));
}
if (sceneKitAssets.isPresent()) {
stepsBuilder.add(
MkdirStep.of(
BuildCellRelativePath.fromCellRelativePath(
context.getBuildCellRootPath(),
getProjectFilesystem(),
resourcesDestinationPath)));
stepsBuilder.add(
CopyStep.forDirectory(
getProjectFilesystem(),
context
.getSourcePathResolver()
.getRelativePath(sceneKitAssets.get().getSourcePathToOutput()),
resourcesDestinationPath,
CopyStep.DirectoryMode.CONTENTS_ONLY));
}
Path metadataPath = getMetadataPath();
AbsPath infoPlistInputPath =
AbsPath.of(context.getSourcePathResolver().getAbsolutePath(infoPlist));
Path infoPlistSubstitutionTempPath =
BuildTargetPaths.getScratchPath(getProjectFilesystem(), getBuildTarget(), "%s.plist");
Path infoPlistOutputPath = metadataPath.resolve("Info.plist");
stepsBuilder.add(
MkdirStep.of(
BuildCellRelativePath.fromCellRelativePath(
context.getBuildCellRootPath(), getProjectFilesystem(), metadataPath)));
if (needsPkgInfoFile()) {
// TODO(bhamiltoncx): This is only appropriate for .app bundles.
stepsBuilder.add(
new WriteFileStep(
getProjectFilesystem(),
"APPLWRUN",
metadataPath.resolve("PkgInfo"),
/* executable */ false));
}
stepsBuilder.add(
MkdirStep.of(
BuildCellRelativePath.fromCellRelativePath(
context.getBuildCellRootPath(),
getProjectFilesystem(),
infoPlistSubstitutionTempPath.getParent())),
new FindAndReplaceStep(
getProjectFilesystem(),
infoPlistInputPath,
infoPlistSubstitutionTempPath,
InfoPlistSubstitution.createVariableExpansionFunction(
withDefaults(
infoPlistSubstitutions,
ImmutableMap.of(
"EXECUTABLE_NAME", binaryName,
"PRODUCT_NAME", binaryName)))),
new PlistProcessStep(
getProjectFilesystem(),
infoPlistSubstitutionTempPath,
assetCatalog.map(AppleAssetCatalog::getOutputPlist),
infoPlistOutputPath,
getInfoPlistAdditionalKeys(),
getInfoPlistOverrideKeys(),
PlistProcessStep.OutputFormat.BINARY));
if (hasBinary) {
appendCopyBinarySteps(stepsBuilder, context);
appendCopyDsymStep(stepsBuilder, buildableContext, context);
}
ImmutableList.Builder<Path> codeSignOnCopyPathsBuilder = ImmutableList.builder();
AppleResourceProcessing.addStepsToCopyResources(
context,
stepsBuilder,
codeSignOnCopyPathsBuilder,
resources,
verifyResources,
bundleRoot,
destinations,
getProjectFilesystem(),
ibtoolFlags,
isLegacyWatchApp(),
platform,
LOG,
ibtool,
ibtoolModuleFlag,
getBuildTarget(),
Optional.of(binaryName));
addStepsToCopyExtensionBundlesDependencies(context, stepsBuilder, codeSignOnCopyPathsBuilder);
AppleResourceProcessing.addVariantFileProcessingSteps(
resources,
context,
bundleRoot,
destinations,
stepsBuilder,
getProjectFilesystem(),
ibtoolFlags,
isLegacyWatchApp(),
platform,
LOG,
ibtool,
ibtoolModuleFlag,
getBuildTarget(),
Optional.of(binaryName));
AppleResourceProcessing.addFrameworksProcessingSteps(
frameworks,
bundleRoot,
destinations,
stepsBuilder,
context,
getProjectFilesystem(),
codeSignOnCopyPathsBuilder);
if (needCodeSign()) {
Optional<Path> signingEntitlementsTempPath = Optional.empty();
Supplier<CodeSignIdentity> codeSignIdentitySupplier;
if (adHocCodeSignIsSufficient()) {
if (useEntitlementsWhenAdhocCodeSigning) {
signingEntitlementsTempPath = prepareEntitlementsPlistFile(context, stepsBuilder);
}
CodeSignIdentity identity =
codesignIdentitySubjectName
.map(id -> CodeSignIdentity.ofAdhocSignedWithSubjectCommonName(id))
.orElse(CodeSignIdentity.AD_HOC);
codeSignIdentitySupplier = () -> identity;
} else {
// Copy the .mobileprovision file if the platform requires it, and sign the executable.
Optional<Path> entitlementsPlist = prepareEntitlementsPlistFile(context, stepsBuilder);
signingEntitlementsTempPath =
Optional.of(
BuildTargetPaths.getScratchPath(
getProjectFilesystem(), getBuildTarget(), "%s.xcent"));
Path dryRunResultPath = bundleRoot.resolve(PP_DRY_RUN_RESULT_FILE);
ProvisioningProfileCopyStep provisioningProfileCopyStep =
new ProvisioningProfileCopyStep(
getProjectFilesystem(),
infoPlistOutputPath,
platform,
Optional.empty(), // Provisioning profile UUID -- find automatically.
entitlementsPlist,
provisioningProfileStore,
resourcesDestinationPath.resolve("embedded.mobileprovision"),
dryRunCodeSigning
? bundleRoot.resolve(CODE_SIGN_DRY_RUN_ENTITLEMENTS_FILE)
: signingEntitlementsTempPath.get(),
codeSignIdentitiesSupplier,
dryRunCodeSigning ? Optional.of(dryRunResultPath) : Optional.empty());
stepsBuilder.add(provisioningProfileCopyStep);
codeSignIdentitySupplier =
() -> {
// Using getUnchecked here because the previous step should already throw if exception
// occurred, and this supplier would never be evaluated.
Optional<ProvisioningProfileMetadata> selectedProfile =
Futures.getUnchecked(
provisioningProfileCopyStep.getSelectedProvisioningProfileFuture());
if (!selectedProfile.isPresent()) {
// This should only happen in dry-run codesign mode (since otherwise an exception
// would have been thrown already.) Still, we need to return *something*.
Preconditions.checkState(dryRunCodeSigning);
return CodeSignIdentity.AD_HOC;
}
ImmutableSet<HashCode> fingerprints =
selectedProfile.get().getDeveloperCertificateFingerprints();
if (fingerprints.isEmpty()) {
// No constraints, pick an arbitrary identity.
// If no identities are available, use an ad-hoc identity.
return Iterables.getFirst(
codeSignIdentitiesSupplier.get(), CodeSignIdentity.AD_HOC);
}
for (CodeSignIdentity identity : codeSignIdentitiesSupplier.get()) {
if (identity.getFingerprint().isPresent()
&& fingerprints.contains(identity.getFingerprint().get())) {
return identity;
}
}
throw new HumanReadableException(
"No code sign identity available for provisioning profile: %s\n"
+ "Profile requires an identity with one of the following SHA1 fingerprints "
+ "available in your keychain: \n %s",
selectedProfile.get().getProfilePath(), Joiner.on("\n ").join(fingerprints));
};
}
AppleResourceProcessing.addSwiftStdlibStepIfNeeded(
context.getSourcePathResolver(),
bundleRoot.resolve(destinations.getFrameworksPath()),
bundleRoot,
dryRunCodeSigning ? Optional.empty() : Optional.of(codeSignIdentitySupplier),
stepsBuilder,
false,
extension,
copySwiftStdlibToFrameworks,
useLipoThin,
swiftStdlibTool,
getProjectFilesystem(),
getBuildTarget(),
sdkPath,
lipo,
bundleBinaryPath,
destinations,
isAppClip.orElse(false));
for (BuildRule extraBinary : extraBinaries) {
Path outputPath = getBundleBinaryPathForBuildRule(extraBinary);
codeSignOnCopyPathsBuilder.add(outputPath);
}
for (Path codeSignOnCopyPath : codeSignOnCopyPathsBuilder.build()) {
stepsBuilder.add(
new CodeSignStep(
getProjectFilesystem(),
context.getSourcePathResolver(),
codeSignOnCopyPath,
Optional.empty(),
codeSignIdentitySupplier,
codesign,
codesignAllocatePath,
dryRunCodeSigning
? Optional.of(codeSignOnCopyPath.resolve(CODE_SIGN_DRY_RUN_ARGS_FILE))
: Optional.empty(),
codesignFlags,
codesignTimeout));
}
stepsBuilder.add(
new CodeSignStep(
getProjectFilesystem(),
context.getSourcePathResolver(),
bundleRoot,
signingEntitlementsTempPath,
codeSignIdentitySupplier,
codesign,
codesignAllocatePath,
dryRunCodeSigning
? Optional.of(bundleRoot.resolve(CODE_SIGN_DRY_RUN_ARGS_FILE))
: Optional.empty(),
codesignFlags,
codesignTimeout));
} else {
AppleResourceProcessing.addSwiftStdlibStepIfNeeded(
context.getSourcePathResolver(),
bundleRoot.resolve(destinations.getFrameworksPath()),
bundleRoot,
Optional.empty(),
stepsBuilder,
false,
extension,
copySwiftStdlibToFrameworks,
useLipoThin,
swiftStdlibTool,
getProjectFilesystem(),
getBuildTarget(),
sdkPath,
lipo,
bundleBinaryPath,
destinations,
isAppClip.orElse(false));
}
// Ensure the bundle directory is archived so we can fetch it later.
buildableContext.recordArtifact(
context.getSourcePathResolver().getRelativePath(getSourcePathToOutput()));
return stepsBuilder.build();
}