@Test public void testSimpleCxxBinaryWithHeader() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "simple", tmp); workspace.setUp(); CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new CxxBuckConfig(new FakeBuckConfig())); BuildTarget target = BuildTargetFactory.newInstance("//foo:simple_with_header"); CxxSourceRuleFactory cxxSourceRuleFactory = CxxSourceRuleFactoryHelper.of(target, cxxPlatform); BuildTarget binaryTarget = CxxDescriptionEnhancer.createCxxLinkTarget(target); String sourceName = "simple_with_header.cpp"; String headerName = "simple_with_header.h"; String headerFull = "foo/" + headerName; BuildTarget preprocessTarget = cxxSourceRuleFactory.createPreprocessBuildTarget( sourceName, CxxSource.Type.CXX, CxxSourceRuleFactory.PicType.PDC); BuildTarget compileTarget = cxxSourceRuleFactory.createCompileBuildTarget(sourceName, CxxSourceRuleFactory.PicType.PDC); BuildTarget headerSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( target, cxxPlatform.getFlavor(), HeaderVisibility.PRIVATE); // Do a clean build, verify that it succeeds, and check that all expected targets built // successfully. workspace.runBuckCommand("build", target.toString()).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); assertEquals( ImmutableSet.of( headerSymlinkTreeTarget, preprocessTarget, compileTarget, binaryTarget, target), buildLog.getAllTargets()); buildLog.assertTargetBuiltLocally(headerSymlinkTreeTarget.toString()); buildLog.assertTargetBuiltLocally(preprocessTarget.toString()); buildLog.assertTargetBuiltLocally(compileTarget.toString()); buildLog.assertTargetBuiltLocally(binaryTarget.toString()); buildLog.assertTargetBuiltLocally(target.toString()); // Clear for new build. workspace.resetBuildLogFile(); // Update the source file. workspace.replaceFileContents(headerFull, "blah = 5", "blah = 6"); // Check that running a build again makes the source get recompiled and the binary // re-linked, but does not cause the header rules to re-run. workspace.runBuckCommand("build", target.toString()).assertSuccess(); buildLog = workspace.getBuildLog(); assertEquals( ImmutableSet.of( headerSymlinkTreeTarget, preprocessTarget, compileTarget, binaryTarget, target), buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(headerSymlinkTreeTarget.toString()); buildLog.assertTargetBuiltLocally(preprocessTarget.toString()); buildLog.assertTargetBuiltLocally(compileTarget.toString()); assertThat( buildLog.getLogEntry(binaryTarget).getSuccessType().get(), Matchers.not(Matchers.equalTo(BuildRuleSuccessType.MATCHING_RULE_KEY))); buildLog.assertTargetBuiltLocally(target.toString()); }
public void doTestSimpleCxxBinaryBuilds(String preprocessMode, boolean expectPreprocessorOutput) throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "simple", tmp); workspace.setUp(); workspace.writeContentsToPath( String.format("[cxx]\npreprocess_mode = %s\n", preprocessMode), ".buckconfig"); CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new CxxBuckConfig(new FakeBuckConfig())); BuildTarget target = BuildTargetFactory.newInstance("//foo:simple"); CxxSourceRuleFactory cxxSourceRuleFactory = CxxSourceRuleFactoryHelper.of(target, cxxPlatform); BuildTarget binaryTarget = CxxDescriptionEnhancer.createCxxLinkTarget(target); String sourceName = "simple.cpp"; String sourceFull = "foo/" + sourceName; BuildTarget preprocessTarget = cxxSourceRuleFactory.createPreprocessBuildTarget( sourceName, CxxSource.Type.CXX, CxxSourceRuleFactory.PicType.PDC); BuildTarget compileTarget = cxxSourceRuleFactory.createCompileBuildTarget(sourceName, CxxSourceRuleFactory.PicType.PDC); BuildTarget headerSymlinkTreeTarget = CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( target, cxxPlatform.getFlavor(), HeaderVisibility.PRIVATE); // Do a clean build, verify that it succeeds, and check that all expected targets built // successfully. workspace.runBuckCommand("build", target.toString()).assertSuccess(); BuckBuildLog buildLog = workspace.getBuildLog(); ImmutableSet<BuildTarget> expectedTargets = ImmutableSet.<BuildTarget>builder() .addAll(ImmutableSet.of(headerSymlinkTreeTarget, compileTarget, binaryTarget, target)) .addAll( (expectPreprocessorOutput ? ImmutableSet.of(preprocessTarget) : ImmutableSet.<BuildTarget>of())) .build(); assertEquals(expectedTargets, buildLog.getAllTargets()); buildLog.assertTargetBuiltLocally(headerSymlinkTreeTarget.toString()); if (expectPreprocessorOutput) { buildLog.assertTargetBuiltLocally(preprocessTarget.toString()); } buildLog.assertTargetBuiltLocally(compileTarget.toString()); buildLog.assertTargetBuiltLocally(binaryTarget.toString()); buildLog.assertTargetBuiltLocally(target.toString()); // Clear for new build. workspace.resetBuildLogFile(); // Check that running a build again results in no builds since everything is up to // date. workspace.runBuckCommand("build", target.toString()).assertSuccess(); buildLog = workspace.getBuildLog(); assertEquals(ImmutableSet.of(target, binaryTarget), buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(binaryTarget.toString()); buildLog.assertTargetHadMatchingRuleKey(target.toString()); // Clear for new build. workspace.resetBuildLogFile(); // Update the source file. workspace.replaceFileContents(sourceFull, "{}", "{ return 0; }"); // Check that running a build again makes the source get recompiled and the binary // re-linked, but does not cause the header rules to re-run. workspace.runBuckCommand("build", target.toString()).assertSuccess(); buildLog = workspace.getBuildLog(); assertEquals(expectedTargets, buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(headerSymlinkTreeTarget.toString()); if (expectPreprocessorOutput) { buildLog.assertTargetBuiltLocally(preprocessTarget.toString()); } buildLog.assertTargetBuiltLocally(compileTarget.toString()); assertThat( buildLog.getLogEntry(binaryTarget).getSuccessType().get(), Matchers.not(Matchers.equalTo(BuildRuleSuccessType.MATCHING_RULE_KEY))); buildLog.assertTargetBuiltLocally(target.toString()); // Clear for new build. workspace.resetBuildLogFile(); // Update the source file. workspace.replaceFileContents(sourceFull, "{ return 0; }", "won't compile"); // Check that running a build again makes the source get recompiled and the binary // re-linked, but does not cause the header rules to re-run. workspace.runBuckCommand("build", target.toString()).assertFailure(); buildLog = workspace.getBuildLog(); assertEquals(expectedTargets, buildLog.getAllTargets()); buildLog.assertTargetHadMatchingRuleKey(headerSymlinkTreeTarget.toString()); if (expectPreprocessorOutput) { buildLog.assertTargetBuiltLocally(preprocessTarget.toString()); } assertThat( buildLog.getLogEntry(binaryTarget).getStatus(), Matchers.equalTo(BuildRuleStatus.CANCELED)); assertThat( buildLog.getLogEntry(target).getStatus(), Matchers.equalTo(BuildRuleStatus.CANCELED)); }