use of com.google.common.collect.ImmutableMap in project buck by facebook.
the class AppleSdkDiscovery method discoverAppleSdkPaths.
/**
* Given a path to an Xcode developer directory and a map of
* (xctoolchain ID: path) pairs as returned by
* {@link AppleToolchainDiscovery}, walks through the platforms
* and builds a map of ({@link AppleSdk}: {@link AppleSdkPaths})
* objects describing the paths to the SDKs inside.
*
* The {@link AppleSdk#getName()} strings match the ones displayed by {@code xcodebuild -showsdks}
* and look like {@code macosx10.9}, {@code iphoneos8.0}, {@code iphonesimulator8.0},
* etc.
*/
public static ImmutableMap<AppleSdk, AppleSdkPaths> discoverAppleSdkPaths(Optional<Path> developerDir, ImmutableList<Path> extraDirs, ImmutableMap<String, AppleToolchain> xcodeToolchains, AppleConfig appleConfig) throws IOException {
Optional<AppleToolchain> defaultToolchain = Optional.ofNullable(xcodeToolchains.get(DEFAULT_TOOLCHAIN_ID));
ImmutableMap.Builder<AppleSdk, AppleSdkPaths> appleSdkPathsBuilder = ImmutableMap.builder();
HashSet<Path> platformPaths = new HashSet<Path>(extraDirs);
if (developerDir.isPresent()) {
Path platformsDir = developerDir.get().resolve("Platforms");
LOG.debug("Searching for Xcode platforms under %s", platformsDir);
platformPaths.add(platformsDir);
}
// We need to find the most recent SDK for each platform so we can
// make the fall-back SDKs with no version number in their name
// ("macosx", "iphonesimulator", "iphoneos").
//
// To do this, we store a map of (platform: [sdk1, sdk2, ...])
// pairs where the SDKs for each platform are ordered by version.
TreeMultimap<ApplePlatform, AppleSdk> orderedSdksForPlatform = TreeMultimap.create(Ordering.natural(), APPLE_SDK_VERSION_ORDERING);
for (Path platforms : platformPaths) {
if (!Files.exists(platforms)) {
LOG.debug("Skipping platform search path %s that does not exist", platforms);
continue;
}
LOG.debug("Searching for Xcode SDKs in %s", platforms);
try (DirectoryStream<Path> platformStream = Files.newDirectoryStream(platforms, "*.platform")) {
for (Path platformDir : platformStream) {
Path developerSdksPath = platformDir.resolve("Developer/SDKs");
try (DirectoryStream<Path> sdkStream = Files.newDirectoryStream(developerSdksPath, "*.sdk")) {
Set<Path> scannedSdkDirs = new HashSet<>();
for (Path sdkDir : sdkStream) {
LOG.debug("Fetching SDK name for %s", sdkDir);
sdkDir = sdkDir.toRealPath();
if (scannedSdkDirs.contains(sdkDir)) {
LOG.debug("Skipping already scanned SDK directory %s", sdkDir);
continue;
}
AppleSdk.Builder sdkBuilder = AppleSdk.builder();
if (buildSdkFromPath(sdkDir, sdkBuilder, xcodeToolchains, defaultToolchain, appleConfig)) {
AppleSdk sdk = sdkBuilder.build();
LOG.debug("Found SDK %s", sdk);
AppleSdkPaths.Builder xcodePathsBuilder = AppleSdkPaths.builder();
for (AppleToolchain toolchain : sdk.getToolchains()) {
xcodePathsBuilder.addToolchainPaths(toolchain.getPath());
}
AppleSdkPaths xcodePaths = xcodePathsBuilder.setDeveloperPath(developerDir).setPlatformPath(platformDir).setSdkPath(sdkDir).build();
appleSdkPathsBuilder.put(sdk, xcodePaths);
orderedSdksForPlatform.put(sdk.getApplePlatform(), sdk);
}
scannedSdkDirs.add(sdkDir);
}
} catch (NoSuchFileException e) {
LOG.warn(e, "Couldn't discover SDKs at path %s, ignoring platform %s", developerSdksPath, platformDir);
}
}
}
}
// Get a snapshot of what's in appleSdkPathsBuilder, then for each
// ApplePlatform, add to appleSdkPathsBuilder the most recent
// SDK with an unversioned name.
ImmutableMap<AppleSdk, AppleSdkPaths> discoveredSdkPaths = appleSdkPathsBuilder.build();
for (ApplePlatform platform : orderedSdksForPlatform.keySet()) {
Set<AppleSdk> platformSdks = orderedSdksForPlatform.get(platform);
boolean shouldCreateUnversionedSdk = true;
for (AppleSdk sdk : platformSdks) {
shouldCreateUnversionedSdk &= !sdk.getName().equals(platform.getName());
}
if (shouldCreateUnversionedSdk) {
AppleSdk mostRecentSdkForPlatform = orderedSdksForPlatform.get(platform).last();
appleSdkPathsBuilder.put(mostRecentSdkForPlatform.withName(platform.getName()), discoveredSdkPaths.get(mostRecentSdkForPlatform));
}
}
// the unversioned aliases added just above.
return appleSdkPathsBuilder.build();
}
use of com.google.common.collect.ImmutableMap in project buck by facebook.
the class ProvisioningProfileCopyStep method execute.
@Override
public StepExecutionResult execute(ExecutionContext context) throws InterruptedException {
final String bundleID;
try {
bundleID = AppleInfoPlistParsing.getBundleIdFromPlistStream(filesystem.getInputStreamForRelativePath(infoPlist)).get();
} catch (IOException e) {
throw new HumanReadableException("Unable to get bundle ID from info.plist: " + infoPlist);
}
final Optional<ImmutableMap<String, NSObject>> entitlements;
final String prefix;
if (entitlementsPlist.isPresent()) {
try {
NSDictionary entitlementsPlistDict = (NSDictionary) PropertyListParser.parse(entitlementsPlist.get().toFile());
entitlements = Optional.of(ImmutableMap.copyOf(entitlementsPlistDict.getHashMap()));
prefix = ProvisioningProfileMetadata.prefixFromEntitlements(entitlements.get()).orElse("*");
} catch (IOException e) {
throw new HumanReadableException("Unable to find entitlement .plist: " + entitlementsPlist.get());
} catch (Exception e) {
throw new HumanReadableException("Malformed entitlement .plist: " + entitlementsPlist.get());
}
} else {
entitlements = ProvisioningProfileStore.MATCH_ANY_ENTITLEMENT;
prefix = "*";
}
final Optional<ImmutableList<CodeSignIdentity>> identities;
if (!codeSignIdentityStore.getIdentities().isEmpty()) {
identities = Optional.of(codeSignIdentityStore.getIdentities());
} else {
identities = ProvisioningProfileStore.MATCH_ANY_IDENTITY;
}
Optional<ProvisioningProfileMetadata> bestProfile = provisioningProfileUUID.isPresent() ? provisioningProfileStore.getProvisioningProfileByUUID(provisioningProfileUUID.get()) : provisioningProfileStore.getBestProvisioningProfile(bundleID, platform, entitlements, identities);
if (dryRunResultsPath.isPresent()) {
try {
NSDictionary dryRunResult = new NSDictionary();
dryRunResult.put(BUNDLE_ID, bundleID);
dryRunResult.put(ENTITLEMENTS, entitlements.orElse(ImmutableMap.of()));
if (bestProfile.isPresent()) {
dryRunResult.put(PROFILE_UUID, bestProfile.get().getUUID());
dryRunResult.put(PROFILE_FILENAME, bestProfile.get().getProfilePath().getFileName().toString());
dryRunResult.put(TEAM_IDENTIFIER, bestProfile.get().getEntitlements().get("com.apple.developer.team-identifier"));
}
filesystem.writeContentsToPath(dryRunResult.toXMLPropertyList(), dryRunResultsPath.get());
} catch (IOException e) {
context.logError(e, "Failed when trying to write dry run results: %s", getDescription(context));
return StepExecutionResult.ERROR;
}
}
selectedProvisioningProfileFuture.set(bestProfile);
if (!bestProfile.isPresent()) {
String message = "No valid non-expired provisioning profiles match for " + prefix + "." + bundleID;
if (dryRunResultsPath.isPresent()) {
LOG.warn(message);
return StepExecutionResult.SUCCESS;
} else {
throw new HumanReadableException(message);
}
}
Path provisioningProfileSource = bestProfile.get().getProfilePath();
// Copy the actual .mobileprovision.
try {
filesystem.copy(provisioningProfileSource, provisioningProfileDestination, CopySourceMode.FILE);
} catch (IOException e) {
context.logError(e, "Failed when trying to copy: %s", getDescription(context));
return StepExecutionResult.ERROR;
}
// Merge the entitlements with the profile, and write out.
if (entitlementsPlist.isPresent()) {
return (new PlistProcessStep(filesystem, entitlementsPlist.get(), Optional.empty(), signingEntitlementsTempPath, bestProfile.get().getMergeableEntitlements(), ImmutableMap.of(), PlistProcessStep.OutputFormat.XML)).execute(context);
} else {
// No entitlements.plist explicitly specified; write out the minimal entitlements needed.
String appID = bestProfile.get().getAppID().getFirst() + "." + bundleID;
NSDictionary entitlementsPlist = new NSDictionary();
entitlementsPlist.putAll(bestProfile.get().getMergeableEntitlements());
entitlementsPlist.put(APPLICATION_IDENTIFIER, appID);
entitlementsPlist.put(KEYCHAIN_ACCESS_GROUPS, new String[] { appID });
return (new WriteFileStep(filesystem, entitlementsPlist.toXMLPropertyList(), signingEntitlementsTempPath, /* executable */
false)).execute(context);
}
}
use of com.google.common.collect.ImmutableMap in project buck by facebook.
the class SceneKitAssets method getBuildSteps.
@Override
public ImmutableList<Step> getBuildSteps(BuildContext context, BuildableContext buildableContext) {
ImmutableList.Builder<Step> stepsBuilder = ImmutableList.builder();
stepsBuilder.add(new MakeCleanDirectoryStep(getProjectFilesystem(), outputDir));
for (SourcePath inputPath : sceneKitAssetsPaths) {
final Path absoluteInputPath = context.getSourcePathResolver().getAbsolutePath(inputPath);
if (copySceneKitAssets.isPresent()) {
stepsBuilder.add(new ShellStep(getProjectFilesystem().getRootPath()) {
@Override
protected ImmutableList<String> getShellCommandInternal(ExecutionContext executionContext) {
ImmutableList.Builder<String> commandBuilder = ImmutableList.builder();
commandBuilder.addAll(copySceneKitAssets.get().getCommandPrefix(context.getSourcePathResolver()));
commandBuilder.add(absoluteInputPath.toString(), "-o", getProjectFilesystem().resolve(outputDir).resolve(absoluteInputPath.getFileName()).toString(), "--target-platform=" + sdkName, "--target-version=" + minOSVersion);
return commandBuilder.build();
}
@Override
public ImmutableMap<String, String> getEnvironmentVariables(ExecutionContext executionContext) {
return copySceneKitAssets.get().getEnvironment(context.getSourcePathResolver());
}
@Override
public String getShortName() {
return "copy-scenekit-assets";
}
});
} else {
stepsBuilder.add(CopyStep.forDirectory(getProjectFilesystem(), absoluteInputPath, outputDir, CopyStep.DirectoryMode.CONTENTS_ONLY));
}
}
buildableContext.recordArtifact(context.getSourcePathResolver().getRelativePath(getSourcePathToOutput()));
return stepsBuilder.build();
}
use of com.google.common.collect.ImmutableMap in project buck by facebook.
the class ProjectGenerator method generateBuildWithBuckTarget.
private void generateBuildWithBuckTarget(TargetNode<?, ?> targetNode) {
final BuildTarget buildTarget = targetNode.getBuildTarget();
String buckTargetProductName = getXcodeTargetName(buildTarget) + BUILD_WITH_BUCK_POSTFIX;
PBXAggregateTarget buildWithBuckTarget = new PBXAggregateTarget(buckTargetProductName);
buildWithBuckTarget.setProductName(buckTargetProductName);
PBXShellScriptBuildPhase buildShellScriptBuildPhase = new PBXShellScriptBuildPhase();
buildShellScriptBuildPhase.setShellScript(getBuildWithBuckShellScript(targetNode));
buildWithBuckTarget.getBuildPhases().add(buildShellScriptBuildPhase);
// Only add a shell script for fixing UUIDs if it is an AppleBundle
if (targetNode.getDescription() instanceof AppleBundleDescription) {
PBXShellScriptBuildPhase codesignPhase = new PBXShellScriptBuildPhase();
codesignPhase.setShellScript(getCodesignShellScript(targetNode));
buildWithBuckTarget.getBuildPhases().add(codesignPhase);
}
TargetNode<CxxLibraryDescription.Arg, ?> node = getAppleNativeNode(targetGraph, targetNode).get();
ImmutableMap<String, ImmutableMap<String, String>> configs = getXcodeBuildConfigurationsForTargetNode(node, ImmutableMap.of()).get();
XCConfigurationList configurationList = new XCConfigurationList();
PBXGroup group = project.getMainGroup().getOrCreateDescendantGroupByPath(StreamSupport.stream(buildTarget.getBasePath().spliterator(), false).map(Object::toString).collect(MoreCollectors.toImmutableList())).getOrCreateChildGroupByName(getXcodeTargetName(buildTarget));
for (String configurationName : configs.keySet()) {
XCBuildConfiguration configuration = configurationList.getBuildConfigurationsByName().getUnchecked(configurationName);
configuration.setBaseConfigurationReference(getConfigurationFileReference(group, getConfigurationNameToXcconfigPath(buildTarget).apply(configurationName)));
NSDictionary inlineSettings = new NSDictionary();
inlineSettings.put("HEADER_SEARCH_PATHS", "");
inlineSettings.put("LIBRARY_SEARCH_PATHS", "");
inlineSettings.put("FRAMEWORK_SEARCH_PATHS", "");
configuration.setBuildSettings(inlineSettings);
}
buildWithBuckTarget.setBuildConfigurationList(configurationList);
project.getTargets().add(buildWithBuckTarget);
targetNodeToGeneratedProjectTargetBuilder.put(targetNode, buildWithBuckTarget);
}
use of com.google.common.collect.ImmutableMap in project buck by facebook.
the class ProjectGenerator method generateHalideLibraryTarget.
private Optional<PBXTarget> generateHalideLibraryTarget(PBXProject project, TargetNode<HalideLibraryDescription.Arg, ?> targetNode) throws IOException {
final BuildTarget buildTarget = targetNode.getBuildTarget();
boolean isFocusedOnTarget = buildTarget.matchesUnflavoredTargets(focusModules);
String productName = getProductNameForBuildTarget(buildTarget);
Path outputPath = getHalideOutputPath(targetNode.getFilesystem(), buildTarget);
Path scriptPath = halideBuckConfig.getXcodeCompileScriptPath();
Optional<String> script = projectFilesystem.readFileIfItExists(scriptPath);
PBXShellScriptBuildPhase scriptPhase = new PBXShellScriptBuildPhase();
scriptPhase.setShellScript(script.orElse(""));
NewNativeTargetProjectMutator mutator = new NewNativeTargetProjectMutator(pathRelativizer, this::resolveSourcePath);
mutator.setTargetName(getXcodeTargetName(buildTarget)).setProduct(ProductType.STATIC_LIBRARY, productName, outputPath).setPreBuildRunScriptPhases(ImmutableList.of(scriptPhase));
NewNativeTargetProjectMutator.Result targetBuilderResult;
targetBuilderResult = mutator.buildTargetAndAddToProject(project, isFocusedOnTarget);
BuildTarget compilerTarget = HalideLibraryDescription.createHalideCompilerBuildTarget(buildTarget);
Path compilerPath = BuildTargets.getGenPath(projectFilesystem, compilerTarget, "%s");
ImmutableMap<String, String> appendedConfig = ImmutableMap.of();
ImmutableMap<String, String> extraSettings = ImmutableMap.of();
ImmutableMap.Builder<String, String> defaultSettingsBuilder = ImmutableMap.builder();
defaultSettingsBuilder.put("REPO_ROOT", projectFilesystem.getRootPath().toAbsolutePath().normalize().toString());
defaultSettingsBuilder.put("HALIDE_COMPILER_PATH", compilerPath.toString());
// pass the source list to the xcode script
String halideCompilerSrcs;
Iterable<Path> compilerSrcFiles = Iterables.transform(targetNode.getConstructorArg().srcs, input -> resolveSourcePath(input.getSourcePath()));
halideCompilerSrcs = Joiner.on(" ").join(compilerSrcFiles);
defaultSettingsBuilder.put("HALIDE_COMPILER_SRCS", halideCompilerSrcs);
String halideCompilerFlags;
halideCompilerFlags = Joiner.on(" ").join(targetNode.getConstructorArg().compilerFlags);
defaultSettingsBuilder.put("HALIDE_COMPILER_FLAGS", halideCompilerFlags);
defaultSettingsBuilder.put("HALIDE_OUTPUT_PATH", outputPath.toString());
defaultSettingsBuilder.put("HALIDE_FUNC_NAME", buildTarget.getShortName());
defaultSettingsBuilder.put(PRODUCT_NAME, productName);
Optional<ImmutableSortedMap<String, ImmutableMap<String, String>>> configs = getXcodeBuildConfigurationsForTargetNode(targetNode, appendedConfig);
PBXNativeTarget target = targetBuilderResult.target;
setTargetBuildConfigurations(getConfigurationNameToXcconfigPath(buildTarget), target, project.getMainGroup(), configs.get(), extraSettings, defaultSettingsBuilder.build(), appendedConfig);
return Optional.of(target);
}
Aggregations