in src/com/facebook/buck/cxx/CxxDescriptionEnhancer.java [1346:1542]
public static CxxLinkAndCompileRules createBuildRulesForCxxBinary(
BuildTarget target,
ProjectFilesystem projectFilesystem,
ActionGraphBuilder graphBuilder,
CellPathResolver cellRoots,
CxxBuckConfig cxxBuckConfig,
CxxPlatform cxxPlatform,
ImmutableMap<String, CxxSource> srcs,
ImmutableMap<Path, SourcePath> headers,
SortedSet<BuildRule> deps,
ImmutableSet<BuildTarget> linkWholeDeps,
Optional<StripStyle> stripStyle,
Optional<LinkerMapMode> flavoredLinkerMapMode,
LinkableDepType linkStyle,
Optional<LinkableListFilter> linkableListFilter,
CxxLinkOptions linkOptions,
ImmutableList<StringWithMacros> preprocessorFlags,
PatternMatchedCollection<ImmutableList<StringWithMacros>> platformPreprocessorFlags,
ImmutableMap<Type, ImmutableList<StringWithMacros>> langPreprocessorFlags,
ImmutableMap<Type, PatternMatchedCollection<ImmutableList<StringWithMacros>>>
langPlatformPreprocessorFlags,
ImmutableSortedSet<FrameworkPath> frameworks,
ImmutableSortedSet<FrameworkPath> libraries,
ImmutableList<StringWithMacros> compilerFlags,
ImmutableMap<Type, ImmutableList<StringWithMacros>> langCompilerFlags,
PatternMatchedCollection<ImmutableList<StringWithMacros>> platformCompilerFlags,
ImmutableMap<Type, PatternMatchedCollection<ImmutableList<StringWithMacros>>>
langPlatformCompilerFlags,
Optional<SourcePath> prefixHeader,
Optional<SourcePath> precompiledHeader,
ImmutableList<StringWithMacros> linkerFlags,
ImmutableList<String> linkerExtraOutputs,
PatternMatchedCollection<ImmutableList<StringWithMacros>> platformLinkerFlags,
Optional<CxxRuntimeType> cxxRuntimeType,
ImmutableSortedSet<SourcePath> rawHeaders,
ImmutableSortedSet<String> includeDirectories,
Optional<String> outputRootName) {
// TODO(beefon): should be:
// Path linkOutput = getLinkOutputPath(
// createCxxLinkTarget(params.getBuildTarget(), flavoredLinkerMapMode),
// projectFilesystem);
ImmutableMap<CxxPreprocessAndCompile, SourcePath> objects =
createCompileRulesForCxxBinary(
target,
projectFilesystem,
graphBuilder,
cellRoots,
cxxBuckConfig,
cxxPlatform,
srcs,
headers,
deps,
linkStyle,
linkOptions,
preprocessorFlags,
platformPreprocessorFlags,
langPreprocessorFlags,
langPlatformPreprocessorFlags,
frameworks,
compilerFlags,
langCompilerFlags,
platformCompilerFlags,
langPlatformCompilerFlags,
prefixHeader,
precompiledHeader,
rawHeaders,
includeDirectories);
CommandTool.Builder executableBuilder = new CommandTool.Builder();
Linker linker = cxxPlatform.getLd().resolve(graphBuilder, target.getTargetConfiguration());
BuildTarget linkRuleTarget = createCxxLinkTarget(target, flavoredLinkerMapMode);
Path linkOutput =
getBinaryOutputPath(
flavoredLinkerMapMode.isPresent()
? target.withAppendedFlavors(flavoredLinkerMapMode.get().getFlavor())
: target,
projectFilesystem,
cxxPlatform.getBinaryExtension(),
outputRootName);
ImmutableList<Arg> args =
createLinkArgsForCxxBinary(
linkRuleTarget,
projectFilesystem,
graphBuilder,
cellRoots,
cxxPlatform,
objects,
deps,
executableBuilder,
linker,
linkStyle,
linkOutput,
linkerFlags,
platformLinkerFlags);
CxxLink cxxLink =
(CxxLink)
graphBuilder.computeIfAbsent(
linkRuleTarget,
ignored ->
// Generate the final link rule. We use the top-level target as the link rule's
// target, so that it corresponds to the actual binary we build.
CxxLinkableEnhancer.createCxxLinkableBuildRule(
cxxBuckConfig,
cxxPlatform,
projectFilesystem,
graphBuilder,
linkRuleTarget,
Linker.LinkType.EXECUTABLE,
Optional.empty(),
linkOutput,
linkerExtraOutputs,
linkStyle,
linkableListFilter,
linkOptions,
RichStream.from(deps)
.filter(NativeLinkableGroup.class)
.map(g -> g.getNativeLinkable(cxxPlatform, graphBuilder))
.toImmutableList(),
cxxRuntimeType,
Optional.empty(),
ImmutableSet.of(),
linkWholeDeps,
NativeLinkableInput.builder()
.setArgs(args)
.setFrameworks(frameworks)
.setLibraries(libraries)
.build(),
Optional.empty(),
cellRoots));
BuildRule binaryRuleForExecutable;
Optional<CxxStrip> cxxStrip = Optional.empty();
if (stripStyle.isPresent()) {
BuildTarget cxxTarget = target;
if (flavoredLinkerMapMode.isPresent()) {
cxxTarget = cxxTarget.withAppendedFlavors(flavoredLinkerMapMode.get().getFlavor());
}
CxxStrip stripRule =
createCxxStripRule(
cxxTarget,
projectFilesystem,
graphBuilder,
stripStyle.get(),
cxxBuckConfig.shouldCacheStrip(),
cxxLink,
cxxPlatform,
outputRootName);
cxxStrip = Optional.of(stripRule);
binaryRuleForExecutable = stripRule;
} else {
binaryRuleForExecutable = cxxLink;
}
SourcePath sourcePathToExecutable = binaryRuleForExecutable.getSourcePathToOutput();
// Special handling for dynamically linked binaries requiring dependencies to be in the same
// directory
if (linkStyle == Linker.LinkableDepType.SHARED
&& linker.getSharedLibraryLoadingType()
== Linker.SharedLibraryLoadingType.THE_SAME_DIRECTORY) {
Path binaryName = linkOutput.getFileName();
BuildTarget binaryWithSharedLibrariesTarget =
createBinaryWithSharedLibrariesSymlinkTreeTarget(target, cxxPlatform.getFlavor());
Path symlinkTreeRoot =
getBinaryWithSharedLibrariesSymlinkTreePath(
projectFilesystem, binaryWithSharedLibrariesTarget, cxxPlatform.getFlavor());
Path appPath = symlinkTreeRoot.resolve(binaryName);
MappedSymlinkTree binaryWithSharedLibraries =
requireBinaryWithSharedLibrariesSymlinkTree(
target,
projectFilesystem,
graphBuilder,
cxxPlatform,
deps,
binaryName,
sourcePathToExecutable);
executableBuilder.addNonHashableInput(binaryWithSharedLibraries.getRootSourcePath());
executableBuilder.addInputs(binaryWithSharedLibraries.getLinks().values());
sourcePathToExecutable =
ExplicitBuildTargetSourcePath.of(binaryWithSharedLibrariesTarget, appPath);
}
// Add the output of the link as the lone argument needed to invoke this binary as a tool.
executableBuilder.addArg(SourcePathArg.of(sourcePathToExecutable));
return new CxxLinkAndCompileRules(
cxxLink,
cxxStrip,
ImmutableSortedSet.copyOf(objects.keySet()),
executableBuilder.build(),
deps);
}