use of com.facebook.buck.apple.AppleLibraryDescription in project buck by facebook.
the class ProjectGenerator method getDestinationSpec.
private Optional<CopyFilePhaseDestinationSpec> getDestinationSpec(TargetNode<?, ?> targetNode) {
if (targetNode.getDescription() instanceof AppleBundleDescription) {
AppleBundleDescription.Arg arg = (AppleBundleDescription.Arg) targetNode.getConstructorArg();
AppleBundleExtension extension = arg.extension.isLeft() ? arg.extension.getLeft() : AppleBundleExtension.BUNDLE;
switch(extension) {
case FRAMEWORK:
return Optional.of(CopyFilePhaseDestinationSpec.of(PBXCopyFilesBuildPhase.Destination.FRAMEWORKS));
case APPEX:
case PLUGIN:
return Optional.of(CopyFilePhaseDestinationSpec.of(PBXCopyFilesBuildPhase.Destination.PLUGINS));
case APP:
if (isWatchApplicationNode(targetNode)) {
return Optional.of(CopyFilePhaseDestinationSpec.builder().setDestination(PBXCopyFilesBuildPhase.Destination.PRODUCTS).setPath("$(CONTENTS_FOLDER_PATH)/Watch").build());
} else {
return Optional.of(CopyFilePhaseDestinationSpec.of(PBXCopyFilesBuildPhase.Destination.EXECUTABLES));
}
case BUNDLE:
return Optional.of(CopyFilePhaseDestinationSpec.of(PBXCopyFilesBuildPhase.Destination.PLUGINS));
//$CASES-OMITTED$
default:
return Optional.of(CopyFilePhaseDestinationSpec.of(PBXCopyFilesBuildPhase.Destination.PRODUCTS));
}
} else if (targetNode.getDescription() instanceof AppleLibraryDescription || targetNode.getDescription() instanceof CxxLibraryDescription) {
if (targetNode.getBuildTarget().getFlavors().contains(CxxDescriptionEnhancer.SHARED_FLAVOR)) {
return Optional.of(CopyFilePhaseDestinationSpec.of(PBXCopyFilesBuildPhase.Destination.FRAMEWORKS));
} else {
return Optional.empty();
}
} else if (targetNode.getDescription() instanceof AppleBinaryDescription) {
return Optional.of(CopyFilePhaseDestinationSpec.of(PBXCopyFilesBuildPhase.Destination.EXECUTABLES));
} else if (targetNode.getDescription() instanceof HalideLibraryDescription) {
return Optional.empty();
} else if (targetNode.getDescription() instanceof CoreDataModelDescription || targetNode.getDescription() instanceof SceneKitAssetsDescription) {
return Optional.of(CopyFilePhaseDestinationSpec.of(PBXCopyFilesBuildPhase.Destination.RESOURCES));
} else {
throw new RuntimeException("Unexpected type: " + targetNode.getDescription().getClass());
}
}
use of com.facebook.buck.apple.AppleLibraryDescription in project buck by facebook.
the class ProjectGenerator method generateBinaryTarget.
private PBXNativeTarget generateBinaryTarget(PBXProject project, Optional<? extends TargetNode<? extends HasAppleBundleFields, ?>> bundle, TargetNode<? extends CxxLibraryDescription.Arg, ?> targetNode, ProductType productType, String productOutputFormat, Optional<Path> infoPlistOptional, boolean includeFrameworks, ImmutableSet<AppleResourceDescription.Arg> recursiveResources, ImmutableSet<AppleResourceDescription.Arg> directResources, ImmutableSet<AppleAssetCatalogDescription.Arg> recursiveAssetCatalogs, ImmutableSet<AppleAssetCatalogDescription.Arg> directAssetCatalogs, ImmutableSet<AppleWrapperResourceArg> wrapperResources, Optional<Iterable<PBXBuildPhase>> copyFilesPhases, Optional<TargetNode<AppleBundleDescription.Arg, ?>> bundleLoaderNode) throws IOException {
LOG.debug("Generating binary target for node %s", targetNode);
TargetNode<?, ?> buildTargetNode = bundle.isPresent() ? bundle.get() : targetNode;
final BuildTarget buildTarget = buildTargetNode.getBuildTarget();
String buildTargetName = getProductNameForBuildTarget(buildTarget);
CxxLibraryDescription.Arg arg = targetNode.getConstructorArg();
NewNativeTargetProjectMutator mutator = new NewNativeTargetProjectMutator(pathRelativizer, this::resolveSourcePath);
ImmutableSet<SourcePath> exportedHeaders = ImmutableSet.copyOf(getHeaderSourcePaths(arg.exportedHeaders));
ImmutableSet<SourcePath> headers = ImmutableSet.copyOf(getHeaderSourcePaths(arg.headers));
ImmutableMap<CxxSource.Type, ImmutableList<String>> langPreprocessorFlags = targetNode.getConstructorArg().langPreprocessorFlags;
mutator.setTargetName(getXcodeTargetName(buildTarget)).setProduct(productType, buildTargetName, Paths.get(String.format(productOutputFormat, buildTargetName)));
boolean isFocusedOnTarget = buildTarget.matchesUnflavoredTargets(focusModules);
Optional<TargetNode<AppleNativeTargetDescriptionArg, ?>> appleTargetNode = targetNode.castArg(AppleNativeTargetDescriptionArg.class);
if (!shouldGenerateHeaderSymlinkTreesOnly()) {
if (isFocusedOnTarget) {
mutator.setLangPreprocessorFlags(langPreprocessorFlags).setPublicHeaders(exportedHeaders).setPrefixHeader(arg.prefixHeader).setSourcesWithFlags(ImmutableSet.copyOf(arg.srcs)).setPrivateHeaders(headers).setRecursiveResources(recursiveResources).setDirectResources(directResources).setWrapperResources(wrapperResources);
}
if (bundle.isPresent() && isFocusedOnTarget) {
HasAppleBundleFields bundleArg = bundle.get().getConstructorArg();
mutator.setInfoPlist(Optional.of(bundleArg.getInfoPlist()));
}
mutator.setBridgingHeader(arg.bridgingHeader);
if (appleTargetNode.isPresent() && isFocusedOnTarget) {
AppleNativeTargetDescriptionArg appleArg = appleTargetNode.get().getConstructorArg();
mutator = mutator.setExtraXcodeSources(ImmutableSet.copyOf(appleArg.extraXcodeSources));
}
if (options.contains(Option.CREATE_DIRECTORY_STRUCTURE) && isFocusedOnTarget) {
mutator.setTargetGroupPath(StreamSupport.stream(buildTarget.getBasePath().spliterator(), false).map(Object::toString).collect(MoreCollectors.toImmutableList()));
}
if (!recursiveAssetCatalogs.isEmpty() && isFocusedOnTarget) {
mutator.setRecursiveAssetCatalogs(recursiveAssetCatalogs);
}
if (!directAssetCatalogs.isEmpty() && isFocusedOnTarget) {
mutator.setDirectAssetCatalogs(directAssetCatalogs);
}
if (includeFrameworks && isFocusedOnTarget) {
ImmutableSet.Builder<FrameworkPath> frameworksBuilder = ImmutableSet.builder();
frameworksBuilder.addAll(targetNode.getConstructorArg().frameworks);
frameworksBuilder.addAll(targetNode.getConstructorArg().libraries);
frameworksBuilder.addAll(collectRecursiveFrameworkDependencies(ImmutableList.of(targetNode)));
mutator.setFrameworks(frameworksBuilder.build());
mutator.setArchives(collectRecursiveLibraryDependencies(ImmutableList.of(targetNode)));
}
// TODO(Task #3772930): Go through all dependencies of the rule
// and add any shell script rules here
ImmutableList.Builder<TargetNode<?, ?>> preScriptPhases = ImmutableList.builder();
ImmutableList.Builder<TargetNode<?, ?>> postScriptPhases = ImmutableList.builder();
if (bundle.isPresent() && targetNode != bundle.get() && isFocusedOnTarget) {
collectBuildScriptDependencies(targetGraph.getAll(bundle.get().getDeclaredDeps()), preScriptPhases, postScriptPhases);
}
collectBuildScriptDependencies(targetGraph.getAll(targetNode.getDeclaredDeps()), preScriptPhases, postScriptPhases);
if (isFocusedOnTarget) {
mutator.setPreBuildRunScriptPhasesFromTargetNodes(preScriptPhases.build());
if (copyFilesPhases.isPresent()) {
mutator.setCopyFilesPhases(copyFilesPhases.get());
}
mutator.setPostBuildRunScriptPhasesFromTargetNodes(postScriptPhases.build());
}
}
NewNativeTargetProjectMutator.Result targetBuilderResult = mutator.buildTargetAndAddToProject(project, isFocusedOnTarget);
PBXNativeTarget target = targetBuilderResult.target;
Optional<PBXGroup> targetGroup = targetBuilderResult.targetGroup;
ImmutableMap.Builder<String, String> extraSettingsBuilder = ImmutableMap.builder();
ImmutableMap.Builder<String, String> defaultSettingsBuilder = ImmutableMap.builder();
if (!shouldGenerateHeaderSymlinkTreesOnly()) {
if (isFocusedOnTarget) {
SourceTreePath buckFilePath = new SourceTreePath(PBXReference.SourceTree.SOURCE_ROOT, pathRelativizer.outputPathToBuildTargetPath(buildTarget).resolve(buildFileName), Optional.empty());
PBXFileReference buckReference = targetGroup.get().getOrCreateFileReferenceBySourceTreePath(buckFilePath);
buckReference.setExplicitFileType(Optional.of("text.script.python"));
}
// -- configurations
extraSettingsBuilder.put("TARGET_NAME", buildTargetName).put("SRCROOT", pathRelativizer.outputPathToBuildTargetPath(buildTarget).toString());
if (productType == ProductType.UI_TEST && isFocusedOnTarget) {
if (bundleLoaderNode.isPresent()) {
BuildTarget testTarget = bundleLoaderNode.get().getBuildTarget();
extraSettingsBuilder.put("TEST_TARGET_NAME", getXcodeTargetName(testTarget));
} else {
throw new HumanReadableException("The test rule '%s' is configured with 'is_ui_test' but has no test_host_app", buildTargetName);
}
} else if (bundleLoaderNode.isPresent() && isFocusedOnTarget) {
TargetNode<AppleBundleDescription.Arg, ?> bundleLoader = bundleLoaderNode.get();
String bundleLoaderProductName = getProductNameForBuildTarget(bundleLoader.getBuildTarget());
String bundleLoaderBundleName = bundleLoaderProductName + "." + getExtensionString(bundleLoader.getConstructorArg().getExtension());
// NOTE(grp): This is a hack. We need to support both deep (OS X) and flat (iOS)
// style bundles for the bundle loader, but at this point we don't know what platform
// the bundle loader (or current target) is going to be built for. However, we can be
// sure that it's the same as the target (presumably a test) we're building right now.
//
// Using that knowledge, we can do build setting tricks to defer choosing the bundle
// loader path until Xcode build time, when the platform is known. There's no build
// setting that conclusively says whether the current platform uses deep bundles:
// that would be too easy. But in the cases we care about (unit test bundles), the
// current bundle will have a style matching the style of the bundle loader app, so
// we can take advantage of that to do the determination.
//
// Unfortunately, the build setting for the bundle structure (CONTENTS_FOLDER_PATH)
// includes the WRAPPER_NAME, so we can't just interpolate that in. Instead, we have
// to use another trick with build setting operations and evaluation. By using the
// $(:file) operation, we can extract the last component of the contents path: either
// "Contents" or the current bundle name. Then, we can interpolate with that expected
// result in the build setting name to conditionally choose a different loader path.
// The conditional that decides which path is used. This is a complex Xcode build setting
// expression that expands to one of two values, depending on the last path component of
// the CONTENTS_FOLDER_PATH variable. As described above, this will be either "Contents"
// for deep bundles or the bundle file name itself for flat bundles. Finally, to santiize
// the potentially invalid build setting names from the bundle file name, it converts that
// to an identifier. We rely on BUNDLE_LOADER_BUNDLE_STYLE_CONDITIONAL_<bundle file name>
// being undefined (and thus expanding to nothing) for the path resolution to work.
//
// The operations on the CONTENTS_FOLDER_PATH are documented here:
// http://codeworkshop.net/posts/xcode-build-setting-transformations
String bundleLoaderOutputPathConditional = "$(BUNDLE_LOADER_BUNDLE_STYLE_CONDITIONAL_$(CONTENTS_FOLDER_PATH:file:identifier))";
// If the $(CONTENTS_FOLDER_PATH:file:identifier) expands to this, we add the deep bundle
// path into the bundle loader. See above for the case when it will expand to this value.
String bundleLoaderOutputPathDeepSetting = "BUNDLE_LOADER_BUNDLE_STYLE_CONDITIONAL_Contents";
String bundleLoaderOutputPathDeepValue = "Contents/MacOS/";
String bundleLoaderOutputPathValue = Joiner.on('/').join(getTargetOutputPath(bundleLoader), bundleLoaderBundleName, bundleLoaderOutputPathConditional, bundleLoaderProductName);
extraSettingsBuilder.put(bundleLoaderOutputPathDeepSetting, bundleLoaderOutputPathDeepValue).put("BUNDLE_LOADER", bundleLoaderOutputPathValue).put("TEST_HOST", "$(BUNDLE_LOADER)");
}
if (infoPlistOptional.isPresent()) {
Path infoPlistPath = pathRelativizer.outputDirToRootRelative(infoPlistOptional.get());
extraSettingsBuilder.put("INFOPLIST_FILE", infoPlistPath.toString());
}
if (arg.bridgingHeader.isPresent()) {
Path bridgingHeaderPath = pathRelativizer.outputDirToRootRelative(resolveSourcePath(arg.bridgingHeader.get()));
extraSettingsBuilder.put("SWIFT_OBJC_BRIDGING_HEADER", Joiner.on('/').join("$(SRCROOT)", bridgingHeaderPath.toString()));
}
Optional<String> swiftVersion = swiftBuckConfig.getVersion();
if (swiftVersion.isPresent()) {
extraSettingsBuilder.put("SWIFT_VERSION", swiftVersion.get());
}
Optional<SourcePath> prefixHeaderOptional = targetNode.getConstructorArg().prefixHeader;
if (prefixHeaderOptional.isPresent()) {
Path prefixHeaderRelative = resolveSourcePath(prefixHeaderOptional.get());
Path prefixHeaderPath = pathRelativizer.outputDirToRootRelative(prefixHeaderRelative);
extraSettingsBuilder.put("GCC_PREFIX_HEADER", prefixHeaderPath.toString());
extraSettingsBuilder.put("GCC_PRECOMPILE_PREFIX_HEADER", "YES");
}
extraSettingsBuilder.put("USE_HEADERMAP", "NO");
defaultSettingsBuilder.put("REPO_ROOT", projectFilesystem.getRootPath().toAbsolutePath().normalize().toString());
defaultSettingsBuilder.put(PRODUCT_NAME, getProductName(buildTargetNode, buildTarget));
if (bundle.isPresent()) {
defaultSettingsBuilder.put("WRAPPER_EXTENSION", getExtensionString(bundle.get().getConstructorArg().getExtension()));
}
// We use BUILT_PRODUCTS_DIR as the root for the everything being built. Target-
// specific output is placed within CONFIGURATION_BUILD_DIR, inside BUILT_PRODUCTS_DIR.
// That allows Copy Files build phases to reference files in the CONFIGURATION_BUILD_DIR
// of other targets by using paths relative to the target-independent BUILT_PRODUCTS_DIR.
defaultSettingsBuilder.put("BUILT_PRODUCTS_DIR", // $SYMROOT/Debug-iphonesimulator
Joiner.on('/').join("$SYMROOT", "$CONFIGURATION$EFFECTIVE_PLATFORM_NAME"));
defaultSettingsBuilder.put("CONFIGURATION_BUILD_DIR", "$BUILT_PRODUCTS_DIR");
boolean nodeIsAppleLibrary = targetNode.getDescription() instanceof AppleLibraryDescription;
boolean nodeIsCxxLibrary = targetNode.getDescription() instanceof CxxLibraryDescription;
if (!bundle.isPresent() && (nodeIsAppleLibrary || nodeIsCxxLibrary)) {
defaultSettingsBuilder.put("EXECUTABLE_PREFIX", "lib");
}
if (isFocusedOnTarget) {
ImmutableSet<Path> recursiveHeaderSearchPaths = collectRecursiveHeaderSearchPaths(targetNode);
ImmutableSet<Path> headerMapBases = recursiveHeaderSearchPaths.isEmpty() ? ImmutableSet.of() : ImmutableSet.of(pathRelativizer.outputDirToRootRelative(buildTargetNode.getFilesystem().getBuckPaths().getBuckOut()));
ImmutableMap.Builder<String, String> appendConfigsBuilder = ImmutableMap.builder();
appendConfigsBuilder.put("HEADER_SEARCH_PATHS", Joiner.on(' ').join(Iterables.concat(recursiveHeaderSearchPaths, headerMapBases))).put("LIBRARY_SEARCH_PATHS", Joiner.on(' ').join(collectRecursiveLibrarySearchPaths(ImmutableSet.of(targetNode)))).put("FRAMEWORK_SEARCH_PATHS", Joiner.on(' ').join(collectRecursiveFrameworkSearchPaths(ImmutableList.of(targetNode))));
Iterable<String> otherCFlags = Iterables.concat(cxxBuckConfig.getFlags("cflags").orElse(DEFAULT_CFLAGS), collectRecursiveExportedPreprocessorFlags(ImmutableList.of(targetNode)), targetNode.getConstructorArg().compilerFlags, targetNode.getConstructorArg().preprocessorFlags);
Iterable<String> otherCxxFlags = Iterables.concat(cxxBuckConfig.getFlags("cxxflags").orElse(DEFAULT_CXXFLAGS), collectRecursiveExportedPreprocessorFlags(ImmutableList.of(targetNode)), targetNode.getConstructorArg().compilerFlags, targetNode.getConstructorArg().preprocessorFlags);
ImmutableList<String> otherLdFlags = convertStringWithMacros(targetNode, Iterables.concat(targetNode.getConstructorArg().linkerFlags, collectRecursiveExportedLinkerFlags(ImmutableList.of(targetNode))));
appendConfigsBuilder.put("OTHER_CFLAGS", Joiner.on(' ').join(Iterables.transform(otherCFlags, Escaper.BASH_ESCAPER))).put("OTHER_CPLUSPLUSFLAGS", Joiner.on(' ').join(Iterables.transform(otherCxxFlags, Escaper.BASH_ESCAPER))).put("OTHER_LDFLAGS", Joiner.on(' ').join(Iterables.transform(otherLdFlags, Escaper.BASH_ESCAPER)));
ImmutableMultimap.Builder<String, ImmutableList<String>> platformFlagsBuilder = ImmutableMultimap.builder();
for (Pair<Pattern, ImmutableList<String>> flags : Iterables.concat(targetNode.getConstructorArg().platformCompilerFlags.getPatternsAndValues(), targetNode.getConstructorArg().platformPreprocessorFlags.getPatternsAndValues(), collectRecursiveExportedPlatformPreprocessorFlags(ImmutableList.of(targetNode)))) {
String sdk = flags.getFirst().pattern().replaceAll("[*.]", "");
platformFlagsBuilder.put(sdk, flags.getSecond());
}
ImmutableMultimap<String, ImmutableList<String>> platformFlags = platformFlagsBuilder.build();
for (String sdk : platformFlags.keySet()) {
appendConfigsBuilder.put(String.format("OTHER_CFLAGS[sdk=*%s*]", sdk), Joiner.on(' ').join(Iterables.transform(Iterables.concat(otherCFlags, Iterables.concat(platformFlags.get(sdk))), Escaper.BASH_ESCAPER))).put(String.format("OTHER_CPLUSPLUSFLAGS[sdk=*%s*]", sdk), Joiner.on(' ').join(Iterables.transform(Iterables.concat(otherCxxFlags, Iterables.concat(platformFlags.get(sdk))), Escaper.BASH_ESCAPER)));
}
ImmutableMultimap.Builder<String, ImmutableList<String>> platformLinkerFlagsBuilder = ImmutableMultimap.builder();
for (Pair<Pattern, ImmutableList<StringWithMacros>> flags : Iterables.concat(targetNode.getConstructorArg().platformLinkerFlags.getPatternsAndValues(), collectRecursiveExportedPlatformLinkerFlags(ImmutableList.of(targetNode)))) {
String sdk = flags.getFirst().pattern().replaceAll("[*.]", "");
platformLinkerFlagsBuilder.put(sdk, convertStringWithMacros(targetNode, flags.getSecond()));
}
ImmutableMultimap<String, ImmutableList<String>> platformLinkerFlags = platformLinkerFlagsBuilder.build();
for (String sdk : platformLinkerFlags.keySet()) {
appendConfigsBuilder.put(String.format("OTHER_LDFLAGS[sdk=*%s*]", sdk), Joiner.on(' ').join(Iterables.transform(Iterables.concat(otherLdFlags, Iterables.concat(platformLinkerFlags.get(sdk))), Escaper.BASH_ESCAPER)));
}
ImmutableMap<String, String> appendedConfig = appendConfigsBuilder.build();
Optional<ImmutableSortedMap<String, ImmutableMap<String, String>>> configs = getXcodeBuildConfigurationsForTargetNode(targetNode, appendedConfig);
setTargetBuildConfigurations(getConfigurationNameToXcconfigPath(buildTarget), target, project.getMainGroup(), configs.get(), extraSettingsBuilder.build(), defaultSettingsBuilder.build(), appendedConfig);
}
}
// -- phases
createHeaderSymlinkTree(getPublicCxxHeaders(targetNode), getPathToHeaderSymlinkTree(targetNode, HeaderVisibility.PUBLIC), arg.xcodePublicHeadersSymlinks.orElse(true) || isHeaderMapDisabled(), !shouldMergeHeaderMaps());
if (isFocusedOnTarget) {
createHeaderSymlinkTree(getPrivateCxxHeaders(targetNode), getPathToHeaderSymlinkTree(targetNode, HeaderVisibility.PRIVATE), arg.xcodePrivateHeadersSymlinks.orElse(true) || isHeaderMapDisabled(), !isHeaderMapDisabled());
}
if (shouldMergeHeaderMaps() && isMainProject) {
createMergedHeaderMap();
}
if (appleTargetNode.isPresent() && isFocusedOnTarget && !shouldGenerateHeaderSymlinkTreesOnly()) {
// Use Core Data models from immediate dependencies only.
addCoreDataModelsIntoTarget(appleTargetNode.get(), targetGroup.get());
addSceneKitAssetsIntoTarget(appleTargetNode.get(), targetGroup.get());
}
return target;
}
use of com.facebook.buck.apple.AppleLibraryDescription in project buck by facebook.
the class KnownBuildRuleTypes method createBuilder.
@VisibleForTesting
static Builder createBuilder(BuckConfig config, ProjectFilesystem filesystem, ProcessExecutor processExecutor, AndroidDirectoryResolver androidDirectoryResolver) throws InterruptedException, IOException {
Platform platform = Platform.detect();
AndroidBuckConfig androidConfig = new AndroidBuckConfig(config, platform);
Optional<String> ndkVersion = androidConfig.getNdkVersion();
// out which one we will end up using.
if (!ndkVersion.isPresent()) {
ndkVersion = androidDirectoryResolver.getNdkVersion();
}
AppleConfig appleConfig = new AppleConfig(config);
SwiftBuckConfig swiftBuckConfig = new SwiftBuckConfig(config);
final ImmutableList<AppleCxxPlatform> appleCxxPlatforms = buildAppleCxxPlatforms(filesystem, appleConfig.getAppleDeveloperDirectorySupplier(processExecutor), appleConfig.getExtraToolchainPaths(), appleConfig.getExtraPlatformPaths(), config, appleConfig, swiftBuckConfig, processExecutor);
final FlavorDomain<AppleCxxPlatform> platformFlavorsToAppleCxxPlatforms = FlavorDomain.from("Apple C++ Platform", appleCxxPlatforms);
ImmutableMap.Builder<Flavor, SwiftPlatform> swiftPlatforms = ImmutableMap.builder();
for (Flavor flavor : platformFlavorsToAppleCxxPlatforms.getFlavors()) {
Optional<SwiftPlatform> swiftPlatformOptional = platformFlavorsToAppleCxxPlatforms.getValue(flavor).getSwiftPlatform();
if (swiftPlatformOptional.isPresent()) {
swiftPlatforms.put(flavor, swiftPlatformOptional.get());
}
}
CxxBuckConfig cxxBuckConfig = new CxxBuckConfig(config);
// Setup the NDK C/C++ platforms.
Optional<Path> ndkRoot = androidDirectoryResolver.getNdkOrAbsent();
ImmutableMap.Builder<NdkCxxPlatforms.TargetCpuType, NdkCxxPlatform> ndkCxxPlatformsBuilder = ImmutableMap.builder();
if (ndkRoot.isPresent()) {
NdkCxxPlatformCompiler.Type compilerType = androidConfig.getNdkCompiler().orElse(NdkCxxPlatforms.DEFAULT_COMPILER_TYPE);
String gccVersion = androidConfig.getNdkGccVersion().orElse(NdkCxxPlatforms.getDefaultGccVersionForNdk(ndkVersion));
String clangVersion = androidConfig.getNdkClangVersion().orElse(NdkCxxPlatforms.getDefaultClangVersionForNdk(ndkVersion));
String compilerVersion = compilerType == NdkCxxPlatformCompiler.Type.GCC ? gccVersion : clangVersion;
NdkCxxPlatformCompiler compiler = NdkCxxPlatformCompiler.builder().setType(compilerType).setVersion(compilerVersion).setGccVersion(gccVersion).build();
ndkCxxPlatformsBuilder.putAll(NdkCxxPlatforms.getPlatforms(cxxBuckConfig, filesystem, ndkRoot.get(), compiler, androidConfig.getNdkCxxRuntime().orElse(NdkCxxPlatforms.DEFAULT_CXX_RUNTIME), androidConfig.getNdkAppPlatform().orElse(NdkCxxPlatforms.DEFAULT_TARGET_APP_PLATFORM), androidConfig.getNdkCpuAbis().orElse(NdkCxxPlatforms.DEFAULT_CPU_ABIS), platform));
}
ImmutableMap<NdkCxxPlatforms.TargetCpuType, NdkCxxPlatform> ndkCxxPlatforms = ndkCxxPlatformsBuilder.build();
// Create a map of system platforms.
ImmutableMap.Builder<Flavor, CxxPlatform> cxxSystemPlatformsBuilder = ImmutableMap.builder();
// testing our Android NDK support for right now.
for (NdkCxxPlatform ndkCxxPlatform : ndkCxxPlatforms.values()) {
cxxSystemPlatformsBuilder.put(ndkCxxPlatform.getCxxPlatform().getFlavor(), ndkCxxPlatform.getCxxPlatform());
}
for (AppleCxxPlatform appleCxxPlatform : platformFlavorsToAppleCxxPlatforms.getValues()) {
cxxSystemPlatformsBuilder.put(appleCxxPlatform.getCxxPlatform().getFlavor(), appleCxxPlatform.getCxxPlatform());
}
CxxPlatform defaultHostCxxPlatform = DefaultCxxPlatforms.build(platform, filesystem, cxxBuckConfig);
cxxSystemPlatformsBuilder.put(defaultHostCxxPlatform.getFlavor(), defaultHostCxxPlatform);
ImmutableMap<Flavor, CxxPlatform> cxxSystemPlatformsMap = cxxSystemPlatformsBuilder.build();
// Add the host platform if needed (for example, when building on Linux).
Flavor hostFlavor = CxxPlatforms.getHostFlavor();
if (!cxxSystemPlatformsMap.containsKey(hostFlavor)) {
cxxSystemPlatformsBuilder.put(hostFlavor, CxxPlatform.builder().from(defaultHostCxxPlatform).setFlavor(hostFlavor).build());
cxxSystemPlatformsMap = cxxSystemPlatformsBuilder.build();
}
// Add platforms for each cxx flavor obtained from the buck config files
// from sections of the form cxx#{flavor name}.
// These platforms are overrides for existing system platforms.
ImmutableSet<Flavor> possibleHostFlavors = CxxPlatforms.getAllPossibleHostFlavors();
HashMap<Flavor, CxxPlatform> cxxOverridePlatformsMap = new HashMap<Flavor, CxxPlatform>(cxxSystemPlatformsMap);
ImmutableSet<Flavor> cxxFlavors = CxxBuckConfig.getCxxFlavors(config);
for (Flavor flavor : cxxFlavors) {
CxxPlatform baseCxxPlatform = cxxSystemPlatformsMap.get(flavor);
if (baseCxxPlatform == null) {
if (possibleHostFlavors.contains(flavor)) {
// If a flavor is for an alternate host, it's safe to skip.
continue;
}
LOG.info("Applying \"%s\" overrides to default host platform", flavor);
baseCxxPlatform = defaultHostCxxPlatform;
}
cxxOverridePlatformsMap.put(flavor, CxxPlatforms.copyPlatformWithFlavorAndConfig(baseCxxPlatform, platform, new CxxBuckConfig(config, flavor), flavor));
}
// Finalize our "default" host.
// TODO(Ktwu) The host flavor should default to a concrete flavor
// like "linux-x86_64", not "default".
hostFlavor = DefaultCxxPlatforms.FLAVOR;
Optional<String> hostCxxPlatformOverride = cxxBuckConfig.getHostPlatform();
if (hostCxxPlatformOverride.isPresent()) {
Flavor overrideFlavor = InternalFlavor.of(hostCxxPlatformOverride.get());
if (cxxOverridePlatformsMap.containsKey(overrideFlavor)) {
hostFlavor = overrideFlavor;
}
}
CxxPlatform hostCxxPlatform = CxxPlatform.builder().from(cxxOverridePlatformsMap.get(hostFlavor)).setFlavor(DefaultCxxPlatforms.FLAVOR).build();
cxxOverridePlatformsMap.put(DefaultCxxPlatforms.FLAVOR, hostCxxPlatform);
ImmutableMap<Flavor, CxxPlatform> cxxPlatformsMap = ImmutableMap.<Flavor, CxxPlatform>builder().putAll(cxxOverridePlatformsMap).build();
ExecutableFinder executableFinder = new ExecutableFinder();
// Build up the final list of C/C++ platforms.
FlavorDomain<CxxPlatform> cxxPlatforms = new FlavorDomain<>("C/C++ platform", cxxPlatformsMap);
// Get the default target platform from config.
CxxPlatform defaultCxxPlatform = CxxPlatforms.getConfigDefaultCxxPlatform(cxxBuckConfig, cxxPlatformsMap, hostCxxPlatform);
DBuckConfig dBuckConfig = new DBuckConfig(config);
ReactNativeBuckConfig reactNativeBuckConfig = new ReactNativeBuckConfig(config);
RustBuckConfig rustBuckConfig = new RustBuckConfig(config);
GoBuckConfig goBuckConfig = new GoBuckConfig(config, processExecutor, cxxPlatforms);
HalideBuckConfig halideBuckConfig = new HalideBuckConfig(config);
ProGuardConfig proGuardConfig = new ProGuardConfig(config);
DxConfig dxConfig = new DxConfig(config);
PythonBuckConfig pyConfig = new PythonBuckConfig(config, executableFinder);
ImmutableList<PythonPlatform> pythonPlatformsList = pyConfig.getPythonPlatforms(processExecutor);
FlavorDomain<PythonPlatform> pythonPlatforms = FlavorDomain.from("Python Platform", pythonPlatformsList);
PythonBinaryDescription pythonBinaryDescription = new PythonBinaryDescription(pyConfig, pythonPlatforms, cxxBuckConfig, defaultCxxPlatform, cxxPlatforms);
// Look up the timeout to apply to entire test rules.
Optional<Long> defaultTestRuleTimeoutMs = config.getLong("test", "rule_timeout");
// Prepare the downloader if we're allowing mid-build downloads
Downloader downloader;
DownloadConfig downloadConfig = new DownloadConfig(config);
if (downloadConfig.isDownloadAtRuntimeOk()) {
downloader = StackedDownloader.createFromConfig(config, androidDirectoryResolver.getSdkOrAbsent());
} else {
// Or just set one that blows up
downloader = new ExplodingDownloader();
}
Builder builder = builder();
JavaBuckConfig javaConfig = config.getView(JavaBuckConfig.class);
JavacOptions defaultJavacOptions = javaConfig.getDefaultJavacOptions();
JavaOptions defaultJavaOptions = javaConfig.getDefaultJavaOptions();
JavaOptions defaultJavaOptionsForTests = javaConfig.getDefaultJavaOptionsForTests();
KotlinBuckConfig kotlinBuckConfig = new KotlinBuckConfig(config);
ScalaBuckConfig scalaConfig = new ScalaBuckConfig(config);
InferBuckConfig inferBuckConfig = new InferBuckConfig(config);
LuaConfig luaConfig = new LuaBuckConfig(config, executableFinder);
CxxBinaryDescription cxxBinaryDescription = new CxxBinaryDescription(cxxBuckConfig, inferBuckConfig, defaultCxxPlatform, cxxPlatforms);
CxxLibraryDescription cxxLibraryDescription = new CxxLibraryDescription(cxxBuckConfig, defaultCxxPlatform, inferBuckConfig, cxxPlatforms);
FlavorDomain<SwiftPlatform> platformFlavorsToSwiftPlatforms = new FlavorDomain<>("Swift Platform", swiftPlatforms.build());
SwiftLibraryDescription swiftLibraryDescription = new SwiftLibraryDescription(cxxBuckConfig, swiftBuckConfig, cxxPlatforms, platformFlavorsToSwiftPlatforms);
builder.register(swiftLibraryDescription);
CodeSignIdentityStore codeSignIdentityStore = CodeSignIdentityStore.fromSystem(processExecutor, appleConfig.getCodeSignIdentitiesCommand());
ProvisioningProfileStore provisioningProfileStore = ProvisioningProfileStore.fromSearchPath(processExecutor, appleConfig.getProvisioningProfileReadCommand(), appleConfig.getProvisioningProfileSearchPath());
AppleLibraryDescription appleLibraryDescription = new AppleLibraryDescription(cxxLibraryDescription, swiftLibraryDescription, platformFlavorsToAppleCxxPlatforms, defaultCxxPlatform, codeSignIdentityStore, provisioningProfileStore, appleConfig);
builder.register(appleLibraryDescription);
PrebuiltAppleFrameworkDescription appleFrameworkDescription = new PrebuiltAppleFrameworkDescription();
builder.register(appleFrameworkDescription);
AppleBinaryDescription appleBinaryDescription = new AppleBinaryDescription(cxxBinaryDescription, swiftLibraryDescription, platformFlavorsToAppleCxxPlatforms, codeSignIdentityStore, provisioningProfileStore, appleConfig);
builder.register(appleBinaryDescription);
HaskellBuckConfig haskellBuckConfig = new HaskellBuckConfig(config, executableFinder);
builder.register(new HaskellLibraryDescription(haskellBuckConfig, cxxBuckConfig, cxxPlatforms));
builder.register(new HaskellBinaryDescription(haskellBuckConfig, cxxPlatforms, defaultCxxPlatform));
builder.register(new HaskellPrebuiltLibraryDescription());
if (javaConfig.getDxThreadCount().isPresent()) {
LOG.warn("java.dx_threads has been deprecated. Use dx.max_threads instead");
}
// Create an executor service exclusively for the smart dexing step.
ListeningExecutorService dxExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(dxConfig.getDxMaxThreadCount().orElse(javaConfig.getDxThreadCount().orElse(SmartDexingStep.determineOptimalThreadCount())), new CommandThreadFactory("SmartDexing")));
builder.register(new AndroidAarDescription(new AndroidManifestDescription(), cxxBuckConfig, defaultJavacOptions, ndkCxxPlatforms));
builder.register(new AndroidBinaryDescription(defaultJavaOptions, defaultJavacOptions, proGuardConfig, ndkCxxPlatforms, dxExecutorService, config, cxxBuckConfig, dxConfig));
builder.register(new AndroidBuildConfigDescription(defaultJavacOptions));
builder.register(new AndroidInstrumentationApkDescription(proGuardConfig, defaultJavacOptions, ndkCxxPlatforms, dxExecutorService, cxxBuckConfig, dxConfig));
builder.register(new AndroidInstrumentationTestDescription(defaultJavaOptions, defaultTestRuleTimeoutMs));
builder.register(new AndroidLibraryDescription(defaultJavacOptions, new DefaultAndroidLibraryCompilerFactory(scalaConfig, kotlinBuckConfig)));
builder.register(new AndroidManifestDescription());
builder.register(new AndroidPrebuiltAarDescription(defaultJavacOptions));
builder.register(new AndroidReactNativeLibraryDescription(reactNativeBuckConfig));
builder.register(new AndroidResourceDescription(config.isGrayscaleImageProcessingEnabled()));
builder.register(new ApkGenruleDescription());
builder.register(new AppleAssetCatalogDescription());
builder.register(new ApplePackageDescription(appleConfig, defaultCxxPlatform, platformFlavorsToAppleCxxPlatforms));
AppleBundleDescription appleBundleDescription = new AppleBundleDescription(appleBinaryDescription, appleLibraryDescription, cxxPlatforms, platformFlavorsToAppleCxxPlatforms, defaultCxxPlatform, codeSignIdentityStore, provisioningProfileStore, appleConfig);
builder.register(appleBundleDescription);
builder.register(new AppleResourceDescription());
builder.register(new AppleTestDescription(appleConfig, appleLibraryDescription, cxxPlatforms, platformFlavorsToAppleCxxPlatforms, defaultCxxPlatform, codeSignIdentityStore, provisioningProfileStore, appleConfig.getAppleDeveloperDirectorySupplierForTests(processExecutor), defaultTestRuleTimeoutMs));
builder.register(new CoreDataModelDescription());
builder.register(new CsharpLibraryDescription());
builder.register(cxxBinaryDescription);
builder.register(cxxLibraryDescription);
builder.register(new CxxGenruleDescription(cxxPlatforms));
builder.register(new CxxLuaExtensionDescription(luaConfig, cxxBuckConfig, cxxPlatforms));
builder.register(new CxxPythonExtensionDescription(pythonPlatforms, cxxBuckConfig, cxxPlatforms));
builder.register(new CxxTestDescription(cxxBuckConfig, defaultCxxPlatform, cxxPlatforms, defaultTestRuleTimeoutMs));
builder.register(new DBinaryDescription(dBuckConfig, cxxBuckConfig, defaultCxxPlatform));
builder.register(new DLibraryDescription(dBuckConfig, cxxBuckConfig, defaultCxxPlatform));
builder.register(new DTestDescription(dBuckConfig, cxxBuckConfig, defaultCxxPlatform, defaultTestRuleTimeoutMs));
builder.register(new ExportFileDescription());
builder.register(new GenruleDescription());
builder.register(new GenAidlDescription());
builder.register(new GoBinaryDescription(goBuckConfig));
builder.register(new GoLibraryDescription(goBuckConfig));
builder.register(new GoTestDescription(goBuckConfig, defaultTestRuleTimeoutMs));
builder.register(new GraphqlLibraryDescription());
GroovyBuckConfig groovyBuckConfig = new GroovyBuckConfig(config);
builder.register(new GroovyLibraryDescription(groovyBuckConfig, defaultJavacOptions));
builder.register(new GroovyTestDescription(groovyBuckConfig, defaultJavaOptionsForTests, defaultJavacOptions, defaultTestRuleTimeoutMs));
builder.register(new GwtBinaryDescription(defaultJavaOptions));
builder.register(new HalideLibraryDescription(cxxBuckConfig, defaultCxxPlatform, cxxPlatforms, halideBuckConfig));
builder.register(new IosReactNativeLibraryDescription(reactNativeBuckConfig));
builder.register(new JavaBinaryDescription(defaultJavaOptions, defaultJavacOptions, defaultCxxPlatform, javaConfig));
builder.register(new JavaAnnotationProcessorDescription());
builder.register(new JavaLibraryDescription(defaultJavacOptions));
builder.register(new JavaTestDescription(defaultJavaOptionsForTests, defaultJavacOptions, defaultTestRuleTimeoutMs, defaultCxxPlatform));
builder.register(new JsBundleDescription());
builder.register(new JsLibraryDescription());
builder.register(new KeystoreDescription());
builder.register(new KotlinLibraryDescription(kotlinBuckConfig, defaultJavacOptions));
builder.register(new KotlinTestDescription(kotlinBuckConfig, defaultJavaOptionsForTests, defaultJavacOptions, defaultTestRuleTimeoutMs));
builder.register(new LuaBinaryDescription(luaConfig, cxxBuckConfig, defaultCxxPlatform, cxxPlatforms, pythonPlatforms));
builder.register(new LuaLibraryDescription());
builder.register(new NdkLibraryDescription(ndkVersion, ndkCxxPlatforms));
OcamlBuckConfig ocamlBuckConfig = new OcamlBuckConfig(config, defaultCxxPlatform);
builder.register(new OcamlBinaryDescription(ocamlBuckConfig));
builder.register(new OcamlLibraryDescription(ocamlBuckConfig));
builder.register(new PrebuiltCxxLibraryDescription(cxxBuckConfig, cxxPlatforms));
builder.register(PrebuiltCxxLibraryGroupDescription.of());
builder.register(new CxxPrecompiledHeaderDescription());
builder.register(new PrebuiltDotnetLibraryDescription());
builder.register(new PrebuiltJarDescription());
builder.register(new PrebuiltNativeLibraryDescription());
builder.register(new PrebuiltOcamlLibraryDescription());
builder.register(new PrebuiltPythonLibraryDescription());
builder.register(new ProjectConfigDescription());
builder.register(pythonBinaryDescription);
PythonLibraryDescription pythonLibraryDescription = new PythonLibraryDescription(pythonPlatforms, cxxPlatforms);
builder.register(pythonLibraryDescription);
builder.register(new PythonTestDescription(pythonBinaryDescription, pyConfig, pythonPlatforms, cxxBuckConfig, defaultCxxPlatform, defaultTestRuleTimeoutMs, cxxPlatforms));
builder.register(new RemoteFileDescription(downloader));
builder.register(new RobolectricTestDescription(defaultJavaOptionsForTests, defaultJavacOptions, defaultTestRuleTimeoutMs, defaultCxxPlatform));
builder.register(new RustBinaryDescription(rustBuckConfig, cxxPlatforms, defaultCxxPlatform));
builder.register(new RustLibraryDescription(rustBuckConfig, cxxPlatforms, defaultCxxPlatform));
builder.register(new RustTestDescription(rustBuckConfig, cxxPlatforms, defaultCxxPlatform));
builder.register(new PrebuiltRustLibraryDescription());
builder.register(new ScalaLibraryDescription(scalaConfig));
builder.register(new ScalaTestDescription(scalaConfig, defaultJavaOptionsForTests, defaultTestRuleTimeoutMs, defaultCxxPlatform));
builder.register(new SceneKitAssetsDescription());
builder.register(new ShBinaryDescription());
builder.register(new ShTestDescription(defaultTestRuleTimeoutMs));
builder.register(new WorkerToolDescription(config));
builder.register(new XcodePostbuildScriptDescription());
builder.register(new XcodePrebuildScriptDescription());
builder.register(new XcodeWorkspaceConfigDescription());
builder.register(new ZipFileDescription());
builder.register(new TargetGroupDescription());
builder.setCxxPlatforms(cxxPlatforms);
builder.setDefaultCxxPlatform(defaultCxxPlatform);
builder.register(VersionedAliasDescription.of());
return builder;
}
use of com.facebook.buck.apple.AppleLibraryDescription in project buck by facebook.
the class ProjectGenerator method getProductsSourceTreePath.
private SourceTreePath getProductsSourceTreePath(TargetNode<?, ?> targetNode) {
String productName = getProductNameForBuildTarget(targetNode.getBuildTarget());
String productOutputName;
if (targetNode.getDescription() instanceof AppleLibraryDescription || targetNode.getDescription() instanceof CxxLibraryDescription || targetNode.getDescription() instanceof HalideLibraryDescription) {
String productOutputFormat = AppleBuildRules.getOutputFileNameFormatForLibrary(targetNode.getBuildTarget().getFlavors().contains(CxxDescriptionEnhancer.SHARED_FLAVOR));
productOutputName = String.format(productOutputFormat, productName);
} else if (targetNode.getDescription() instanceof AppleBundleDescription || targetNode.getDescription() instanceof AppleTestDescription) {
HasAppleBundleFields arg = (HasAppleBundleFields) targetNode.getConstructorArg();
productName = arg.getProductName().orElse(productName);
productOutputName = productName + "." + getExtensionString(arg.getExtension());
} else if (targetNode.getDescription() instanceof AppleBinaryDescription) {
productOutputName = productName;
} else {
throw new RuntimeException("Unexpected type: " + targetNode.getDescription().getClass());
}
return new SourceTreePath(PBXReference.SourceTree.BUILT_PRODUCTS_DIR, Paths.get(productOutputName), Optional.empty());
}
use of com.facebook.buck.apple.AppleLibraryDescription in project buck by facebook.
the class ProjectGenerator method generateProjectTarget.
@SuppressWarnings("unchecked")
private Optional<PBXTarget> generateProjectTarget(TargetNode<?, ?> targetNode) throws IOException {
Preconditions.checkState(isBuiltByCurrentProject(targetNode.getBuildTarget()), "should not generate rule if it shouldn't be built by current project");
Optional<PBXTarget> result = Optional.empty();
if (targetNode.getDescription() instanceof AppleLibraryDescription) {
result = Optional.of(generateAppleLibraryTarget(project, (TargetNode<AppleNativeTargetDescriptionArg, ?>) targetNode, Optional.empty()));
} else if (targetNode.getDescription() instanceof CxxLibraryDescription) {
result = Optional.of(generateCxxLibraryTarget(project, (TargetNode<CxxLibraryDescription.Arg, ?>) targetNode, ImmutableSet.of(), ImmutableSet.of(), Optional.empty()));
} else if (targetNode.getDescription() instanceof AppleBinaryDescription) {
result = Optional.of(generateAppleBinaryTarget(project, (TargetNode<AppleNativeTargetDescriptionArg, ?>) targetNode));
} else if (targetNode.getDescription() instanceof AppleBundleDescription) {
TargetNode<AppleBundleDescription.Arg, ?> bundleTargetNode = (TargetNode<AppleBundleDescription.Arg, ?>) targetNode;
result = Optional.of(generateAppleBundleTarget(project, bundleTargetNode, (TargetNode<AppleNativeTargetDescriptionArg, ?>) targetGraph.get(bundleTargetNode.getConstructorArg().binary), Optional.empty()));
} else if (targetNode.getDescription() instanceof AppleTestDescription) {
result = Optional.of(generateAppleTestTarget((TargetNode<AppleTestDescription.Arg, ?>) targetNode));
} else if (targetNode.getDescription() instanceof AppleResourceDescription) {
checkAppleResourceTargetNodeReferencingValidContents((TargetNode<AppleResourceDescription.Arg, ?>) targetNode);
} else if (targetNode.getDescription() instanceof HalideLibraryDescription) {
TargetNode<HalideLibraryDescription.Arg, ?> halideTargetNode = (TargetNode<HalideLibraryDescription.Arg, ?>) targetNode;
BuildTarget buildTarget = targetNode.getBuildTarget();
// The generated target just runs a shell script that invokes the "compiler" with the
// correct target architecture.
result = generateHalideLibraryTarget(project, halideTargetNode);
// Make sure the compiler gets built at project time, since we'll need
// it to generate the shader code during the Xcode build.
requiredBuildTargetsBuilder.add(HalideLibraryDescription.createHalideCompilerBuildTarget(buildTarget));
// headers from.
if (HalideLibraryDescription.isPlatformSupported(halideTargetNode.getConstructorArg(), defaultCxxPlatform)) {
// Run the compiler once at project time to generate the header
// file needed for compilation if the Halide target is for the default
// platform.
requiredBuildTargetsBuilder.add(buildTarget.withFlavors(HalideLibraryDescription.HALIDE_COMPILE_FLAVOR, defaultCxxPlatform.getFlavor()));
}
}
buckEventBus.post(ProjectGenerationEvent.processed());
return result;
}
Aggregations