use of com.facebook.buck.model.BuildTarget in project buck by facebook.
the class CxxLibraryDescription method createSharedLibrary.
/**
* Create all build rules needed to generate the shared library.
*
* @return the {@link CxxLink} rule representing the actual shared library.
*/
private static CxxLink createSharedLibrary(BuildRuleParams params, BuildRuleResolver ruleResolver, SourcePathResolver pathResolver, SourcePathRuleFinder ruleFinder, CxxBuckConfig cxxBuckConfig, CxxPlatform cxxPlatform, CxxLibraryDescription.Arg args, ImmutableList<StringWithMacros> linkerFlags, ImmutableSet<FrameworkPath> frameworks, ImmutableSet<FrameworkPath> libraries, Optional<String> soname, Optional<Linker.CxxRuntimeType> cxxRuntimeType, Linker.LinkType linkType, Linker.LinkableDepType linkableDepType, Optional<SourcePath> bundleLoader, ImmutableSet<BuildTarget> blacklist) throws NoSuchBuildTargetException {
Optional<LinkerMapMode> flavoredLinkerMapMode = LinkerMapMode.FLAVOR_DOMAIN.getValue(params.getBuildTarget());
params = LinkerMapMode.removeLinkerMapModeFlavorInParams(params, flavoredLinkerMapMode);
// Create rules for compiling the PIC object files.
ImmutableMap<CxxPreprocessAndCompile, SourcePath> objects = requireObjects(params, ruleResolver, pathResolver, ruleFinder, cxxBuckConfig, cxxPlatform, CxxSourceRuleFactory.PicType.PIC, args);
// Setup the rules to link the shared library.
BuildTarget sharedTarget = CxxDescriptionEnhancer.createSharedLibraryBuildTarget(LinkerMapMode.restoreLinkerMapModeFlavorInParams(params, flavoredLinkerMapMode).getBuildTarget(), cxxPlatform.getFlavor(), linkType);
String sharedLibrarySoname = CxxDescriptionEnhancer.getSharedLibrarySoname(soname, params.getBuildTarget(), cxxPlatform);
Path sharedLibraryPath = CxxDescriptionEnhancer.getSharedLibraryPath(params.getProjectFilesystem(), sharedTarget, sharedLibrarySoname);
ImmutableList.Builder<StringWithMacros> extraLdFlagsBuilder = ImmutableList.builder();
extraLdFlagsBuilder.addAll(linkerFlags);
ImmutableList<StringWithMacros> extraLdFlags = extraLdFlagsBuilder.build();
return CxxLinkableEnhancer.createCxxLinkableBuildRule(cxxBuckConfig, cxxPlatform, LinkerMapMode.restoreLinkerMapModeFlavorInParams(params, flavoredLinkerMapMode), ruleResolver, pathResolver, ruleFinder, sharedTarget, linkType, Optional.of(sharedLibrarySoname), sharedLibraryPath, linkableDepType, Iterables.filter(params.getDeps(), NativeLinkable.class), cxxRuntimeType, bundleLoader, blacklist, NativeLinkableInput.builder().addAllArgs(CxxDescriptionEnhancer.toStringWithMacrosArgs(params.getBuildTarget(), params.getCellRoots(), ruleResolver, cxxPlatform, extraLdFlags)).addAllArgs(SourcePathArg.from(objects.values())).setFrameworks(frameworks).setLibraries(libraries).build());
}
use of com.facebook.buck.model.BuildTarget in project buck by facebook.
the class NativeLinkables method getNativeLinkables.
/**
* Extract from the dependency graph all the libraries which must be considered for linking.
*
* Traversal proceeds depending on whether each dependency is to be statically or dynamically
* linked.
*
* @param linkStyle how dependencies should be linked, if their preferred_linkage is
* {@code NativeLinkable.Linkage.ANY}.
*/
public static ImmutableMap<BuildTarget, NativeLinkable> getNativeLinkables(final CxxPlatform cxxPlatform, Iterable<? extends NativeLinkable> inputs, final Linker.LinkableDepType linkStyle, final Predicate<? super NativeLinkable> traverse) {
final Map<BuildTarget, NativeLinkable> nativeLinkables = Maps.newHashMap();
for (NativeLinkable nativeLinkable : inputs) {
nativeLinkables.put(nativeLinkable.getBuildTarget(), nativeLinkable);
}
final MutableDirectedGraph<BuildTarget> graph = new MutableDirectedGraph<>();
AbstractBreadthFirstTraversal<BuildTarget> visitor = new AbstractBreadthFirstTraversal<BuildTarget>(nativeLinkables.keySet()) {
@Override
public ImmutableSet<BuildTarget> visit(BuildTarget target) {
NativeLinkable nativeLinkable = Preconditions.checkNotNull(nativeLinkables.get(target));
graph.addNode(target);
// We always traverse a rule's exported native linkables.
Iterable<? extends NativeLinkable> nativeLinkableDeps = nativeLinkable.getNativeLinkableExportedDepsForPlatform(cxxPlatform);
boolean shouldTraverse = true;
switch(nativeLinkable.getPreferredLinkage(cxxPlatform)) {
case ANY:
shouldTraverse = linkStyle != Linker.LinkableDepType.SHARED;
break;
case SHARED:
shouldTraverse = false;
break;
case STATIC:
shouldTraverse = true;
break;
}
// If we're linking this dependency statically, we also need to traverse its deps.
if (shouldTraverse) {
nativeLinkableDeps = Iterables.concat(nativeLinkableDeps, nativeLinkable.getNativeLinkableDepsForPlatform(cxxPlatform));
}
// Process all the traversable deps.
ImmutableSet.Builder<BuildTarget> deps = ImmutableSet.builder();
for (NativeLinkable dep : nativeLinkableDeps) {
if (traverse.apply(dep)) {
BuildTarget depTarget = dep.getBuildTarget();
graph.addEdge(target, depTarget);
deps.add(depTarget);
nativeLinkables.put(depTarget, dep);
}
}
return deps.build();
}
};
visitor.start();
// Topologically sort the rules.
Iterable<BuildTarget> ordered = TopologicalSort.sort(graph).reverse();
// Return a map of of the results.
ImmutableMap.Builder<BuildTarget, NativeLinkable> result = ImmutableMap.builder();
for (BuildTarget target : ordered) {
result.put(target, nativeLinkables.get(target));
}
return result.build();
}
use of com.facebook.buck.model.BuildTarget in project buck by facebook.
the class Omnibus method createRoot.
// Create a build rule which links the given root node against the merged omnibus library
// described by the given spec file.
protected static OmnibusRoot createRoot(BuildRuleParams params, BuildRuleResolver ruleResolver, SourcePathRuleFinder ruleFinder, CxxBuckConfig cxxBuckConfig, CxxPlatform cxxPlatform, ImmutableList<? extends Arg> extraLdflags, OmnibusSpec spec, SourcePath omnibus, NativeLinkTarget root, BuildTarget rootTargetBase, Optional<Path> output) throws NoSuchBuildTargetException {
ImmutableList.Builder<Arg> argsBuilder = ImmutableList.builder();
// Add any extra flags to the link.
argsBuilder.addAll(extraLdflags);
// Since the dummy omnibus library doesn't actually contain any symbols, make sure the linker
// won't drop its runtime reference to it.
argsBuilder.addAll(StringArg.from(cxxPlatform.getLd().resolve(ruleResolver).getNoAsNeededSharedLibsFlags()));
// Since we're linking against a dummy libomnibus, ignore undefined symbols.
argsBuilder.addAll(StringArg.from(cxxPlatform.getLd().resolve(ruleResolver).getIgnoreUndefinedSymbolsFlags()));
// Add the args for the root link target first.
NativeLinkableInput input = root.getNativeLinkTargetInput(cxxPlatform);
argsBuilder.addAll(input.getArgs());
// Grab a topologically sorted mapping of all the root's deps.
ImmutableMap<BuildTarget, NativeLinkable> deps = NativeLinkables.getNativeLinkables(cxxPlatform, root.getNativeLinkTargetDeps(cxxPlatform), Linker.LinkableDepType.SHARED);
// Now process the dependencies in topological order, to assemble the link line.
boolean alreadyAddedOmnibusToArgs = false;
for (Map.Entry<BuildTarget, NativeLinkable> entry : deps.entrySet()) {
BuildTarget target = entry.getKey();
NativeLinkable nativeLinkable = entry.getValue();
Linker.LinkableDepType linkStyle = NativeLinkables.getLinkStyle(nativeLinkable.getPreferredLinkage(cxxPlatform), Linker.LinkableDepType.SHARED);
// If this dep needs to be linked statically, then we always link it directly.
if (linkStyle != Linker.LinkableDepType.SHARED) {
Preconditions.checkState(linkStyle == Linker.LinkableDepType.STATIC_PIC);
argsBuilder.addAll(nativeLinkable.getNativeLinkableInput(cxxPlatform, linkStyle).getArgs());
continue;
}
// If this dep is another root node, substitute in the custom linked library we built for it.
if (spec.getRoots().containsKey(target)) {
argsBuilder.add(SourcePathArg.of(new DefaultBuildTargetSourcePath(getRootTarget(params.getBuildTarget(), target))));
continue;
}
// libomnibus instead.
if (spec.getBody().containsKey(target)) {
// && linkStyle == Linker.LinkableDepType.SHARED) {
if (!alreadyAddedOmnibusToArgs) {
argsBuilder.add(SourcePathArg.of(omnibus));
alreadyAddedOmnibusToArgs = true;
}
continue;
}
// Otherwise, this is either an explicitly statically linked or excluded node, so link it
// normally.
Preconditions.checkState(spec.getExcluded().containsKey(target));
argsBuilder.addAll(nativeLinkable.getNativeLinkableInput(cxxPlatform, linkStyle).getArgs());
}
// Create the root library rule using the arguments assembled above.
BuildTarget rootTarget = getRootTarget(params.getBuildTarget(), rootTargetBase);
NativeLinkTargetMode rootTargetMode = root.getNativeLinkTargetMode(cxxPlatform);
CxxLink rootLinkRule;
switch(rootTargetMode.getType()) {
// Link the root as a shared library.
case SHARED:
{
Optional<String> rootSoname = rootTargetMode.getLibraryName();
rootLinkRule = CxxLinkableEnhancer.createCxxLinkableSharedBuildRule(cxxBuckConfig, cxxPlatform, params, ruleResolver, ruleFinder, rootTarget, output.orElse(BuildTargets.getGenPath(params.getProjectFilesystem(), rootTarget, "%s").resolve(rootSoname.orElse(String.format("%s.%s", rootTarget.getShortName(), cxxPlatform.getSharedLibraryExtension())))), rootSoname, argsBuilder.build());
break;
}
// Link the root as an executable.
case EXECUTABLE:
{
rootLinkRule = CxxLinkableEnhancer.createCxxLinkableBuildRule(cxxBuckConfig, cxxPlatform, params, ruleResolver, ruleFinder, rootTarget, output.orElse(BuildTargets.getGenPath(params.getProjectFilesystem(), rootTarget, "%s").resolve(rootTarget.getShortName())), argsBuilder.build(), Linker.LinkableDepType.SHARED, Optional.empty());
break;
}
// $CASES-OMITTED$
default:
throw new IllegalStateException(String.format("%s: unexpected omnibus root type: %s %s", params.getBuildTarget(), root.getBuildTarget(), rootTargetMode.getType()));
}
CxxLink rootRule = ruleResolver.addToIndex(rootLinkRule);
return OmnibusRoot.of(rootRule.getSourcePathToOutput());
}
use of com.facebook.buck.model.BuildTarget 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.model.BuildTarget 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();
}
Aggregations