use of com.facebook.buck.io.ProjectFilesystem in project buck by facebook.
the class ArchiveStepIntegrationTest method thinArchives.
@Test
public void thinArchives() throws IOException, InterruptedException {
assumeTrue(Platform.detect() == Platform.MACOS || Platform.detect() == Platform.LINUX);
ProjectFilesystem filesystem = new ProjectFilesystem(tmp.getRoot());
CxxPlatform platform = CxxPlatformUtils.build(new CxxBuckConfig(FakeBuckConfig.builder().build()));
assumeTrue(platform.getAr().supportsThinArchives());
// Build up the paths to various files the archive step will use.
SourcePathResolver sourcePathResolver = new SourcePathResolver(new SourcePathRuleFinder(new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer())));
Archiver archiver = platform.getAr();
Path output = filesystem.getPath("foo/libthin.a");
filesystem.mkdirs(output.getParent());
// Create a really large input file so it's obvious that the archive is thin.
Path input = filesystem.getPath("bar/blah.dat");
filesystem.mkdirs(input.getParent());
byte[] largeInputFile = new byte[1024 * 1024];
byte[] fillerToRepeat = "hello\n".getBytes(StandardCharsets.UTF_8);
for (int i = 0; i < largeInputFile.length; i++) {
largeInputFile[i] = fillerToRepeat[i % fillerToRepeat.length];
}
filesystem.writeBytesToPath(largeInputFile, input);
// Build an archive step.
ArchiveStep archiveStep = new ArchiveStep(filesystem, archiver.getEnvironment(sourcePathResolver), archiver.getCommandPrefix(sourcePathResolver), ImmutableList.of(), getArchiveOptions(true), output, ImmutableList.of(input), archiver);
// Execute the archive step and verify it ran successfully.
ExecutionContext executionContext = TestExecutionContext.newInstance();
TestConsole console = (TestConsole) executionContext.getConsole();
int exitCode = archiveStep.execute(executionContext).getExitCode();
assertEquals("archive step failed: " + console.getTextWrittenToStdErr(), 0, exitCode);
// Verify that the thin header is present.
assertThat(filesystem.readFirstLine(output), Matchers.equalTo(Optional.of("!<thin>")));
// Verify that even though the archived contents is really big, the archive is still small.
assertThat(filesystem.getFileSize(output), Matchers.lessThan(1000L));
// can parse the archive contents.
try (OutputStream outputStream = Files.newOutputStream(filesystem.resolve(output), StandardOpenOption.WRITE)) {
outputStream.write(ObjectFileScrubbers.GLOBAL_HEADER);
}
// zero'd out.
try (ArArchiveInputStream stream = new ArArchiveInputStream(new FileInputStream(filesystem.resolve(output).toFile()))) {
ArArchiveEntry entry = stream.getNextArEntry();
// Verify that the input names are relative paths from the outputs parent dir.
assertThat(entry.getName(), Matchers.equalTo(output.getParent().relativize(input).toString()));
}
}
use of com.facebook.buck.io.ProjectFilesystem in project buck by facebook.
the class ArchiveStepIntegrationTest method thatGeneratedArchivesAreDeterministic.
@Test
@SuppressWarnings("PMD.AvoidUsingOctalValues")
public void thatGeneratedArchivesAreDeterministic() throws IOException, InterruptedException {
assumeTrue(Platform.detect() == Platform.MACOS || Platform.detect() == Platform.LINUX);
ProjectFilesystem filesystem = new ProjectFilesystem(tmp.getRoot());
CxxPlatform platform = CxxPlatformUtils.build(new CxxBuckConfig(FakeBuckConfig.builder().build()));
// Build up the paths to various files the archive step will use.
SourcePathResolver sourcePathResolver = new SourcePathResolver(new SourcePathRuleFinder(new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer())));
Archiver archiver = platform.getAr();
Path output = filesystem.getPath("output.a");
Path input = filesystem.getPath("input.dat");
filesystem.writeContentsToPath("blah", input);
Preconditions.checkState(filesystem.resolve(input).toFile().setExecutable(true));
// Build an archive step.
ArchiveStep archiveStep = new ArchiveStep(filesystem, archiver.getEnvironment(sourcePathResolver), archiver.getCommandPrefix(sourcePathResolver), ImmutableList.of(), getArchiveOptions(false), output, ImmutableList.of(input), archiver);
FileScrubberStep fileScrubberStep = new FileScrubberStep(filesystem, output, platform.getAr().getScrubbers());
// Execute the archive step and verify it ran successfully.
ExecutionContext executionContext = TestExecutionContext.newInstance();
TestConsole console = (TestConsole) executionContext.getConsole();
int exitCode = archiveStep.execute(executionContext).getExitCode();
assertEquals("archive step failed: " + console.getTextWrittenToStdErr(), 0, exitCode);
exitCode = fileScrubberStep.execute(executionContext).getExitCode();
assertEquals("archive scrub step failed: " + console.getTextWrittenToStdErr(), 0, exitCode);
// zero'd out.
try (ArArchiveInputStream stream = new ArArchiveInputStream(new FileInputStream(filesystem.resolve(output).toFile()))) {
ArArchiveEntry entry = stream.getNextArEntry();
assertEquals(ObjectFileCommonModificationDate.COMMON_MODIFICATION_TIME_STAMP, entry.getLastModified());
assertEquals(0, entry.getUserId());
assertEquals(0, entry.getGroupId());
assertEquals(String.format("0%o", entry.getMode()), 0100644, entry.getMode());
}
}
use of com.facebook.buck.io.ProjectFilesystem in project buck by facebook.
the class CxxBinaryIntegrationTest method testInferCxxBinaryWithDiamondDepsEmitsAllBuildRulesInvolvedWhenCacheHit.
@Test
public void testInferCxxBinaryWithDiamondDepsEmitsAllBuildRulesInvolvedWhenCacheHit() throws IOException {
assumeTrue(Platform.detect() != Platform.WINDOWS);
ProjectWorkspace workspace = InferHelper.setupCxxInferWorkspace(this, tmp, Optional.empty());
workspace.enableDirCache();
workspace.setupCxxSandboxing(sandboxSources);
ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath());
BuildTarget inputBuildTarget = BuildTargetFactory.newInstance("//foo:binary_with_diamond_deps").withFlavors(CxxInferEnhancer.InferFlavors.INFER.get());
String buildTargetName = inputBuildTarget.getFullyQualifiedName();
/*
* Build the given target and check that it succeeds.
*/
workspace.runBuckCommand("build", buildTargetName).assertSuccess();
/*
* Check that building after clean will use the cache
*/
workspace.runBuckCommand("clean").assertSuccess();
workspace.runBuckCommand("build", buildTargetName).assertSuccess();
BuckBuildLog buildLog = workspace.getBuildLog();
ImmutableSet<BuildTarget> allInvolvedTargets = buildLog.getAllTargets();
// Only main target should be fetched from cache
assertEquals(1, allInvolvedTargets.size());
for (BuildTarget bt : allInvolvedTargets) {
buildLog.assertTargetWasFetchedFromCache(bt.toString());
}
assertTrue(Files.exists(workspace.getPath(BuildTargets.getGenPath(filesystem, inputBuildTarget, "infer-%s/infer-deps.txt"))));
String loggedDeps = workspace.getFileContents(BuildTargets.getGenPath(filesystem, inputBuildTarget, "infer-%s/infer-deps.txt"));
BuildTarget analyzeMainTarget = BuildTargetFactory.newInstance("//foo:binary_with_diamond_deps#infer-analyze");
BuildTarget analyzeDepOneTarget = BuildTargetFactory.newInstance("//foo:diamond_dep_one#default,infer-analyze");
BuildTarget analyzeDepTwoTarget = BuildTargetFactory.newInstance("//foo:diamond_dep_two#default,infer-analyze");
BuildTarget analyzeSimpleLibTarget = BuildTargetFactory.newInstance("//foo:simple_lib#default,infer-analyze");
String sanitizedSimpleCpp = sanitize("simple.cpp.o");
String sanitizedDepOne = sanitize("dep_one.c.o");
String sanitizedDepTwo = sanitize("dep_two.c.o");
String sanitizedSrcWithDeps = sanitize("src_with_deps.c.o");
BuildTarget simpleCppTarget = BuildTargetFactory.newInstance("//foo:simple_lib#default,infer-capture-" + sanitizedSimpleCpp);
BuildTarget depOneTarget = BuildTargetFactory.newInstance("//foo:diamond_dep_one#default,infer-capture-" + sanitizedDepOne);
BuildTarget depTwoTarget = BuildTargetFactory.newInstance("//foo:diamond_dep_two#default,infer-capture-" + sanitizedDepTwo);
BuildTarget srcWithDepsTarget = BuildTargetFactory.newInstance("//foo:binary_with_diamond_deps#default,infer-capture-" + sanitizedSrcWithDeps);
Path basePath = filesystem.getRootPath().toRealPath();
String expectedOutput = Joiner.on('\n').join(ImmutableList.of(InferLogLine.fromBuildTarget(analyzeMainTarget, basePath.resolve(BuildTargets.getGenPath(filesystem, analyzeMainTarget, "infer-analysis-%s"))).toString(), InferLogLine.fromBuildTarget(srcWithDepsTarget, basePath.resolve(BuildTargets.getGenPath(filesystem, srcWithDepsTarget, "infer-out-%s"))).toString(), InferLogLine.fromBuildTarget(analyzeDepOneTarget, basePath.resolve(BuildTargets.getGenPath(filesystem, analyzeDepOneTarget, "infer-analysis-%s"))).toString(), InferLogLine.fromBuildTarget(depOneTarget, basePath.resolve(BuildTargets.getGenPath(filesystem, depOneTarget, "infer-out-%s"))).toString(), InferLogLine.fromBuildTarget(analyzeDepTwoTarget, basePath.resolve(BuildTargets.getGenPath(filesystem, analyzeDepTwoTarget, "infer-analysis-%s"))).toString(), InferLogLine.fromBuildTarget(depTwoTarget, basePath.resolve(BuildTargets.getGenPath(filesystem, depTwoTarget, "infer-out-%s"))).toString(), InferLogLine.fromBuildTarget(analyzeSimpleLibTarget, basePath.resolve(BuildTargets.getGenPath(filesystem, analyzeSimpleLibTarget, "infer-analysis-%s"))).toString(), InferLogLine.fromBuildTarget(simpleCppTarget, basePath.resolve(BuildTargets.getGenPath(filesystem, simpleCppTarget, "infer-out-%s"))).toString()));
assertEquals(expectedOutput + "\n", loggedDeps);
}
use of com.facebook.buck.io.ProjectFilesystem in project buck by facebook.
the class CxxBinaryIntegrationTest method testChangingCompilerPathForcesRebuild.
@Test
public void testChangingCompilerPathForcesRebuild() throws Exception {
assumeTrue(Platform.detect() != Platform.WINDOWS);
ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "simple", tmp);
workspace.setUp();
workspace.enableDirCache();
workspace.setupCxxSandboxing(sandboxSources);
ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath());
BuildTarget target = BuildTargetFactory.newInstance("//foo:simple");
BuildTarget linkTarget = CxxDescriptionEnhancer.createCxxLinkTarget(target, Optional.empty());
// Get the real location of the compiler executable.
String executable = Platform.detect() == Platform.MACOS ? "clang++" : "g++";
Path executableLocation = new ExecutableFinder().getOptionalExecutable(Paths.get(executable), ImmutableMap.copyOf(System.getenv())).orElse(Paths.get("/usr/bin", executable));
// Write script as faux clang++/g++ binary
Path firstCompilerPath = tmp.newFolder("path1");
Path firstCompiler = firstCompilerPath.resolve(executable);
filesystem.writeContentsToPath("#!/bin/sh\n" + "exec " + executableLocation.toString() + " \"$@\"\n", firstCompiler);
// Write script as slightly different faux clang++/g++ binary
Path secondCompilerPath = tmp.newFolder("path2");
Path secondCompiler = secondCompilerPath.resolve(executable);
filesystem.writeContentsToPath("#!/bin/sh\n" + "exec " + executableLocation.toString() + " \"$@\"\n" + "# Comment to make hash different.\n", secondCompiler);
// Make the second faux clang++/g++ binary executable
MoreFiles.makeExecutable(secondCompiler);
// Run two builds, each with different compiler "binaries". In the first
// instance, both binaries are in the PATH but the first binary is not
// marked executable so is not picked up.
workspace.runBuckCommandWithEnvironmentOverridesAndContext(workspace.getDestPath(), Optional.empty(), ImmutableMap.of("PATH", firstCompilerPath.toString() + pathSeparator + secondCompilerPath.toString() + pathSeparator + System.getenv("PATH")), "build", target.getFullyQualifiedName()).assertSuccess();
workspace.resetBuildLogFile();
// Now, make the first faux clang++/g++ binary executable. In this second
// instance, both binaries are still in the PATH but the first binary is
// now marked executable and so is picked up; causing a rebuild.
MoreFiles.makeExecutable(firstCompiler);
workspace.runBuckCommandWithEnvironmentOverridesAndContext(workspace.getDestPath(), Optional.empty(), ImmutableMap.of("PATH", firstCompilerPath.toString() + pathSeparator + secondCompilerPath.toString() + pathSeparator + System.getenv("PATH")), "build", target.getFullyQualifiedName()).assertSuccess();
// Make sure the binary change caused a rebuild.
workspace.getBuildLog().assertTargetBuiltLocally(linkTarget.toString());
}
use of com.facebook.buck.io.ProjectFilesystem in project buck by facebook.
the class CxxBinaryIntegrationTest method testStrippedBinaryProducesBothUnstrippedAndStrippedOutputs.
@Test
public void testStrippedBinaryProducesBothUnstrippedAndStrippedOutputs() throws IOException, InterruptedException {
assumeTrue(Platform.detect() == Platform.MACOS);
BuildTarget unstrippedTarget = BuildTargetFactory.newInstance("//:test");
BuildTarget strippedTarget = unstrippedTarget.withAppendedFlavors(StripStyle.DEBUGGING_SYMBOLS.getFlavor());
ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "header_namespace", tmp);
workspace.setUp();
workspace.setupCxxSandboxing(sandboxSources);
ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath());
workspace.runBuckCommand("build", "--config", "cxx.cxxflags=-g", strippedTarget.getFullyQualifiedName()).assertSuccess();
Path strippedPath = workspace.getPath(BuildTargets.getGenPath(filesystem, strippedTarget.withAppendedFlavors(CxxStrip.RULE_FLAVOR), "%s"));
Path unstrippedPath = workspace.getPath(BuildTargets.getGenPath(filesystem, unstrippedTarget, "%s"));
String strippedOut = workspace.runCommand("dsymutil", "-s", strippedPath.toString()).getStdout().orElse("");
String unstrippedOut = workspace.runCommand("dsymutil", "-s", unstrippedPath.toString()).getStdout().orElse("");
assertThat(strippedOut, Matchers.containsStringIgnoringCase("dyld_stub_binder"));
assertThat(unstrippedOut, Matchers.containsStringIgnoringCase("dyld_stub_binder"));
assertThat(strippedOut, Matchers.not(Matchers.containsStringIgnoringCase("test.cpp")));
assertThat(unstrippedOut, Matchers.containsStringIgnoringCase("test.cpp"));
}
Aggregations