@Test public void depfileBasedRuleKeyRebuildsAfterChangeToUsedHeaderUsingFileRelativeInclusion() throws Exception { CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new CxxBuckConfig(FakeBuckConfig.builder().build())); BuildTarget target = BuildTargetFactory.newInstance("//:binary_with_used_relative_header"); String usedHeaderName = "source_relative_header.h"; String sourceName = "source_relative_header.cpp"; BuildTarget preprocessTarget = getPreprocessTarget(cxxPlatform, target, sourceName, AbstractCxxSource.Type.CXX); // Run the build and verify that the C++ source was preprocessed. workspace.runBuckBuild("--config", "build.depfiles=true", target.toString()).assertSuccess(); BuckBuildLog.BuildLogEntry firstRunEntry = workspace.getBuildLog().getLogEntry(preprocessTarget); assertThat( firstRunEntry.getSuccessType(), equalTo(Optional.of(BuildRuleSuccessType.BUILT_LOCALLY))); // Modify the used header. workspace.writeContentsToPath("static inline int newFunction() { return 20; }", usedHeaderName); // Run the build again and verify that we recompiled as the header caused the depfile rule key // to change. workspace.runBuckBuild("--config", "build.depfiles=true", target.toString()).assertSuccess(); BuckBuildLog.BuildLogEntry secondRunEntry = workspace.getBuildLog().getLogEntry(preprocessTarget); assertThat( secondRunEntry.getSuccessType(), equalTo(Optional.of(BuildRuleSuccessType.BUILT_LOCALLY))); // Also, make sure all three rule keys are actually different. assertThat(secondRunEntry.getRuleKey(), Matchers.not(equalTo(firstRunEntry.getRuleKey()))); }
@Test public void depfileBasedRuleKeyAvoidsRecompilingAfterChangeToUnusedHeader() throws Exception { CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new CxxBuckConfig(FakeBuckConfig.builder().build())); BuildTarget target = BuildTargetFactory.newInstance("//:binary_with_unused_header"); String unusedHeaderName = "unused_header.h"; String sourceName = "source.cpp"; BuildTarget preprocessTarget = getPreprocessTarget(cxxPlatform, target, sourceName, AbstractCxxSource.Type.CXX); // Run the build and verify that the C++ source was preprocessed. workspace.runBuckBuild("--config", "build.depfiles=true", target.toString()).assertSuccess(); BuckBuildLog.BuildLogEntry firstRunEntry = workspace.getBuildLog().getLogEntry(preprocessTarget); assertThat( firstRunEntry.getSuccessType(), equalTo(Optional.of(BuildRuleSuccessType.BUILT_LOCALLY))); // Now modify the unused header. workspace.writeContentsToPath( "static inline int newFunction() { return 20; }", unusedHeaderName); // Run the build again and verify that got a matching depfile rule key, and therefore // didn't recompile. workspace.runBuckBuild("--config", "build.depfiles=true", target.toString()).assertSuccess(); BuckBuildLog.BuildLogEntry secondRunEntry = workspace.getBuildLog().getLogEntry(preprocessTarget); assertThat( secondRunEntry.getSuccessType(), equalTo(Optional.of(BuildRuleSuccessType.MATCHING_DEP_FILE_RULE_KEY))); // Also, make sure the original rule keys are actually different. assertThat(secondRunEntry.getRuleKey(), Matchers.not(equalTo(firstRunEntry.getRuleKey()))); }
@Test public void inputBasedRuleKeyAvoidsRecompilingAfterChangeToUnusedHeader() throws Exception { // This test is only meant to check the separate flow, as we want to avoid recompiling if only // unused headers have changed. assumeTrue("only tests \"separate\" preprocess mode", mode == CxxPreprocessMode.SEPARATE); CxxPlatform cxxPlatform = DefaultCxxPlatforms.build(new CxxBuckConfig(FakeBuckConfig.builder().build())); BuildTarget target = BuildTargetFactory.newInstance("//:binary_with_unused_header"); CxxSourceRuleFactory cxxSourceRuleFactory = CxxSourceRuleFactoryHelper.of(workspace.getDestPath(), target, cxxPlatform); String unusedHeaderName = "unused_header.h"; String sourceName = "source.cpp"; BuildTarget compileTarget = cxxSourceRuleFactory.createCompileBuildTarget(sourceName, CxxSourceRuleFactory.PicType.PDC); // Run the build and verify that the C++ source was compiled. workspace.runBuckBuild(target.toString()); BuckBuildLog.BuildLogEntry firstRunEntry = workspace.getBuildLog().getLogEntry(compileTarget); assertThat( firstRunEntry.getSuccessType(), equalTo(Optional.of(BuildRuleSuccessType.BUILT_LOCALLY))); // Now modify the unused header. workspace.writeContentsToPath( "static inline int newFunction() { return 20; }", unusedHeaderName); // Run the build again and verify that got a matching input-based rule key, and therefore // didn't recompile. workspace.runBuckBuild(target.toString()); BuckBuildLog.BuildLogEntry secondRunEntry = workspace.getBuildLog().getLogEntry(compileTarget); assertThat( secondRunEntry.getSuccessType(), equalTo(Optional.of(BuildRuleSuccessType.MATCHING_INPUT_BASED_RULE_KEY))); // Also, make sure the original rule keys are actually different. assertThat(secondRunEntry.getRuleKey(), Matchers.not(equalTo(firstRunEntry.getRuleKey()))); }