private ImmutableList<com.facebook.buck.rules.args.Arg> getExtensionArgs( BuildRuleParams params, BuildRuleResolver ruleResolver, SourcePathResolver pathResolver, CxxPlatform cxxPlatform, Arg args) throws NoSuchBuildTargetException { // Extract all C/C++ sources from the constructor arg. ImmutableMap<String, CxxSource> srcs = CxxDescriptionEnhancer.parseCxxSources( params.getBuildTarget(), pathResolver, cxxPlatform, args); ImmutableMap<Path, SourcePath> headers = CxxDescriptionEnhancer.parseHeaders( params.getBuildTarget(), pathResolver, Optional.of(cxxPlatform), args); // Setup the header symlink tree and combine all the preprocessor input from this rule // and all dependencies. HeaderSymlinkTree headerSymlinkTree = CxxDescriptionEnhancer.requireHeaderSymlinkTree( params, ruleResolver, new SourcePathResolver(ruleResolver), cxxPlatform, headers, HeaderVisibility.PRIVATE); ImmutableList<CxxPreprocessorInput> cxxPreprocessorInput = CxxDescriptionEnhancer.collectCxxPreprocessorInput( params, cxxPlatform, CxxFlags.getLanguageFlags( args.preprocessorFlags, args.platformPreprocessorFlags, args.langPreprocessorFlags, cxxPlatform), ImmutableList.of(headerSymlinkTree), ImmutableSet.<FrameworkPath>of(), CxxPreprocessables.getTransitiveCxxPreprocessorInput(cxxPlatform, params.getDeps())); // Generate rule to build the object files. ImmutableMap<CxxPreprocessAndCompile, SourcePath> picObjects = CxxSourceRuleFactory.requirePreprocessAndCompileRules( params, ruleResolver, pathResolver, cxxBuckConfig, cxxPlatform, cxxPreprocessorInput, CxxFlags.getLanguageFlags( args.compilerFlags, args.platformCompilerFlags, args.langCompilerFlags, cxxPlatform), args.prefixHeader, cxxBuckConfig.getPreprocessMode(), srcs, CxxSourceRuleFactory.PicType.PIC); ImmutableList.Builder<com.facebook.buck.rules.args.Arg> argsBuilder = ImmutableList.builder(); argsBuilder.addAll( StringArg.from(CxxFlags.getFlags(args.linkerFlags, args.platformLinkerFlags, cxxPlatform))); // Embed a origin-relative library path into the binary so it can find the shared libraries. argsBuilder.addAll( StringArg.from( Linkers.iXlinker( "-rpath", String.format("%s/", cxxPlatform.getLd().resolve(ruleResolver).libOrigin())))); // Add object files into the args. argsBuilder.addAll(SourcePathArg.from(pathResolver, picObjects.values())); return argsBuilder.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; }