use of com.facebook.buck.cxx.NativeLinkTarget in project buck by facebook.
the class LuaBinaryDescription method getPackageComponentsFromDeps.
private LuaBinaryPackageComponents getPackageComponentsFromDeps(BuildRuleParams baseParams, BuildRuleResolver ruleResolver, SourcePathResolver pathResolver, SourcePathRuleFinder ruleFinder, final CxxPlatform cxxPlatform, final PythonPlatform pythonPlatform, Optional<BuildTarget> nativeStarterLibrary, String mainModule, LuaConfig.PackageStyle packageStyle, Iterable<BuildRule> deps) throws NoSuchBuildTargetException {
final LuaPackageComponents.Builder builder = LuaPackageComponents.builder();
final OmnibusRoots.Builder omnibusRoots = OmnibusRoots.builder(cxxPlatform, ImmutableSet.of());
final Map<BuildTarget, NativeLinkable> nativeLinkableRoots = new LinkedHashMap<>();
final Map<BuildTarget, CxxLuaExtension> luaExtensions = new LinkedHashMap<>();
final Map<BuildTarget, CxxPythonExtension> pythonExtensions = new LinkedHashMap<>();
// Walk the deps to find all Lua packageables and native linkables.
new AbstractBreadthFirstThrowingTraversal<BuildRule, NoSuchBuildTargetException>(deps) {
private final ImmutableSet<BuildRule> empty = ImmutableSet.of();
@Override
public ImmutableSet<BuildRule> visit(BuildRule rule) throws NoSuchBuildTargetException {
ImmutableSet<BuildRule> deps = empty;
if (rule instanceof LuaPackageable) {
LuaPackageable packageable = (LuaPackageable) rule;
LuaPackageComponents components = packageable.getLuaPackageComponents();
LuaPackageComponents.addComponents(builder, components);
if (components.hasNativeCode(cxxPlatform)) {
for (BuildRule dep : rule.getDeps()) {
if (dep instanceof NativeLinkable) {
NativeLinkable linkable = (NativeLinkable) dep;
nativeLinkableRoots.put(linkable.getBuildTarget(), linkable);
omnibusRoots.addExcludedRoot(linkable);
}
}
}
deps = rule.getDeps();
} else if (rule instanceof CxxPythonExtension) {
CxxPythonExtension extension = (CxxPythonExtension) rule;
NativeLinkTarget target = extension.getNativeLinkTarget(pythonPlatform);
pythonExtensions.put(target.getBuildTarget(), (CxxPythonExtension) rule);
omnibusRoots.addIncludedRoot(target);
} else if (rule instanceof PythonPackagable) {
PythonPackagable packageable = (PythonPackagable) rule;
PythonPackageComponents components = packageable.getPythonPackageComponents(pythonPlatform, cxxPlatform);
builder.putAllPythonModules(MoreMaps.transformKeys(components.getModules(), Object::toString));
builder.putAllNativeLibraries(MoreMaps.transformKeys(components.getNativeLibraries(), Object::toString));
if (components.hasNativeCode(cxxPlatform)) {
for (BuildRule dep : rule.getDeps()) {
if (dep instanceof NativeLinkable) {
NativeLinkable linkable = (NativeLinkable) dep;
nativeLinkableRoots.put(linkable.getBuildTarget(), linkable);
omnibusRoots.addExcludedRoot(linkable);
}
}
}
deps = rule.getDeps();
} else if (rule instanceof CxxLuaExtension) {
CxxLuaExtension extension = (CxxLuaExtension) rule;
luaExtensions.put(extension.getBuildTarget(), extension);
omnibusRoots.addIncludedRoot(extension);
} else if (rule instanceof NativeLinkable) {
NativeLinkable linkable = (NativeLinkable) rule;
nativeLinkableRoots.put(linkable.getBuildTarget(), linkable);
omnibusRoots.addPotentialRoot(linkable);
}
return deps;
}
}.start();
// Build the starter.
Starter starter = createStarter(baseParams, ruleResolver, pathResolver, ruleFinder, cxxPlatform, nativeStarterLibrary, mainModule, packageStyle, !nativeLinkableRoots.isEmpty() || !omnibusRoots.isEmpty());
SourcePath starterPath = null;
if (luaConfig.getNativeLinkStrategy() == NativeLinkStrategy.MERGED) {
// If we're using a native starter, include it in omnibus linking.
if (starter instanceof NativeExecutableStarter) {
NativeExecutableStarter nativeStarter = (NativeExecutableStarter) starter;
omnibusRoots.addIncludedRoot(nativeStarter);
}
// Build the omnibus libraries.
OmnibusRoots roots = omnibusRoots.build();
OmnibusLibraries libraries = Omnibus.getSharedLibraries(baseParams, ruleResolver, ruleFinder, cxxBuckConfig, cxxPlatform, ImmutableList.of(), roots.getIncludedRoots().values(), roots.getExcludedRoots().values());
// Add all the roots from the omnibus link. If it's an extension, add it as a module.
for (Map.Entry<BuildTarget, OmnibusRoot> root : libraries.getRoots().entrySet()) {
// If it's a Lua extension add it as a module.
CxxLuaExtension luaExtension = luaExtensions.get(root.getKey());
if (luaExtension != null) {
builder.putModules(luaExtension.getModule(cxxPlatform), root.getValue().getPath());
continue;
}
// If it's a Python extension, add it as a python module.
CxxPythonExtension pythonExtension = pythonExtensions.get(root.getKey());
if (pythonExtension != null) {
builder.putPythonModules(pythonExtension.getModule().toString(), root.getValue().getPath());
continue;
}
// A root named after the top-level target is our native starter.
if (root.getKey().equals(baseParams.getBuildTarget())) {
starterPath = root.getValue().getPath();
continue;
}
// Otherwise, add it as a native library.
NativeLinkTarget target = Preconditions.checkNotNull(roots.getIncludedRoots().get(root.getKey()), "%s: linked unexpected omnibus root: %s", baseParams.getBuildTarget(), root.getKey());
NativeLinkTargetMode mode = target.getNativeLinkTargetMode(cxxPlatform);
String soname = Preconditions.checkNotNull(mode.getLibraryName().orElse(null), "%s: omnibus library for %s was built without soname", baseParams.getBuildTarget(), root.getKey());
builder.putNativeLibraries(soname, root.getValue().getPath());
}
// Add all remaining libraries as native libraries.
for (OmnibusLibrary library : libraries.getLibraries()) {
builder.putNativeLibraries(library.getSoname(), library.getPath());
}
} else {
// roots.
for (Map.Entry<BuildTarget, CxxLuaExtension> entry : luaExtensions.entrySet()) {
CxxLuaExtension extension = entry.getValue();
builder.putModules(extension.getModule(cxxPlatform), extension.getExtension(cxxPlatform));
nativeLinkableRoots.putAll(Maps.uniqueIndex(extension.getNativeLinkTargetDeps(cxxPlatform), NativeLinkable::getBuildTarget));
}
// Add in native executable deps.
if (starter instanceof NativeExecutableStarter) {
NativeExecutableStarter executableStarter = (NativeExecutableStarter) starter;
nativeLinkableRoots.putAll(Maps.uniqueIndex(executableStarter.getNativeStarterDeps(), NativeLinkable::getBuildTarget));
}
// python-platform specific deps to the native linkables.
for (Map.Entry<BuildTarget, CxxPythonExtension> entry : pythonExtensions.entrySet()) {
PythonPackageComponents components = entry.getValue().getPythonPackageComponents(pythonPlatform, cxxPlatform);
builder.putAllPythonModules(MoreMaps.transformKeys(components.getModules(), Object::toString));
builder.putAllNativeLibraries(MoreMaps.transformKeys(components.getNativeLibraries(), Object::toString));
nativeLinkableRoots.putAll(Maps.uniqueIndex(entry.getValue().getNativeLinkTarget(pythonPlatform).getNativeLinkTargetDeps(cxxPlatform), NativeLinkable::getBuildTarget));
}
// Add shared libraries from all native linkables.
for (NativeLinkable nativeLinkable : NativeLinkables.getTransitiveNativeLinkables(cxxPlatform, nativeLinkableRoots.values()).values()) {
NativeLinkable.Linkage linkage = nativeLinkable.getPreferredLinkage(cxxPlatform);
if (linkage != NativeLinkable.Linkage.STATIC) {
builder.putAllNativeLibraries(nativeLinkable.getSharedLibraries(cxxPlatform));
}
}
}
// building one directly from the starter.
if (starterPath == null) {
starterPath = starter.build();
}
return LuaBinaryPackageComponents.of(starterPath, builder.build());
}
use of com.facebook.buck.cxx.NativeLinkTarget in project buck by facebook.
the class PythonUtil method getAllComponents.
static PythonPackageComponents getAllComponents(BuildRuleParams params, BuildRuleResolver ruleResolver, SourcePathRuleFinder ruleFinder, final PythonPackageComponents packageComponents, final PythonPlatform pythonPlatform, CxxBuckConfig cxxBuckConfig, final CxxPlatform cxxPlatform, ImmutableList<? extends Arg> extraLdflags, final NativeLinkStrategy nativeLinkStrategy, final ImmutableSet<BuildTarget> preloadDeps) throws NoSuchBuildTargetException {
final PythonPackageComponents.Builder allComponents = new PythonPackageComponents.Builder(params.getBuildTarget());
final Map<BuildTarget, CxxPythonExtension> extensions = new LinkedHashMap<>();
final Map<BuildTarget, NativeLinkable> nativeLinkableRoots = new LinkedHashMap<>();
final OmnibusRoots.Builder omnibusRoots = OmnibusRoots.builder(cxxPlatform, preloadDeps);
// Add the top-level components.
allComponents.addComponent(packageComponents, params.getBuildTarget());
// Walk all our transitive deps to build our complete package that we'll
// turn into an executable.
new AbstractBreadthFirstThrowingTraversal<BuildRule, NoSuchBuildTargetException>(params.getDeps()) {
private final ImmutableList<BuildRule> empty = ImmutableList.of();
@Override
public Iterable<BuildRule> visit(BuildRule rule) throws NoSuchBuildTargetException {
Iterable<BuildRule> deps = empty;
if (rule instanceof CxxPythonExtension) {
CxxPythonExtension extension = (CxxPythonExtension) rule;
NativeLinkTarget target = ((CxxPythonExtension) rule).getNativeLinkTarget(pythonPlatform);
extensions.put(target.getBuildTarget(), extension);
omnibusRoots.addIncludedRoot(target);
List<BuildRule> cxxpydeps = new ArrayList<>();
for (BuildRule dep : rule.getDeps()) {
if (dep instanceof CxxPythonExtension) {
cxxpydeps.add(dep);
}
}
deps = cxxpydeps;
} else if (rule instanceof PythonPackagable) {
PythonPackagable packagable = (PythonPackagable) rule;
PythonPackageComponents comps = packagable.getPythonPackageComponents(pythonPlatform, cxxPlatform);
allComponents.addComponent(comps, rule.getBuildTarget());
if (comps.hasNativeCode(cxxPlatform)) {
for (BuildRule dep : rule.getDeps()) {
if (dep instanceof NativeLinkable) {
NativeLinkable linkable = (NativeLinkable) dep;
nativeLinkableRoots.put(linkable.getBuildTarget(), linkable);
omnibusRoots.addExcludedRoot(linkable);
}
}
}
deps = rule.getDeps();
} else if (rule instanceof NativeLinkable) {
NativeLinkable linkable = (NativeLinkable) rule;
nativeLinkableRoots.put(linkable.getBuildTarget(), linkable);
omnibusRoots.addPotentialRoot(linkable);
}
return deps;
}
}.start();
// excluded native linkable roots.
if (nativeLinkStrategy == NativeLinkStrategy.MERGED) {
OmnibusRoots roots = omnibusRoots.build();
OmnibusLibraries libraries = Omnibus.getSharedLibraries(params, ruleResolver, ruleFinder, cxxBuckConfig, cxxPlatform, extraLdflags, roots.getIncludedRoots().values(), roots.getExcludedRoots().values());
// Otherwise, add it as a native library.
for (Map.Entry<BuildTarget, OmnibusRoot> root : libraries.getRoots().entrySet()) {
CxxPythonExtension extension = extensions.get(root.getKey());
if (extension != null) {
allComponents.addModule(extension.getModule(), root.getValue().getPath(), root.getKey());
} else {
NativeLinkTarget target = Preconditions.checkNotNull(roots.getIncludedRoots().get(root.getKey()), "%s: linked unexpected omnibus root: %s", params.getBuildTarget(), root.getKey());
NativeLinkTargetMode mode = target.getNativeLinkTargetMode(cxxPlatform);
String soname = Preconditions.checkNotNull(mode.getLibraryName().orElse(null), "%s: omnibus library for %s was built without soname", params.getBuildTarget(), root.getKey());
allComponents.addNativeLibraries(Paths.get(soname), root.getValue().getPath(), root.getKey());
}
}
// Add all remaining libraries as native libraries.
for (OmnibusLibrary library : libraries.getLibraries()) {
allComponents.addNativeLibraries(Paths.get(library.getSoname()), library.getPath(), params.getBuildTarget());
}
} else {
// For regular linking, add all extensions via the package components interface.
Map<BuildTarget, NativeLinkable> extensionNativeDeps = new LinkedHashMap<>();
for (Map.Entry<BuildTarget, CxxPythonExtension> entry : extensions.entrySet()) {
allComponents.addComponent(entry.getValue().getPythonPackageComponents(pythonPlatform, cxxPlatform), entry.getValue().getBuildTarget());
extensionNativeDeps.putAll(Maps.uniqueIndex(entry.getValue().getNativeLinkTarget(pythonPlatform).getNativeLinkTargetDeps(cxxPlatform), NativeLinkable::getBuildTarget));
}
// Add all the native libraries.
ImmutableMap<BuildTarget, NativeLinkable> nativeLinkables = NativeLinkables.getTransitiveNativeLinkables(cxxPlatform, Iterables.concat(nativeLinkableRoots.values(), extensionNativeDeps.values()));
for (NativeLinkable nativeLinkable : nativeLinkables.values()) {
NativeLinkable.Linkage linkage = nativeLinkable.getPreferredLinkage(cxxPlatform);
if (nativeLinkableRoots.containsKey(nativeLinkable.getBuildTarget()) || linkage != NativeLinkable.Linkage.STATIC) {
ImmutableMap<String, SourcePath> libs = nativeLinkable.getSharedLibraries(cxxPlatform);
for (Map.Entry<String, SourcePath> ent : libs.entrySet()) {
allComponents.addNativeLibraries(Paths.get(ent.getKey()), ent.getValue(), nativeLinkable.getBuildTarget());
}
}
}
}
return allComponents.build();
}
use of com.facebook.buck.cxx.NativeLinkTarget in project buck by facebook.
the class CxxPythonExtensionDescription method createBuildRule.
@Override
public <A extends Arg> BuildRule createBuildRule(TargetGraph targetGraph, final BuildRuleParams params, final BuildRuleResolver ruleResolver, final A args) throws NoSuchBuildTargetException {
Optional<Map.Entry<Flavor, CxxPlatform>> platform = cxxPlatforms.getFlavorAndValue(params.getBuildTarget());
if (params.getBuildTarget().getFlavors().contains(CxxDescriptionEnhancer.SANDBOX_TREE_FLAVOR)) {
return CxxDescriptionEnhancer.createSandboxTreeBuildRule(ruleResolver, args, platform.get().getValue(), params);
}
// See if we're building a particular "type" of this library, and if so, extract
// it as an enum.
final Optional<Map.Entry<Flavor, Type>> type = LIBRARY_TYPE.getFlavorAndValue(params.getBuildTarget());
final Optional<Map.Entry<Flavor, PythonPlatform>> pythonPlatform = pythonPlatforms.getFlavorAndValue(params.getBuildTarget());
// pre-existing static lib, which we do here.
if (type.isPresent() && platform.isPresent() && pythonPlatform.isPresent()) {
Preconditions.checkState(type.get().getValue() == Type.EXTENSION);
return createExtensionBuildRule(params.copyReplacingDeclaredAndExtraDeps(Suppliers.ofInstance(ImmutableSortedSet.copyOf(getPlatformDeps(params, ruleResolver, pythonPlatform.get().getValue(), args))), Suppliers.ofInstance(ImmutableSortedSet.of())), ruleResolver, pythonPlatform.get().getValue(), platform.get().getValue(), args);
}
// Otherwise, we return the generic placeholder of this library, that dependents can use
// get the real build rules via querying the action graph.
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(ruleResolver);
final SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
Path baseModule = PythonUtil.getBasePath(params.getBuildTarget(), args.baseModule);
String moduleName = args.moduleName.orElse(params.getBuildTarget().getShortName());
final Path module = baseModule.resolve(getExtensionName(moduleName));
return new CxxPythonExtension(params) {
@Override
protected BuildRule getExtension(PythonPlatform pythonPlatform, CxxPlatform cxxPlatform) throws NoSuchBuildTargetException {
return ruleResolver.requireRule(getBuildTarget().withAppendedFlavors(pythonPlatform.getFlavor(), cxxPlatform.getFlavor(), CxxDescriptionEnhancer.SHARED_FLAVOR));
}
@Override
public Path getModule() {
return module;
}
@Override
public PythonPackageComponents getPythonPackageComponents(PythonPlatform pythonPlatform, CxxPlatform cxxPlatform) throws NoSuchBuildTargetException {
BuildRule extension = getExtension(pythonPlatform, cxxPlatform);
SourcePath output = extension.getSourcePathToOutput();
return PythonPackageComponents.of(ImmutableMap.of(module, output), ImmutableMap.of(), ImmutableMap.of(), ImmutableSet.of(), Optional.of(false));
}
@Override
public NativeLinkTarget getNativeLinkTarget(final PythonPlatform pythonPlatform) {
return new NativeLinkTarget() {
@Override
public BuildTarget getBuildTarget() {
return params.getBuildTarget().withAppendedFlavors(pythonPlatform.getFlavor());
}
@Override
public NativeLinkTargetMode getNativeLinkTargetMode(CxxPlatform cxxPlatform) {
return NativeLinkTargetMode.library();
}
@Override
public Iterable<? extends NativeLinkable> getNativeLinkTargetDeps(CxxPlatform cxxPlatform) {
return FluentIterable.from(getPlatformDeps(params, ruleResolver, pythonPlatform, args)).filter(NativeLinkable.class);
}
@Override
public NativeLinkableInput getNativeLinkTargetInput(CxxPlatform cxxPlatform) throws NoSuchBuildTargetException {
return NativeLinkableInput.builder().addAllArgs(getExtensionArgs(params.withBuildTarget(params.getBuildTarget().withAppendedFlavors(pythonPlatform.getFlavor(), CxxDescriptionEnhancer.SHARED_FLAVOR)).copyReplacingDeclaredAndExtraDeps(Suppliers.ofInstance(ImmutableSortedSet.copyOf(getPlatformDeps(params, ruleResolver, pythonPlatform, args))), Suppliers.ofInstance(ImmutableSortedSet.of())), ruleResolver, pathResolver, ruleFinder, cxxPlatform, args)).addAllFrameworks(args.frameworks).build();
}
@Override
public Optional<Path> getNativeLinkTargetOutputPath(CxxPlatform cxxPlatform) {
return Optional.empty();
}
};
}
@Override
public Stream<BuildTarget> getRuntimeDeps() {
return getDeclaredDeps().stream().map(BuildRule::getBuildTarget);
}
};
}
use of com.facebook.buck.cxx.NativeLinkTarget in project buck by facebook.
the class CxxPythonExtensionDescriptionTest method nativeLinkTargetDeps.
@Test
public void nativeLinkTargetDeps() throws Exception {
BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
CxxLibrary dep = (CxxLibrary) new CxxLibraryBuilder(BuildTargetFactory.newInstance("//:dep")).build(resolver);
CxxPythonExtensionBuilder builder = new CxxPythonExtensionBuilder(BuildTargetFactory.newInstance("//:rule"), FlavorDomain.of("Python Platform", PY2, PY3), new CxxBuckConfig(FakeBuckConfig.builder().build()), CxxTestBuilder.createDefaultPlatforms());
CxxPythonExtension rule = builder.setDeps(ImmutableSortedSet.of(dep.getBuildTarget())).build(resolver);
NativeLinkTarget nativeLinkTarget = rule.getNativeLinkTarget(PY2);
assertThat(ImmutableList.copyOf(nativeLinkTarget.getNativeLinkTargetDeps(CxxPlatformUtils.DEFAULT_PLATFORM)), Matchers.<NativeLinkable>hasItem(dep));
}
use of com.facebook.buck.cxx.NativeLinkTarget in project buck by facebook.
the class CxxPythonExtensionDescriptionTest method nativeLinkTargetInput.
@Test
public void nativeLinkTargetInput() throws Exception {
CxxPythonExtensionBuilder builder = new CxxPythonExtensionBuilder(BuildTargetFactory.newInstance("//:rule"), FlavorDomain.of("Python Platform", PY2, PY3), new CxxBuckConfig(FakeBuckConfig.builder().build()), CxxTestBuilder.createDefaultPlatforms());
builder.setLinkerFlags(ImmutableList.of(StringWithMacrosUtils.format("--flag")));
BuildRuleResolver resolver = new BuildRuleResolver(TargetGraphFactory.newInstance(builder.build()), new DefaultTargetNodeToBuildRuleTransformer());
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(resolver));
CxxPythonExtension rule = builder.build(resolver);
NativeLinkTarget nativeLinkTarget = rule.getNativeLinkTarget(PY2);
NativeLinkableInput input = nativeLinkTarget.getNativeLinkTargetInput(CxxPlatformUtils.DEFAULT_PLATFORM);
assertThat(Arg.stringify(input.getArgs(), pathResolver), Matchers.hasItems("--flag"));
}
Aggregations