@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { ImmutableList.Builder<Step> steps = ImmutableList.builder(); final Path pathToNativeLibs = getPathToNativeLibsDir(); steps.add(new MakeCleanDirectoryStep(pathToNativeLibs)); final Path pathToNativeLibsAssets = getPathToNativeLibsAssetsDir(); steps.add(new MakeCleanDirectoryStep(pathToNativeLibsAssets)); for (SourcePath nativeLibDir : nativeLibDirectories.asList().reverse()) { copyNativeLibrary( getProjectFilesystem(), getResolver().getPath(nativeLibDir), pathToNativeLibs, cpuFilters, steps); } addStepsForCopyingNativeLibrariesOrAssets(filteredNativeLibraries, pathToNativeLibs, steps); addStepsForCopyingNativeLibrariesOrAssets( filteredNativeLibrariesAssets, pathToNativeLibsAssets, steps); final Path pathToMetadataTxt = getPathToMetadataTxt(); steps.add( new AbstractExecutionStep("hash_native_libs") { @Override public int execute(ExecutionContext context) { ProjectFilesystem filesystem = context.getProjectFilesystem(); ImmutableList.Builder<String> metadataLines = ImmutableList.builder(); try { for (Path nativeLib : filesystem.getFilesUnderPath(pathToNativeLibs)) { String filesha1 = filesystem.computeSha1(nativeLib); Path relativePath = pathToNativeLibs.relativize(nativeLib); metadataLines.add(String.format("%s %s", relativePath.toString(), filesha1)); } for (Path nativeLib : filesystem.getFilesUnderPath(pathToNativeLibsAssets)) { String filesha1 = filesystem.computeSha1(nativeLib); Path relativePath = pathToNativeLibsAssets.relativize(nativeLib); metadataLines.add(String.format("%s %s", relativePath.toString(), filesha1)); } filesystem.writeLinesToPath(metadataLines.build(), pathToMetadataTxt); } catch (IOException e) { context.logError(e, "There was an error hashing native libraries."); return 1; } return 0; } }); buildableContext.recordArtifact(pathToNativeLibs); buildableContext.recordArtifact(pathToNativeLibsAssets); buildableContext.recordArtifact(pathToMetadataTxt); return steps.build(); }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { buildableContext.recordArtifact(specsDir); buildableContext.recordArtifact(this.getPathToOutput()); return ImmutableList.<Step>builder() .add(new MkdirStep(getProjectFilesystem(), specsDir)) .add( new SymCopyStep( getProjectFilesystem(), FluentIterable.from(captureAndAnalyzeRules.captureRules) .transform( new Function<CxxInferCapture, Path>() { @Override public Path apply(CxxInferCapture input) { return input.getPathToOutput(); } }) .toList(), resultsDir)) .add( new AbstractExecutionStep("write_specs_path_list") { @Override public StepExecutionResult execute(ExecutionContext context) throws IOException { try { ImmutableList<String> specsDirsWithAbsolutePath = FluentIterable.from(getSpecsOfAllDeps()) .transform( new Function<SourcePath, String>() { @Override public String apply(SourcePath input) { return getResolver().getAbsolutePath(input).toString(); } }) .toList(); getProjectFilesystem().writeLinesToPath(specsDirsWithAbsolutePath, specsPathList); } catch (IOException e) { context.logError(e, "Error while writing specs path list file for the analyzer"); return StepExecutionResult.ERROR; } return StepExecutionResult.SUCCESS; } }) .add( new DefaultShellStep( getProjectFilesystem().getRootPath(), getAnalyzeCommand(), ImmutableMap.<String, String>of())) .build(); }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { ImmutableList.Builder<Step> commands = ImmutableList.builder(); commands.add(new MakeCleanDirectoryStep(getProjectFilesystem(), genPath)); BuildTarget target = getBuildTarget(); Path outputDirectory = BuildTargets.getScratchPath(target, "__%s.aidl"); commands.add(new MakeCleanDirectoryStep(getProjectFilesystem(), outputDirectory)); AidlStep command = new AidlStep( getProjectFilesystem(), target, getResolver().getAbsolutePath(aidlFilePath), ImmutableSet.of(importPath), outputDirectory); commands.add(command); // Files must ultimately be written to GEN_DIR to be used as source paths. Path genDirectory = Paths.get(BuckConstant.GEN_DIR, importPath); // Warn the user if the genDirectory is not under the output directory. if (!importPath.startsWith(target.getBasePath().toString())) { // TODO(shs96c): Make this fatal. Give people some time to clean up their rules. context .getEventBus() .post( ConsoleEvent.warning( "%s, gen_aidl import path (%s) should be a child of %s", target, importPath, target.getBasePath())); } commands.add(new MkdirStep(getProjectFilesystem(), genDirectory)); commands.add( new JarDirectoryStep( getProjectFilesystem(), output, ImmutableSortedSet.of(outputDirectory), /* main class */ null, /* manifest */ null)); buildableContext.recordArtifact(output); return commands.build(); }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { ImmutableList.Builder<Step> commands = ImmutableList.builder(); Path outputDirectory = getOutputDirectory(); Step mkdir = new MkdirStep(getProjectFilesystem(), outputDirectory); commands.add(mkdir); ImmutableSet<Path> includePaths; if (metaInfDirectory != null) { Path stagingRoot = outputDirectory.resolve("meta_inf_staging"); Path stagingTarget = stagingRoot.resolve("META-INF"); MakeCleanDirectoryStep createStagingRoot = new MakeCleanDirectoryStep(getProjectFilesystem(), stagingRoot); commands.add(createStagingRoot); MkdirAndSymlinkFileStep link = new MkdirAndSymlinkFileStep(getProjectFilesystem(), metaInfDirectory, stagingTarget); commands.add(link); includePaths = ImmutableSet.<Path>builder() .add(stagingRoot) .addAll(getTransitiveClasspathEntries().values()) .build(); } else { includePaths = ImmutableSet.copyOf(getTransitiveClasspathEntries().values()); } Path outputFile = getPathToOutput(); Path manifestPath = manifestFile == null ? null : getResolver().getPath(manifestFile); Step jar = new JarDirectoryStep( getProjectFilesystem(), outputFile, includePaths, mainClass, manifestPath, mergeManifests, blacklist); commands.add(jar); buildableContext.recordArtifact(outputFile); return commands.build(); }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { String shortName = getBuildTarget().getShortName(); buildableContext.recordArtifact(outputDir.resolve(shortName + ".h")); buildableContext.recordArtifact(outputDir.resolve(shortName + ".o")); ImmutableList.Builder<Step> commands = ImmutableList.builder(); commands.add(new MakeCleanDirectoryStep(getProjectFilesystem(), outputDir)); commands.add( new HalideCompilerStep( getProjectFilesystem().getRootPath(), halideCompiler.getCommandPrefix(getResolver()), outputDir, shortName)); return commands.build(); }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { ImmutableList.Builder<Step> steps = ImmutableList.builder(); steps.add(new MakeCleanDirectoryStep(unpackDirectory)); steps.add(new UnzipStep(aarFile.resolve(), unpackDirectory)); steps.add(new TouchStep(getProguardConfig())); steps.add(new MkdirStep(getAssetsDirectory())); // For now, we do not support an .aar file that has entries in the libs directory. // Basically, this is for simplicity because we do not know how many more prebuilt_jar rules // we would have to add at enhacement time. If this is a problem in practice, then we can // add a step that generates an uber-jar from classes.jar and the contents of the libs // directory and then have the prebuilt_jar step wrap the uber-jar instead of classes.jar. // Because there are not many .aar files in the wild, it is difficult to tell whether this // will be a pain point for developers. steps.add( new AbstractExecutionStep("check_for_libs") { @Override public int execute(ExecutionContext context) { Path libsDirectory = unpackDirectory.resolve("libs"); ProjectFilesystem projectFilesystem = context.getProjectFilesystem(); if (!projectFilesystem.exists(libsDirectory)) { return 0; } if (projectFilesystem.listFiles(libsDirectory).length > 0) { context.logError( new IllegalArgumentException(), "Error processing %s for %s. " + "Currently, Buck does not support .aar files with lib entries. " + "If this is a problem for you, please file an issue on GitHub.", aarFile, getBuildTarget()); return 1; } else { return 0; } } }); buildableContext.recordArtifactsInDirectory(unpackDirectory); return steps.build(); }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { ImmutableList.Builder<Step> steps = ImmutableList.builder(); // Setup the scratch dir. Path scratchDir = BuildTargets.getScratchPath(getProjectFilesystem(), getBuildTarget(), "%s"); steps.add(new MakeCleanDirectoryStep(getProjectFilesystem(), scratchDir)); // Setup the package DB directory. final Path packageDb = getPackageDb(); steps.add(new RmStep(getProjectFilesystem(), packageDb, true, true)); buildableContext.recordArtifact(packageDb); // Create the registration file. Path registrationFile = scratchDir.resolve("registration-file"); steps.add(getWriteRegistrationFileStep(registrationFile, packageDb)); // Build the the package DB. steps.add(new GhcPkgStep(ImmutableList.of("init", packageDb.toString()), ImmutableMap.of())); steps.add( new GhcPkgStep( ImmutableList.of( "-v0", "register", "--package-conf=" + packageDb, "--no-expand-pkgroot", registrationFile.toString()), ImmutableMap.of( "GHC_PACKAGE_PATH", Joiner.on(':') .join( FluentIterable.from(depPackages.values()) .transform( input -> getResolver() .getAbsolutePath(input.getPackageDb()) .toString()))))); return steps.build(); }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { Path outputDir = getPathToOutput(); String shortName = getBuildTarget().getShortName(); buildableContext.recordArtifact(objectOutputPath(getBuildTarget(), getProjectFilesystem())); buildableContext.recordArtifact(headerOutputPath(getBuildTarget(), getProjectFilesystem())); ImmutableList.Builder<Step> commands = ImmutableList.builder(); ProjectFilesystem projectFilesystem = getProjectFilesystem(); commands.add(new MakeCleanDirectoryStep(projectFilesystem, outputDir)); commands.add( new HalideCompilerStep( projectFilesystem.getRootPath(), halideCompiler.getEnvironment(getResolver()), halideCompiler.getCommandPrefix(getResolver()), outputDir, shortName, targetPlatform)); return commands.build(); }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, final BuildableContext buildableContext) { ImmutableList.Builder<Step> steps = ImmutableList.builder(); // Create a copy of the JAR in case it was generated by another rule. Path resolvedBinaryJar = getResolver().getAbsolutePath(binaryJar); steps.add(new MkdirStep(getProjectFilesystem(), copiedBinaryJar.getParent())); steps.add(CopyStep.forFile(getProjectFilesystem(), resolvedBinaryJar, copiedBinaryJar)); buildableContext.recordArtifact(copiedBinaryJar); // Create a step to compute the ABI key. steps.add(new MkdirStep(getProjectFilesystem(), internalAbiJar.getParent())); steps.add(new RmStep(getProjectFilesystem(), internalAbiJar, true)); steps.add( new CalculateAbiStep( buildableContext, getProjectFilesystem(), resolvedBinaryJar, internalAbiJar)); JavaLibraryRules.addAccumulateClassNamesStep(this, buildableContext, steps); return steps.build(); }
@Override public List<Step> getBuildSteps(BuildContext context, final BuildableContext buildableContext) { ImmutableList.Builder<Step> steps = ImmutableList.builder(); final Path rDotJavaSrcFolder = getRDotJavaSrcFolder(buildTarget); steps.add(new MakeCleanDirectoryStep(rDotJavaSrcFolder)); // Generate the .java files and record where they will be written in javaSourceFilePaths. Set<SourcePath> javaSourceFilePaths = Sets.newHashSet(); if (androidResourceDeps.isEmpty()) { // In this case, the user is likely running a Robolectric test that does not happen to // depend on any resources. However, if Robolectric doesn't find an R.java file, it flips // out, so we have to create one, anyway. // TODO(mbolin): Stop hardcoding com.facebook. This should match the package in the // associated TestAndroidManifest.xml file. String rDotJavaPackage = "com.facebook"; String javaCode = MergeAndroidResourcesStep.generateJavaCodeForPackageWithoutResources(rDotJavaPackage); steps.add(new MakeCleanDirectoryStep(rDotJavaSrcFolder.resolve("com/facebook"))); Path rDotJavaFile = rDotJavaSrcFolder.resolve("com/facebook/R.java"); steps.add(new WriteFileStep(javaCode, rDotJavaFile)); javaSourceFilePaths.add(new PathSourcePath(rDotJavaFile)); } else { Map<Path, String> symbolsFileToRDotJavaPackage = Maps.newHashMap(); for (HasAndroidResourceDeps res : androidResourceDeps) { String rDotJavaPackage = res.getRDotJavaPackage(); symbolsFileToRDotJavaPackage.put(res.getPathToTextSymbolsFile(), rDotJavaPackage); Path rDotJavaFilePath = MergeAndroidResourcesStep.getOutputFilePath(rDotJavaSrcFolder, rDotJavaPackage); javaSourceFilePaths.add(new PathSourcePath(rDotJavaFilePath)); } steps.add(new MergeAndroidResourcesStep(symbolsFileToRDotJavaPackage, rDotJavaSrcFolder)); } // Clear out the directory where the .class files will be generated. final Path rDotJavaClassesFolder = getRDotJavaBinFolder(); steps.add(new MakeCleanDirectoryStep(rDotJavaClassesFolder)); Path pathToAbiOutputDir = getPathToAbiOutputDir(buildTarget); steps.add(new MakeCleanDirectoryStep(pathToAbiOutputDir)); Path pathToAbiOutputFile = pathToAbiOutputDir.resolve("abi"); // Compile the .java files. final JavacStep javacStep = UberRDotJavaUtil.createJavacStepForDummyRDotJavaFiles( javaSourceFilePaths, rDotJavaClassesFolder, Optional.of(pathToAbiOutputFile), javacOptions, buildTarget); steps.add(javacStep); steps.add( new AbstractExecutionStep("record_abi_key") { @Override public int execute(ExecutionContext context) { Sha1HashCode abiKey = javacStep.getAbiKey(); Preconditions.checkNotNull( abiKey, "Javac step must create a non-null ABI key for this rule."); buildableContext.addMetadata(METADATA_KEY_FOR_ABI_KEY, abiKey.getHash()); return 0; } }); buildableContext.recordArtifactsInDirectory(rDotJavaClassesFolder); return steps.build(); }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { ImmutableList.Builder<Step> stepsBuilder = ImmutableList.builder(); Path metadataPath = getMetadataPath(); Path infoPlistInputPath = getResolver().getPath(infoPlist); Path infoPlistSubstitutionTempPath = BuildTargets.getScratchPath(getBuildTarget(), "%s.plist"); Path infoPlistOutputPath = metadataPath.resolve("Info.plist"); stepsBuilder.add( new MakeCleanDirectoryStep(bundleRoot), new MkdirStep(metadataPath), // TODO(user): This is only appropriate for .app bundles. new WriteFileStep("APPLWRUN", metadataPath.resolve("PkgInfo"), /* executable */ false), new FindAndReplaceStep( infoPlistInputPath, infoPlistSubstitutionTempPath, InfoPlistSubstitution.createVariableExpansionFunction( withDefaults( infoPlistSubstitutions, ImmutableMap.of( "EXECUTABLE_NAME", binaryName, "PRODUCT_NAME", binaryName)))), new PlistProcessStep( infoPlistSubstitutionTempPath, infoPlistOutputPath, getInfoPlistAdditionalKeys(platformName, sdkName), getInfoPlistOverrideKeys(platformName), PlistProcessStep.OutputFormat.BINARY)); if (binary.isPresent() && binary.get().getPathToOutput() != null) { stepsBuilder.add(new MkdirStep(bundleRoot.resolve(this.destinations.getExecutablesPath()))); Path bundleBinaryPath = bundleRoot.resolve(binaryPath); stepsBuilder.add(CopyStep.forFile(binary.get().getPathToOutput(), bundleBinaryPath)); stepsBuilder.add( new DsymStep( dsymutil.getCommandPrefix(getResolver()), bundleBinaryPath, bundleBinaryPath.resolveSibling( bundleBinaryPath.getFileName().toString() + ".dSYM"))); stepsBuilder.add( new DefaultShellStep( ImmutableList.<String>builder() .addAll(strip.getCommandPrefix(getResolver())) .add("-S") .add(getProjectFilesystem().resolve(bundleBinaryPath).toString()) .build())); } Path bundleDestinationPath = bundleRoot.resolve(this.destinations.getResourcesPath()); for (SourcePath dir : resourceDirs) { stepsBuilder.add(new MkdirStep(bundleDestinationPath)); stepsBuilder.add( CopyStep.forDirectory( getResolver().getPath(dir), bundleDestinationPath, CopyStep.DirectoryMode.DIRECTORY_AND_CONTENTS)); } for (SourcePath dir : dirsContainingResourceDirs) { stepsBuilder.add(new MkdirStep(bundleDestinationPath)); stepsBuilder.add( CopyStep.forDirectory( getResolver().getPath(dir), bundleDestinationPath, CopyStep.DirectoryMode.CONTENTS_ONLY)); } for (SourcePath file : resourceFiles) { stepsBuilder.add(new MkdirStep(bundleDestinationPath)); Path resolvedFilePath = getResolver().getPath(file); Path destinationPath = bundleDestinationPath.resolve(resolvedFilePath.getFileName()); addResourceProcessingSteps(resolvedFilePath, destinationPath, stepsBuilder); } addStepsToCopyExtensionBundlesDependencies(stepsBuilder); if (resourceVariantFiles.isPresent()) { for (SourcePath variantSourcePath : resourceVariantFiles.get()) { Path variantFilePath = getResolver().getPath(variantSourcePath); Path variantDirectory = variantFilePath.getParent(); if (variantDirectory == null || !variantDirectory.toString().endsWith(".lproj")) { throw new HumanReadableException( "Variant files have to be in a directory with name ending in '.lproj', " + "but '%s' is not.", variantFilePath); } Path bundleVariantDestinationPath = bundleDestinationPath.resolve(variantDirectory.getFileName()); stepsBuilder.add(new MkdirStep(bundleVariantDestinationPath)); Path destinationPath = bundleVariantDestinationPath.resolve(variantFilePath.getFileName()); addResourceProcessingSteps(variantFilePath, destinationPath, stepsBuilder); } } if (assetCatalog.isPresent()) { Path bundleDir = assetCatalog.get().getOutputDir(); stepsBuilder.add( CopyStep.forDirectory(bundleDir, bundleRoot, CopyStep.DirectoryMode.CONTENTS_ONLY)); } // Copy the .mobileprovision file if the platform requires it. if (provisioningProfiles.isPresent()) { Optional<Path> entitlementsPlist = Optional.absent(); final String srcRoot = context.getProjectRoot().resolve(getBuildTarget().getBasePath()).toString(); Optional<String> entitlementsPlistString = InfoPlistSubstitution.getVariableExpansionForPlatform( CODE_SIGN_ENTITLEMENTS, platformName, withDefaults( infoPlistSubstitutions, ImmutableMap.of( "SOURCE_ROOT", srcRoot, "SRCROOT", srcRoot))); if (entitlementsPlistString.isPresent()) { entitlementsPlist = Optional.of(Paths.get(entitlementsPlistString.get())); } final Path signingEntitlementsTempPath = BuildTargets.getScratchPath(getBuildTarget(), "%s.xcent"); stepsBuilder.add( new ProvisioningProfileCopyStep( infoPlistOutputPath, Optional.<String>absent(), // Provisioning profile UUID -- find automatically. entitlementsPlist, provisioningProfiles.get(), bundleDestinationPath.resolve("embedded.mobileprovision"), signingEntitlementsTempPath)); stepsBuilder.add( new CodeSignStep( bundleDestinationPath, signingEntitlementsTempPath, codeSignIdentity.get().getHash())); } // Ensure the bundle directory is archived so we can fetch it later. buildableContext.recordArtifact(getPathToOutput()); return stepsBuilder.build(); }