private static void buildAppleCxxPlatforms( Supplier<Optional<Path>> appleDeveloperDirectorySupplier, ImmutableList<Path> extraToolchainPaths, ImmutableList<Path> extraPlatformPaths, BuckConfig buckConfig, AppleConfig appleConfig, ImmutableMap.Builder<Flavor, AppleCxxPlatform> platformFlavorsToAppleSdkPathsBuilder) throws IOException { Optional<Path> appleDeveloperDirectory = appleDeveloperDirectorySupplier.get(); if (appleDeveloperDirectory.isPresent() && !Files.isDirectory(appleDeveloperDirectory.get())) { LOG.error( "Developer directory is set to %s, but is not a directory", appleDeveloperDirectory.get()); return; } ImmutableMap<String, AppleToolchain> toolchains = AppleToolchainDiscovery.discoverAppleToolchains( appleDeveloperDirectory, extraToolchainPaths); ImmutableMap<AppleSdk, AppleSdkPaths> sdkPaths = AppleSdkDiscovery.discoverAppleSdkPaths( appleDeveloperDirectory, extraPlatformPaths, toolchains); for (Map.Entry<AppleSdk, AppleSdkPaths> entry : sdkPaths.entrySet()) { AppleSdk sdk = entry.getKey(); AppleSdkPaths appleSdkPaths = entry.getValue(); String targetSdkVersion = appleConfig.getTargetSdkVersion(sdk.getApplePlatform()).or(sdk.getVersion()); LOG.debug("SDK %s using default version %s", sdk, targetSdkVersion); for (String architecture : sdk.getArchitectures()) { AppleCxxPlatform appleCxxPlatform = AppleCxxPlatforms.build(sdk, targetSdkVersion, architecture, appleSdkPaths, buckConfig); platformFlavorsToAppleSdkPathsBuilder.put( appleCxxPlatform.getCxxPlatform().getFlavor(), appleCxxPlatform); } } }
@VisibleForTesting static Builder createBuilder( BuckConfig config, ProcessExecutor processExecutor, AndroidDirectoryResolver androidDirectoryResolver, Optional<Path> testTempDirOverride) throws InterruptedException, IOException { Platform platform = Platform.detect(); AndroidBuckConfig androidConfig = new AndroidBuckConfig(config, platform); Optional<String> ndkVersion = androidConfig.getNdkVersion(); // If a NDK version isn't specified, we've got to reach into the runtime environment to find // out which one we will end up using. if (!ndkVersion.isPresent()) { ndkVersion = androidDirectoryResolver.getNdkVersion(); } AppleConfig appleConfig = new AppleConfig(config); final AppleBundle.DebugInfoFormat defaultDebugInfoFormat = appleConfig.getDebugInfoFormat(); ImmutableMap.Builder<Flavor, AppleCxxPlatform> platformFlavorsToAppleCxxPlatformsBuilder = ImmutableMap.builder(); buildAppleCxxPlatforms( appleConfig.getAppleDeveloperDirectorySupplier(processExecutor), appleConfig.getExtraToolchainPaths(), appleConfig.getExtraPlatformPaths(), config, appleConfig, platformFlavorsToAppleCxxPlatformsBuilder); ImmutableMap<Flavor, AppleCxxPlatform> platformFlavorsToAppleCxxPlatforms = platformFlavorsToAppleCxxPlatformsBuilder.build(); // Setup the NDK C/C++ platforms. Optional<Path> ndkRoot = androidDirectoryResolver.findAndroidNdkDir(); ImmutableMap.Builder<NdkCxxPlatforms.TargetCpuType, NdkCxxPlatform> ndkCxxPlatformsBuilder = ImmutableMap.builder(); if (ndkRoot.isPresent()) { NdkCxxPlatforms.Compiler.Type compilerType = androidConfig.getNdkCompiler().or(NdkCxxPlatforms.DEFAULT_COMPILER_TYPE); String gccVersion = androidConfig.getNdkGccVersion().or(NdkCxxPlatforms.DEFAULT_GCC_VERSION); NdkCxxPlatforms.Compiler compiler = ImmutableNdkCxxPlatforms.Compiler.builder() .setType(compilerType) .setVersion( compilerType == NdkCxxPlatforms.Compiler.Type.GCC ? gccVersion : androidConfig .getNdkClangVersion() .or(NdkCxxPlatforms.DEFAULT_CLANG_VERSION)) .setGccVersion(gccVersion) .build(); ndkCxxPlatformsBuilder.putAll( NdkCxxPlatforms.getPlatforms( new ProjectFilesystem(ndkRoot.get()), compiler, androidConfig.getNdkCxxRuntime().or(NdkCxxPlatforms.DEFAULT_CXX_RUNTIME), androidConfig.getNdkAppPlatform().or(NdkCxxPlatforms.DEFAULT_TARGET_APP_PLATFORM), androidConfig.getNdkCpuAbis().or(NdkCxxPlatforms.DEFAULT_CPU_ABIS), platform)); } ImmutableMap<NdkCxxPlatforms.TargetCpuType, NdkCxxPlatform> ndkCxxPlatforms = ndkCxxPlatformsBuilder.build(); // Construct the C/C++ config wrapping the buck config. CxxBuckConfig cxxBuckConfig = new CxxBuckConfig(config); ImmutableMap.Builder<Flavor, CxxPlatform> cxxPlatformsBuilder = ImmutableMap.builder(); // If an Android NDK is present, add platforms for that. This is mostly useful for // testing our Android NDK support for right now. for (NdkCxxPlatform ndkCxxPlatform : ndkCxxPlatforms.values()) { cxxPlatformsBuilder.put( ndkCxxPlatform.getCxxPlatform().getFlavor(), ndkCxxPlatform.getCxxPlatform()); } for (Map.Entry<Flavor, AppleCxxPlatform> entry : platformFlavorsToAppleCxxPlatforms.entrySet()) { cxxPlatformsBuilder.put(entry.getKey(), entry.getValue().getCxxPlatform()); } // Add the default, config-defined C/C++ platform. CxxPlatform systemDefaultCxxPlatform = DefaultCxxPlatforms.build(platform, cxxBuckConfig); cxxPlatformsBuilder.put(systemDefaultCxxPlatform.getFlavor(), systemDefaultCxxPlatform); ImmutableMap<Flavor, CxxPlatform> cxxPlatformsMap = cxxPlatformsBuilder.build(); // Get the default platform from config. CxxPlatform defaultCxxPlatform = CxxPlatforms.getConfigDefaultCxxPlatform( cxxBuckConfig, cxxPlatformsMap, systemDefaultCxxPlatform); // Add platforms for each cxx flavor obtained from the buck config files // from sections of the form cxx#{flavor name} ImmutableSet<Flavor> cxxFlavors = CxxBuckConfig.getCxxFlavors(config); for (Flavor flavor : cxxFlavors) { CxxBuckConfig flavoredCxxBuckConfig = new CxxBuckConfig(config, flavor); CxxPlatform defaultPlatformForFlavor = CxxPlatforms.getConfigDefaultCxxPlatform( flavoredCxxBuckConfig, cxxPlatformsMap, systemDefaultCxxPlatform); cxxPlatformsBuilder.put( flavor, CxxPlatforms.copyPlatformWithFlavorAndConfig( defaultPlatformForFlavor, flavoredCxxBuckConfig, flavor)); } cxxPlatformsMap = cxxPlatformsBuilder.build(); // Build up the final list of C/C++ platforms. FlavorDomain<CxxPlatform> cxxPlatforms = new FlavorDomain<>("C/C++ platform", cxxPlatformsMap); DBuckConfig dBuckConfig = new DBuckConfig(config); ReactNativeBuckConfig reactNativeBuckConfig = new ReactNativeBuckConfig(config); RustBuckConfig rustBuckConfig = new RustBuckConfig(config); GoBuckConfig goBuckConfig = new GoBuckConfig(config, processExecutor); HalideBuckConfig halideBuckConfig = new HalideBuckConfig(config); ProGuardConfig proGuardConfig = new ProGuardConfig(config); PythonBuckConfig pyConfig = new PythonBuckConfig(config, new ExecutableFinder()); ImmutableList<PythonPlatform> pythonPlatformsList = pyConfig.getPythonPlatforms(processExecutor); ImmutableMap.Builder<Flavor, PythonPlatform> pythonPlatformsMapBuilder = ImmutableMap.builder(); for (PythonPlatform pythonPlatform : pythonPlatformsList) { pythonPlatformsMapBuilder.put(pythonPlatform.getFlavor(), pythonPlatform); } ImmutableMap<Flavor, PythonPlatform> pythonPlatformsMap = pythonPlatformsMapBuilder.build(); FlavorDomain<PythonPlatform> pythonPlatforms = new FlavorDomain<>("Python Platform", pythonPlatformsMap); PythonBinaryDescription pythonBinaryDescription = new PythonBinaryDescription(pyConfig, pythonPlatforms, 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.findAndroidSdkDirSafe()); } else { // Or just set one that blows up downloader = new ExplodingDownloader(); } Builder builder = builder(); JavaBuckConfig javaConfig = new JavaBuckConfig(config); JavacOptions defaultJavacOptions = javaConfig.getDefaultJavacOptions(); InferBuckConfig inferBuckConfig = new InferBuckConfig(config); CxxBinaryDescription cxxBinaryDescription = new CxxBinaryDescription( inferBuckConfig, defaultCxxPlatform, cxxPlatforms, cxxBuckConfig.getPreprocessMode()); CxxLibraryDescription cxxLibraryDescription = new CxxLibraryDescription( cxxBuckConfig, inferBuckConfig, cxxPlatforms, cxxBuckConfig.getPreprocessMode()); CodeSignIdentityStore codeSignIdentityStore = CodeSignIdentityStore.fromSystem(processExecutor); ProvisioningProfileStore provisioningProfileStore = ProvisioningProfileStore.fromSearchPath(appleConfig.getProvisioningProfileSearchPath()); AppleLibraryDescription appleLibraryDescription = new AppleLibraryDescription( cxxLibraryDescription, cxxPlatforms, platformFlavorsToAppleCxxPlatforms, defaultCxxPlatform, codeSignIdentityStore, provisioningProfileStore, defaultDebugInfoFormat); builder.register(appleLibraryDescription); AppleBinaryDescription appleBinaryDescription = new AppleBinaryDescription( cxxBinaryDescription, cxxPlatforms, platformFlavorsToAppleCxxPlatforms, defaultCxxPlatform, codeSignIdentityStore, provisioningProfileStore, defaultDebugInfoFormat); builder.register(appleBinaryDescription); // Create an executor service exclusively for the smart dexing step. ListeningExecutorService dxExecutorService = MoreExecutors.listeningDecorator( Executors.newFixedThreadPool( SmartDexingStep.determineOptimalThreadCount(), new CommandThreadFactory("SmartDexing"))); builder.register(new AndroidAarDescription(new AndroidManifestDescription(), ndkCxxPlatforms)); builder.register( new AndroidBinaryDescription( defaultJavacOptions, proGuardConfig, ndkCxxPlatforms, dxExecutorService)); builder.register(new AndroidBuildConfigDescription(defaultJavacOptions)); builder.register( new AndroidInstrumentationApkDescription( proGuardConfig, defaultJavacOptions, ndkCxxPlatforms, dxExecutorService)); builder.register(new AndroidInstrumentationTestDescription(defaultTestRuleTimeoutMs)); builder.register(new AndroidLibraryDescription(defaultJavacOptions)); builder.register(new AndroidManifestDescription()); builder.register(new AndroidPrebuiltAarDescription(defaultJavacOptions)); builder.register(new AndroidReactNativeLibraryDescription(reactNativeBuckConfig)); builder.register(new AndroidResourceDescription()); builder.register(new ApkGenruleDescription()); builder.register(new AppleAssetCatalogDescription()); builder.register(new ApplePackageDescription()); AppleBundleDescription appleBundleDescription = new AppleBundleDescription( appleBinaryDescription, appleLibraryDescription, cxxPlatforms, platformFlavorsToAppleCxxPlatforms, defaultCxxPlatform, codeSignIdentityStore, provisioningProfileStore, defaultDebugInfoFormat); builder.register(appleBundleDescription); builder.register(new AppleResourceDescription()); builder.register( new AppleTestDescription( appleConfig, appleBundleDescription, appleLibraryDescription, cxxPlatforms, platformFlavorsToAppleCxxPlatforms, defaultCxxPlatform, codeSignIdentityStore, provisioningProfileStore, appleConfig.getAppleDeveloperDirectorySupplier(processExecutor))); builder.register(new CoreDataModelDescription()); builder.register(new CSharpLibraryDescription()); builder.register(cxxBinaryDescription); builder.register(cxxLibraryDescription); builder.register( new CxxPythonExtensionDescription(pythonPlatforms, cxxBuckConfig, cxxPlatforms)); builder.register( new CxxTestDescription( cxxBuckConfig, defaultCxxPlatform, cxxPlatforms, defaultTestRuleTimeoutMs)); builder.register(new DBinaryDescription(dBuckConfig, defaultCxxPlatform)); builder.register(new DLibraryDescription(dBuckConfig)); builder.register( new DTestDescription(dBuckConfig, defaultTestRuleTimeoutMs, defaultCxxPlatform)); builder.register(new ExportFileDescription()); builder.register(new GenruleDescription()); builder.register(new GenAidlDescription()); builder.register(new GoBinaryDescription(goBuckConfig, defaultCxxPlatform)); builder.register(new GoLibraryDescription(goBuckConfig)); builder.register( new GoTestDescription(goBuckConfig, defaultTestRuleTimeoutMs, defaultCxxPlatform)); builder.register(new GwtBinaryDescription()); builder.register( new HalideLibraryDescription( cxxPlatforms, cxxBuckConfig.getPreprocessMode(), halideBuckConfig)); builder.register(new IosReactNativeLibraryDescription(reactNativeBuckConfig)); builder.register(new JavaBinaryDescription(defaultJavacOptions, defaultCxxPlatform)); builder.register(new JavaLibraryDescription(defaultJavacOptions)); builder.register( new JavaTestDescription( defaultJavacOptions, defaultTestRuleTimeoutMs, defaultCxxPlatform, testTempDirOverride)); builder.register(new KeystoreDescription()); builder.register(new NdkLibraryDescription(ndkVersion, ndkCxxPlatforms)); OCamlBuckConfig ocamlBuckConfig = new OCamlBuckConfig(platform, config); builder.register(new OCamlBinaryDescription(ocamlBuckConfig)); builder.register(new OCamlLibraryDescription(ocamlBuckConfig)); builder.register(new PrebuiltCxxLibraryDescription(cxxPlatforms)); 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); builder.register(new PythonLibraryDescription()); builder.register( new PythonTestDescription( pythonBinaryDescription, pyConfig, pythonPlatforms, defaultCxxPlatform, defaultTestRuleTimeoutMs, cxxPlatforms)); builder.register(new RemoteFileDescription(downloader)); builder.register( new RobolectricTestDescription( defaultJavacOptions, defaultTestRuleTimeoutMs, defaultCxxPlatform, testTempDirOverride)); builder.register(new RustBinaryDescription(rustBuckConfig)); builder.register(new RustLibraryDescription(rustBuckConfig)); builder.register(new ShBinaryDescription()); builder.register(new ShTestDescription()); ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(config); builder.register( new ThriftLibraryDescription( thriftBuckConfig, ImmutableList.of( new ThriftJavaEnhancer(thriftBuckConfig, defaultJavacOptions), new ThriftCxxEnhancer(thriftBuckConfig, cxxLibraryDescription, /* cpp2 */ false), new ThriftCxxEnhancer(thriftBuckConfig, cxxLibraryDescription, /* cpp2 */ true), new ThriftPythonEnhancer(thriftBuckConfig, ThriftPythonEnhancer.Type.NORMAL), new ThriftPythonEnhancer(thriftBuckConfig, ThriftPythonEnhancer.Type.TWISTED)))); builder.register(new XcodePostbuildScriptDescription()); builder.register(new XcodePrebuildScriptDescription()); builder.register(new XcodeWorkspaceConfigDescription()); builder.register(new ZipDescription()); builder.setCxxPlatforms(cxxPlatforms); builder.setDefaultCxxPlatform(defaultCxxPlatform); return builder; }