public static Downloader createFromConfig(BuckConfig config, Optional<Path> androidSdkRoot) { ImmutableList.Builder<Downloader> downloaders = ImmutableList.builder(); DownloadConfig downloadConfig = new DownloadConfig(config); Optional<Proxy> proxy = downloadConfig.getProxy(); for (String repo : downloadConfig.getAllMavenRepos()) { // Check the type. if (repo.startsWith("http:") || repo.startsWith("https://")) { downloaders.add(new RemoteMavenDownloader(proxy, repo)); } else if (repo.startsWith("file:")) { try { URL url = new URL(repo); Preconditions.checkNotNull(url.getPath()); downloaders.add( new OnDiskMavenDownloader( config.resolvePathThatMayBeOutsideTheProjectFilesystem( Paths.get(url.getPath())))); } catch (FileNotFoundException e) { throw new HumanReadableException( e, "Error occurred when attempting to use %s " + "as a local Maven repository as configured in .buckconfig. See " + "https://buckbuild.com/concept/buckconfig.html#maven_repositories for how to " + "configure this setting", repo); } catch (MalformedURLException e) { throw new HumanReadableException("Unable to determine path from %s", repo); } } else { try { downloaders.add( new OnDiskMavenDownloader( config.resolvePathThatMayBeOutsideTheProjectFilesystem(Paths.get(repo)))); } catch (FileNotFoundException e) { throw new HumanReadableException( e, "Error occurred when attempting to use %s " + "as a local Maven repository as configured in .buckconfig. See " + "https://buckbuild.com/concept/buckconfig.html#maven_repositories for how to " + "configure this setting", repo); } } } if (androidSdkRoot.isPresent()) { Path androidMavenRepo = androidSdkRoot.get().resolve("extras/android/m2repository"); try { downloaders.add(new OnDiskMavenDownloader(androidMavenRepo)); } catch (FileNotFoundException e) { LOG.warn("Android Maven repo %s doesn't exist", androidMavenRepo.toString()); } Path googleMavenRepo = androidSdkRoot.get().resolve("extras/google/m2repository"); try { downloaders.add(new OnDiskMavenDownloader(googleMavenRepo)); } catch (FileNotFoundException e) { LOG.warn("Google Maven repo '%s' doesn't exist", googleMavenRepo.toString()); } } // Add a default downloader // TODO(shs96c): Remove the maven_repo check Optional<String> defaultMavenRepo = downloadConfig.getMavenRepo(); if (defaultMavenRepo.isPresent()) { LOG.warn( "Please configure maven repos by adding them to a 'maven_repositories' " + "section in your buckconfig"); } downloaders.add(new HttpDownloader(proxy)); return new StackedDownloader(downloaders.build()); }
@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; }