use of com.facebook.buck.graph.AbstractBreadthFirstTraversal in project buck by facebook.
the class TargetsCommand method getDependentNodes.
/**
* @param graph A graph used to resolve dependencies between targets.
* @param nodes A set of nodes.
* @param detectTestChanges If true, tests are considered to be dependencies of the targets they
* are testing.
* @return A set of all nodes that transitively depend on {@code nodes}
* (a superset of {@code nodes}).
*/
private static ImmutableSet<TargetNode<?, ?>> getDependentNodes(final TargetGraph graph, ImmutableSet<TargetNode<?, ?>> nodes, boolean detectTestChanges) {
ImmutableMultimap.Builder<TargetNode<?, ?>, TargetNode<?, ?>> extraEdgesBuilder = ImmutableMultimap.builder();
if (detectTestChanges) {
for (TargetNode<?, ?> node : graph.getNodes()) {
if (node.getConstructorArg() instanceof HasTests) {
ImmutableSortedSet<BuildTarget> tests = ((HasTests) node.getConstructorArg()).getTests();
for (BuildTarget testTarget : tests) {
Optional<TargetNode<?, ?>> testNode = graph.getOptional(testTarget);
if (!testNode.isPresent()) {
throw new HumanReadableException("'%s' (test of '%s') is not in the target graph.", testTarget, node);
}
extraEdgesBuilder.put(testNode.get(), node);
}
}
}
}
final ImmutableMultimap<TargetNode<?, ?>, TargetNode<?, ?>> extraEdges = extraEdgesBuilder.build();
final ImmutableSet.Builder<TargetNode<?, ?>> builder = ImmutableSet.builder();
AbstractBreadthFirstTraversal<TargetNode<?, ?>> traversal = new AbstractBreadthFirstTraversal<TargetNode<?, ?>>(nodes) {
@Override
public ImmutableSet<TargetNode<?, ?>> visit(TargetNode<?, ?> targetNode) {
builder.add(targetNode);
return FluentIterable.from(graph.getIncomingNodesFor(targetNode)).append(extraEdges.get(targetNode)).toSet();
}
};
traversal.start();
return builder.build();
}
use of com.facebook.buck.graph.AbstractBreadthFirstTraversal 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.graph.AbstractBreadthFirstTraversal in project buck by facebook.
the class NativeLinkables method getTransitiveNativeLinkables.
public static ImmutableMap<BuildTarget, NativeLinkable> getTransitiveNativeLinkables(final CxxPlatform cxxPlatform, Iterable<? extends NativeLinkable> inputs) {
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);
ImmutableSet.Builder<BuildTarget> deps = ImmutableSet.builder();
for (NativeLinkable dep : Iterables.concat(nativeLinkable.getNativeLinkableDepsForPlatform(cxxPlatform), nativeLinkable.getNativeLinkableExportedDepsForPlatform(cxxPlatform))) {
BuildTarget depTarget = dep.getBuildTarget();
graph.addEdge(target, depTarget);
deps.add(depTarget);
nativeLinkables.put(depTarget, dep);
}
return deps.build();
}
};
visitor.start();
return ImmutableMap.copyOf(nativeLinkables);
}
Aggregations