use of com.facebook.buck.rules.SourcePath in project buck by facebook.
the class Omnibus method createOmnibus.
// Create a build rule to link the giant merged omnibus library described by the given spec.
protected static OmnibusLibrary createOmnibus(BuildRuleParams params, BuildRuleResolver ruleResolver, SourcePathRuleFinder ruleFinder, CxxBuckConfig cxxBuckConfig, CxxPlatform cxxPlatform, ImmutableList<? extends Arg> extraLdflags, OmnibusSpec spec) throws NoSuchBuildTargetException {
ImmutableList.Builder<Arg> argsBuilder = ImmutableList.builder();
// Add extra ldflags to the beginning of the link.
argsBuilder.addAll(extraLdflags);
// For roots that aren't dependencies of nodes in the body, we extract their undefined symbols
// to add to the link so that required symbols get pulled into the merged library.
List<SourcePath> undefinedSymbolsOnlyRoots = new ArrayList<>();
for (BuildTarget target : Sets.difference(spec.getRoots().keySet(), spec.getGraph().getNodes())) {
NativeLinkTarget linkTarget = Preconditions.checkNotNull(spec.getRoots().get(target));
undefinedSymbolsOnlyRoots.add(ruleResolver.requireRule(getRootTarget(params.getBuildTarget(), shouldCreateDummyRoot(linkTarget, cxxPlatform) ? getDummyRootTarget(target) : target)).getSourcePathToOutput());
}
argsBuilder.addAll(createUndefinedSymbolsArgs(params, ruleResolver, ruleFinder, cxxPlatform, undefinedSymbolsOnlyRoots));
// Walk the graph in topological order, appending each nodes contributions to the link.
ImmutableList<BuildTarget> targets = TopologicalSort.sort(spec.getGraph()).reverse();
for (BuildTarget target : targets) {
// If this is a root, just place the shared library we've linked above onto the link line.
// We need this so that the linker can grab any undefined symbols from it, and therefore
// know which symbols to pull in from the body nodes.
NativeLinkTarget root = spec.getRoots().get(target);
if (root != null) {
argsBuilder.add(SourcePathArg.of(((CxxLink) ruleResolver.requireRule(getRootTarget(params.getBuildTarget(), root.getBuildTarget()))).getSourcePathToOutput()));
continue;
}
// Otherwise, this is a body node, and we need to add its static library to the link line,
// so that the linker can discard unused object files from it.
NativeLinkable nativeLinkable = Preconditions.checkNotNull(spec.getBody().get(target));
NativeLinkableInput input = NativeLinkables.getNativeLinkableInput(cxxPlatform, Linker.LinkableDepType.STATIC_PIC, nativeLinkable);
argsBuilder.addAll(input.getArgs());
}
// We process all excluded omnibus deps last, and just add their components as if this were a
// normal shared link.
ImmutableMap<BuildTarget, NativeLinkable> deps = NativeLinkables.getNativeLinkables(cxxPlatform, spec.getDeps().values(), Linker.LinkableDepType.SHARED);
for (NativeLinkable nativeLinkable : deps.values()) {
NativeLinkableInput input = NativeLinkables.getNativeLinkableInput(cxxPlatform, Linker.LinkableDepType.SHARED, nativeLinkable);
argsBuilder.addAll(input.getArgs());
}
// Create the merged omnibus library using the arguments assembled above.
BuildTarget omnibusTarget = params.getBuildTarget().withAppendedFlavors(OMNIBUS_FLAVOR);
String omnibusSoname = getOmnibusSoname(cxxPlatform);
CxxLink omnibusRule = ruleResolver.addToIndex(CxxLinkableEnhancer.createCxxLinkableSharedBuildRule(cxxBuckConfig, cxxPlatform, params, ruleResolver, ruleFinder, omnibusTarget, BuildTargets.getGenPath(params.getProjectFilesystem(), omnibusTarget, "%s").resolve(omnibusSoname), Optional.of(omnibusSoname), argsBuilder.build()));
return OmnibusLibrary.of(omnibusSoname, omnibusRule.getSourcePathToOutput());
}
use of com.facebook.buck.rules.SourcePath in project buck by facebook.
the class Omnibus method getSharedLibraries.
/**
* An alternate link strategy for languages which need to package native deps up as shared
* libraries, which only links native nodes which have an explicit edge from non-native code as
* separate, and statically linking all other native nodes into a single giant shared library.
* This reduces the number of shared libraries considerably and also allows the linker to throw
* away a lot of unused object files.
*
* @param nativeLinkTargetRoots root nodes which will be included in the omnibus link.
* @param nativeLinkableRoots root nodes which are to be excluded from the omnibus link.
* @return a map of shared library names to their containing {@link SourcePath}s.
* @throws NoSuchBuildTargetException
*/
public static OmnibusLibraries getSharedLibraries(BuildRuleParams params, BuildRuleResolver ruleResolver, SourcePathRuleFinder ruleFinder, CxxBuckConfig cxxBuckConfig, CxxPlatform cxxPlatform, ImmutableList<? extends Arg> extraLdflags, Iterable<? extends NativeLinkTarget> nativeLinkTargetRoots, Iterable<? extends NativeLinkable> nativeLinkableRoots) throws NoSuchBuildTargetException {
OmnibusLibraries.Builder libs = OmnibusLibraries.builder();
OmnibusSpec spec = buildSpec(cxxPlatform, nativeLinkTargetRoots, nativeLinkableRoots);
// Create an empty dummy omnibus library, to give the roots something to link against before
// we have the actual omnibus library available. Note that this requires that the linker
// supports linking shared libraries with undefined references.
SourcePath dummyOmnibus = createDummyOmnibus(params, ruleResolver, ruleFinder, cxxBuckConfig, cxxPlatform, extraLdflags);
// Create rule for each of the root nodes, linking against the dummy omnibus library above.
for (NativeLinkTarget target : spec.getRoots().values()) {
// undefined symbol list we need to build the real omnibus library.
if (shouldCreateDummyRoot(target, cxxPlatform)) {
createDummyRoot(params, ruleResolver, ruleFinder, cxxBuckConfig, cxxPlatform, extraLdflags, spec, dummyOmnibus, target);
} else {
OmnibusRoot root = createRoot(params, ruleResolver, ruleFinder, cxxBuckConfig, cxxPlatform, extraLdflags, spec, dummyOmnibus, target);
libs.putRoots(target.getBuildTarget(), root);
}
}
// If there are any body nodes, generate the giant merged omnibus library.
Optional<SourcePath> realOmnibus = Optional.empty();
if (!spec.getBody().isEmpty()) {
OmnibusLibrary omnibus = createOmnibus(params, ruleResolver, ruleFinder, cxxBuckConfig, cxxPlatform, extraLdflags, spec);
libs.addLibraries(omnibus);
realOmnibus = Optional.of(omnibus.getPath());
}
// See the comment above in the first pass for more details.
for (NativeLinkTarget target : spec.getRoots().values()) {
if (shouldCreateDummyRoot(target, cxxPlatform)) {
OmnibusRoot root = createRoot(params, ruleResolver, ruleFinder, cxxBuckConfig, cxxPlatform, extraLdflags, spec, realOmnibus.orElse(dummyOmnibus), target);
libs.putRoots(target.getBuildTarget(), root);
}
}
// Lastly, add in any shared libraries from excluded nodes the normal way.
for (NativeLinkable nativeLinkable : spec.getExcluded().values()) {
if (nativeLinkable.getPreferredLinkage(cxxPlatform) != NativeLinkable.Linkage.STATIC) {
for (Map.Entry<String, SourcePath> ent : nativeLinkable.getSharedLibraries(cxxPlatform).entrySet()) {
libs.addLibraries(OmnibusLibrary.of(ent.getKey(), ent.getValue()));
}
}
}
return libs.build();
}
use of com.facebook.buck.rules.SourcePath in project buck by facebook.
the class PrebuiltCxxLibraryDescription method requireSharedLibrary.
/**
* Makes sure all build rules needed to produce the shared library are added to the action
* graph.
*
* @return the {@link SourcePath} representing the actual shared library.
*/
private SourcePath requireSharedLibrary(BuildTarget target, BuildRuleResolver resolver, SourcePathResolver pathResolver, CellPathResolver cellRoots, ProjectFilesystem filesystem, CxxPlatform cxxPlatform, Optional<String> versionSubdir, Arg args) throws NoSuchBuildTargetException {
SourcePath sharedLibraryPath = PrebuiltCxxLibraryDescription.getSharedLibraryPath(target, cellRoots, filesystem, resolver, cxxPlatform, versionSubdir, args.libDir, args.libName);
// produced. This is preventing distributed build loading files lazily.
if (sharedLibraryPath instanceof BuildTargetSourcePath || filesystem.exists(pathResolver.getAbsolutePath(sharedLibraryPath))) {
return sharedLibraryPath;
}
// Otherwise, generate it's build rule.
CxxLink sharedLibrary = (CxxLink) resolver.requireRule(target.withAppendedFlavors(cxxPlatform.getFlavor(), CxxDescriptionEnhancer.SHARED_FLAVOR));
return sharedLibrary.getSourcePathToOutput();
}
use of com.facebook.buck.rules.SourcePath in project buck by facebook.
the class DDescriptionUtils method sourcePathsForCompiledSources.
/**
* Generates BuildTargets and BuildRules to compile D sources to object files, and
* returns a list of SourcePaths referring to the generated object files.
* @param sources source files to compile
* @param compilerFlags flags to pass to the compiler
* @param baseParams build parameters for the compilation
* @param buildRuleResolver resolver for build rules
* @param sourcePathResolver resolver for source paths
* @param cxxPlatform the C++ platform to compile for
* @param dBuckConfig the Buck configuration for D
* @return SourcePaths of the generated object files
*/
public static ImmutableList<SourcePath> sourcePathsForCompiledSources(BuildRuleParams baseParams, BuildRuleResolver buildRuleResolver, SourcePathResolver sourcePathResolver, SourcePathRuleFinder ruleFinder, CxxPlatform cxxPlatform, DBuckConfig dBuckConfig, ImmutableList<String> compilerFlags, SourceList sources, DIncludes includes) throws NoSuchBuildTargetException {
ImmutableList.Builder<SourcePath> sourcePaths = ImmutableList.builder();
for (Map.Entry<String, SourcePath> source : sources.toNameMap(baseParams.getBuildTarget(), sourcePathResolver, "srcs").entrySet()) {
BuildTarget compileTarget = createDCompileBuildTarget(baseParams.getBuildTarget(), source.getKey(), cxxPlatform);
BuildRule rule = requireBuildRule(compileTarget, baseParams, buildRuleResolver, ruleFinder, dBuckConfig, compilerFlags, source.getKey(), source.getValue(), includes);
sourcePaths.add(rule.getSourcePathToOutput());
}
return sourcePaths.build();
}
use of com.facebook.buck.rules.SourcePath in project buck by facebook.
the class DDescriptionUtils method createNativeLinkable.
/**
* Creates a {@link com.facebook.buck.cxx.NativeLinkable} using sources compiled by
* the D compiler.
*
* @param params build parameters for the build target
* @param sources source files to compile
* @param compilerFlags flags to pass to the compiler
* @param buildRuleResolver resolver for build rules
* @param cxxPlatform the C++ platform to compile for
* @param dBuckConfig the Buck configuration for D
* @return the new build rule
*/
public static CxxLink createNativeLinkable(BuildRuleParams params, BuildRuleResolver buildRuleResolver, CxxPlatform cxxPlatform, DBuckConfig dBuckConfig, CxxBuckConfig cxxBuckConfig, ImmutableList<String> compilerFlags, SourceList sources, ImmutableList<String> linkerFlags, DIncludes includes) throws NoSuchBuildTargetException {
BuildTarget buildTarget = params.getBuildTarget();
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(buildRuleResolver);
SourcePathResolver sourcePathResolver = new SourcePathResolver(ruleFinder);
ImmutableList<SourcePath> sourcePaths = sourcePathsForCompiledSources(params, buildRuleResolver, sourcePathResolver, ruleFinder, cxxPlatform, dBuckConfig, compilerFlags, sources, includes);
// dependencies.
return CxxLinkableEnhancer.createCxxLinkableBuildRule(cxxBuckConfig, cxxPlatform, params, buildRuleResolver, sourcePathResolver, ruleFinder, buildTarget, Linker.LinkType.EXECUTABLE, Optional.empty(), BuildTargets.getGenPath(params.getProjectFilesystem(), buildTarget, "%s/" + buildTarget.getShortName()), Linker.LinkableDepType.STATIC, FluentIterable.from(params.getDeps()).filter(NativeLinkable.class), /* cxxRuntimeType */
Optional.empty(), /* bundleLoader */
Optional.empty(), ImmutableSet.of(), NativeLinkableInput.builder().addAllArgs(StringArg.from(dBuckConfig.getLinkerFlags())).addAllArgs(StringArg.from(linkerFlags)).addAllArgs(SourcePathArg.from(sourcePaths)).build());
}
Aggregations