in src/com/facebook/buck/cxx/CxxTestDescription.java [155:339]
public BuildRule createBuildRule(
BuildRuleCreationContextWithTargetGraph context,
BuildTarget inputBuildTarget,
BuildRuleParams params,
CxxTestDescriptionArg args) {
Optional<StripStyle> flavoredStripStyle = StripStyle.FLAVOR_DOMAIN.getValue(inputBuildTarget);
Optional<LinkerMapMode> flavoredLinkerMapMode =
LinkerMapMode.FLAVOR_DOMAIN.getValue(inputBuildTarget);
inputBuildTarget =
CxxStrip.removeStripStyleFlavorInTarget(inputBuildTarget, flavoredStripStyle);
inputBuildTarget =
LinkerMapMode.removeLinkerMapModeFlavorInTarget(inputBuildTarget, flavoredLinkerMapMode);
BuildTarget buildTarget = inputBuildTarget;
ActionGraphBuilder graphBuilder = context.getActionGraphBuilder();
args.checkDuplicateSources(graphBuilder.getSourcePathResolver());
CxxPlatform cxxPlatform =
getCxxPlatform(buildTarget, args)
.resolve(graphBuilder, buildTarget.getTargetConfiguration());
ProjectFilesystem projectFilesystem = context.getProjectFilesystem();
CellPathResolver cellRoots = context.getCellPathResolver();
if (buildTarget.getFlavors().contains(CxxCompilationDatabase.COMPILATION_DATABASE)) {
CxxLinkAndCompileRules cxxLinkAndCompileRules =
CxxDescriptionEnhancer.createBuildRulesForCxxBinaryDescriptionArg(
context.getTargetGraph(),
buildTarget.withoutFlavors(CxxCompilationDatabase.COMPILATION_DATABASE),
projectFilesystem,
graphBuilder,
cellRoots,
cxxBuckConfig,
cxxPlatform,
args,
getImplicitFrameworkDeps(buildTarget.getTargetConfiguration(), args),
flavoredStripStyle,
flavoredLinkerMapMode);
return CxxCompilationDatabase.createCompilationDatabase(
buildTarget, projectFilesystem, cxxLinkAndCompileRules.compileRules);
}
if (buildTarget.getFlavors().contains(CxxCompilationDatabase.UBER_COMPILATION_DATABASE)) {
return CxxDescriptionEnhancer.createUberCompilationDatabase(
getCxxPlatformsProvider(buildTarget.getTargetConfiguration())
.getUnresolvedCxxPlatforms()
.getValue(buildTarget)
.isPresent()
? buildTarget
: buildTarget.withAppendedFlavors(cxxPlatform.getFlavor()),
projectFilesystem,
graphBuilder);
}
// Generate the link rule that builds the test binary.
CxxLinkAndCompileRules cxxLinkAndCompileRules =
CxxDescriptionEnhancer.createBuildRulesForCxxBinaryDescriptionArg(
context.getTargetGraph(),
buildTarget,
projectFilesystem,
graphBuilder,
cellRoots,
cxxBuckConfig,
cxxPlatform,
args,
getImplicitFrameworkDeps(buildTarget.getTargetConfiguration(), args),
flavoredStripStyle,
flavoredLinkerMapMode);
// Construct the actual build params we'll use, notably with an added dependency on the
// CxxLink rule above which builds the test binary.
BuildTarget testBuildTarget =
CxxStrip.restoreStripStyleFlavorInTarget(buildTarget, flavoredStripStyle);
testBuildTarget =
LinkerMapMode.restoreLinkerMapModeFlavorInTarget(testBuildTarget, flavoredLinkerMapMode);
BuildRuleParams testParams =
params
.withDeclaredDeps(cxxLinkAndCompileRules.deps)
.copyAppendingExtraDeps(
BuildableSupport.getDepsCollection(
cxxLinkAndCompileRules.executable, graphBuilder));
StringWithMacrosConverter macrosConverter =
StringWithMacrosConverter.of(
buildTarget,
cellRoots.getCellNameResolver(),
graphBuilder,
ImmutableList.of(LocationMacroExpander.INSTANCE));
// Supplier which expands macros in the passed in test environment.
ImmutableMap<String, Arg> testEnv =
ImmutableMap.copyOf(Maps.transformValues(args.getEnv(), macrosConverter::convert));
ImmutableList<Arg> testArgs =
args.getArgs().stream()
.map(macrosConverter::convert)
.collect(ImmutableList.toImmutableList());
Function<SourcePathRuleFinder, ImmutableSortedSet<BuildRule>> additionalDeps =
ruleFinderInner -> {
ImmutableSortedSet.Builder<BuildRule> deps = ImmutableSortedSet.naturalOrder();
// It's not uncommon for users to add dependencies onto other binaries that they run
// during the test, so make sure to add them as runtime deps.
deps.addAll(
Sets.difference(
params.getBuildDeps(), cxxLinkAndCompileRules.getBinaryRule().getBuildDeps()));
// Add any build-time from any macros embedded in the `env` or `args` parameter.
for (Arg part : Iterables.concat(testArgs, testEnv.values())) {
deps.addAll(BuildableSupport.getDepsCollection(part, ruleFinderInner));
}
return deps.build();
};
CxxTest test;
CxxTestType type = args.getFramework().orElse(getDefaultTestType());
switch (type) {
case GTEST:
{
test =
new CxxGtestTest(
testBuildTarget,
projectFilesystem,
testParams,
cxxLinkAndCompileRules.getBinaryRule(),
cxxLinkAndCompileRules.executable,
testEnv,
testArgs,
FluentIterable.from(args.getResources())
.transform(p -> PathSourcePath.of(projectFilesystem, p))
.toSortedSet(Ordering.natural()),
args.getAdditionalCoverageTargets(),
additionalDeps,
args.getLabels(),
args.getContacts(),
args.getRunTestSeparately().orElse(false),
args.getTestRuleTimeoutMs()
.map(Optional::of)
.orElse(
cxxBuckConfig
.getDelegate()
.getView(TestBuckConfig.class)
.getDefaultTestRuleTimeoutMs()),
cxxBuckConfig.getMaximumTestOutputSize(),
cxxBuckConfig.checkGTestTestList());
break;
}
case BOOST:
{
test =
new CxxBoostTest(
testBuildTarget,
projectFilesystem,
testParams,
cxxLinkAndCompileRules.getBinaryRule(),
cxxLinkAndCompileRules.executable,
testEnv,
testArgs,
FluentIterable.from(args.getResources())
.transform(p -> PathSourcePath.of(projectFilesystem, p))
.toSortedSet(Ordering.natural()),
args.getAdditionalCoverageTargets(),
additionalDeps,
args.getLabels(),
args.getContacts(),
args.getRunTestSeparately().orElse(false),
args.getTestRuleTimeoutMs()
.map(Optional::of)
.orElse(
cxxBuckConfig
.getDelegate()
.getView(TestBuckConfig.class)
.getDefaultTestRuleTimeoutMs()));
break;
}
default:
{
Preconditions.checkState(false, "Unhandled C++ test type: %s", type);
throw new RuntimeException();
}
}
return test;
}