use of com.facebook.buck.cxx.Linker in project buck by facebook.
the class NativeRelinker method makeRelinkerRule.
private RelinkerRule makeRelinkerRule(TargetCpuType cpuType, SourcePath source, ImmutableList<RelinkerRule> relinkerDeps) {
Function<RelinkerRule, SourcePath> getSymbolsNeeded = RelinkerRule::getSymbolsNeededPath;
String libname = resolver.getAbsolutePath(source).getFileName().toString();
BuildRuleParams relinkerParams = buildRuleParams.withAppendedFlavor(InternalFlavor.of("xdso-dce")).withAppendedFlavor(InternalFlavor.of(Flavor.replaceInvalidCharacters(cpuType.toString()))).withAppendedFlavor(InternalFlavor.of(Flavor.replaceInvalidCharacters(libname))).copyAppendingExtraDeps(relinkerDeps);
BuildRule baseRule = ruleFinder.getRule(source).orElse(null);
ImmutableList<Arg> linkerArgs = ImmutableList.of();
Linker linker = null;
if (baseRule != null && baseRule instanceof CxxLink) {
CxxLink link = (CxxLink) baseRule;
linkerArgs = link.getArgs();
linker = link.getLinker();
}
return new RelinkerRule(relinkerParams, resolver, ruleFinder, ImmutableSortedSet.copyOf(Lists.transform(relinkerDeps, getSymbolsNeeded)), cpuType, Preconditions.checkNotNull(nativePlatforms.get(cpuType)).getObjdump(), cxxBuckConfig, source, linker, linkerArgs);
}
use of com.facebook.buck.cxx.Linker in project buck by facebook.
the class HaskellDescriptionUtils method createLinkRule.
/**
* Create a Haskell link rule that links the given inputs to a executable or shared library and
* pulls in transitive native linkable deps from the given dep roots.
*/
public static HaskellLinkRule createLinkRule(BuildTarget target, BuildRuleParams baseParams, BuildRuleResolver resolver, SourcePathRuleFinder ruleFinder, CxxPlatform cxxPlatform, HaskellConfig haskellConfig, Linker.LinkType linkType, ImmutableList<String> extraFlags, Iterable<Arg> linkerInputs, Iterable<? extends NativeLinkable> deps, Linker.LinkableDepType depType) throws NoSuchBuildTargetException {
Tool linker = haskellConfig.getLinker().resolve(resolver);
String name = target.getShortName();
ImmutableList.Builder<Arg> linkerArgsBuilder = ImmutableList.builder();
ImmutableList.Builder<Arg> argsBuilder = ImmutableList.builder();
// Add the base flags from the `.buckconfig` first.
argsBuilder.addAll(StringArg.from(haskellConfig.getLinkerFlags()));
// Pass in the appropriate flags to link a shared library.
if (linkType.equals(Linker.LinkType.SHARED)) {
name = CxxDescriptionEnhancer.getSharedLibrarySoname(Optional.empty(), target.withFlavors(), cxxPlatform);
argsBuilder.addAll(StringArg.from("-shared", "-dynamic"));
argsBuilder.addAll(StringArg.from(MoreIterables.zipAndConcat(Iterables.cycle("-optl"), cxxPlatform.getLd().resolve(resolver).soname(name))));
}
// Add in extra flags passed into this function.
argsBuilder.addAll(StringArg.from(extraFlags));
// We pass in the linker inputs and all native linkable deps by prefixing with `-optl` so that
// the args go straight to the linker, and preserve their order.
linkerArgsBuilder.addAll(linkerInputs);
for (NativeLinkable nativeLinkable : NativeLinkables.getNativeLinkables(cxxPlatform, deps, depType).values()) {
linkerArgsBuilder.addAll(NativeLinkables.getNativeLinkableInput(cxxPlatform, depType, nativeLinkable).getArgs());
}
// Since we use `-optl` to pass all linker inputs directly to the linker, the haskell linker
// will complain about not having any input files. So, create a dummy archive with an empty
// module and pass that in normally to work around this.
BuildTarget emptyModuleTarget = target.withAppendedFlavors(InternalFlavor.of("empty-module"));
WriteFile emptyModule = resolver.addToIndex(new WriteFile(baseParams.withBuildTarget(emptyModuleTarget), "module Unused where", BuildTargets.getGenPath(baseParams.getProjectFilesystem(), emptyModuleTarget, "%s/Unused.hs"), /* executable */
false));
HaskellCompileRule emptyCompiledModule = resolver.addToIndex(createCompileRule(target.withAppendedFlavors(InternalFlavor.of("empty-compiled-module")), baseParams, resolver, ruleFinder, // Buck dependency.
baseParams.getDeps(), cxxPlatform, haskellConfig, depType, Optional.empty(), Optional.empty(), ImmutableList.of(), HaskellSources.builder().putModuleMap("Unused", emptyModule.getSourcePathToOutput()).build()));
BuildTarget emptyArchiveTarget = target.withAppendedFlavors(InternalFlavor.of("empty-archive"));
Archive emptyArchive = resolver.addToIndex(Archive.from(emptyArchiveTarget, baseParams, ruleFinder, cxxPlatform, Archive.Contents.NORMAL, BuildTargets.getGenPath(baseParams.getProjectFilesystem(), emptyArchiveTarget, "%s/libempty.a"), emptyCompiledModule.getObjects()));
argsBuilder.add(SourcePathArg.of(emptyArchive.getSourcePathToOutput()));
ImmutableList<Arg> args = argsBuilder.build();
ImmutableList<Arg> linkerArgs = linkerArgsBuilder.build();
return resolver.addToIndex(new HaskellLinkRule(baseParams.withBuildTarget(target).copyReplacingDeclaredAndExtraDeps(Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>naturalOrder().addAll(linker.getDeps(ruleFinder)).addAll(Stream.of(args, linkerArgs).flatMap(Collection::stream).flatMap(arg -> arg.getDeps(ruleFinder).stream()).iterator()).build()), Suppliers.ofInstance(ImmutableSortedSet.of())), linker, name, args, linkerArgs, haskellConfig.shouldCacheLinks()));
}
use of com.facebook.buck.cxx.Linker in project buck by facebook.
the class PythonInPlaceBinary method getScript.
private static Supplier<String> getScript(final BuildRuleResolver resolver, final PythonPlatform pythonPlatform, final CxxPlatform cxxPlatform, final String mainModule, final PythonPackageComponents components, final Path relativeLinkTreeRoot, final ImmutableSet<String> preloadLibraries) {
final String relativeLinkTreeRootStr = Escaper.escapeAsPythonString(relativeLinkTreeRoot.toString());
final Linker ld = cxxPlatform.getLd().resolve(resolver);
return () -> {
ST st = new ST(getRunInplaceResource()).add("PYTHON", pythonPlatform.getEnvironment().getPythonPath()).add("MAIN_MODULE", Escaper.escapeAsPythonString(mainModule)).add("MODULES_DIR", relativeLinkTreeRootStr);
// Only add platform-specific values when the binary includes native libraries.
if (components.getNativeLibraries().isEmpty()) {
st.add("NATIVE_LIBS_ENV_VAR", "None");
st.add("NATIVE_LIBS_DIR", "None");
} else {
st.add("NATIVE_LIBS_ENV_VAR", Escaper.escapeAsPythonString(ld.searchPathEnvVar()));
st.add("NATIVE_LIBS_DIR", relativeLinkTreeRootStr);
}
if (preloadLibraries.isEmpty()) {
st.add("NATIVE_LIBS_PRELOAD_ENV_VAR", "None");
st.add("NATIVE_LIBS_PRELOAD", "None");
} else {
st.add("NATIVE_LIBS_PRELOAD_ENV_VAR", Escaper.escapeAsPythonString(ld.preloadEnvVar()));
st.add("NATIVE_LIBS_PRELOAD", Escaper.escapeAsPythonString(Joiner.on(':').join(preloadLibraries)));
}
return st.render();
};
}
use of com.facebook.buck.cxx.Linker in project buck by facebook.
the class HaskellLibraryDescriptionTest method linkWhole.
@Test
public void linkWhole() throws Exception {
BuildTarget target = BuildTargetFactory.newInstance("//:rule");
HaskellLibraryBuilder builder = new HaskellLibraryBuilder(target).setLinkWhole(true);
BuildRuleResolver resolver = new BuildRuleResolver(TargetGraphFactory.newInstance(builder.build()), new DefaultTargetNodeToBuildRuleTransformer());
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(resolver));
HaskellLibrary library = builder.build(resolver);
// Lookup the link whole flags.
Linker linker = CxxPlatformUtils.DEFAULT_PLATFORM.getLd().resolve(resolver);
ImmutableList<String> linkWholeFlags = FluentIterable.from(linker.linkWhole(StringArg.of("sentinel"))).transformAndConcat((input) -> Arg.stringifyList(input, pathResolver)).filter(Predicates.not("sentinel"::equals)).toList();
// Test static dep type.
NativeLinkableInput staticInput = library.getNativeLinkableInput(CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC);
assertThat(Arg.stringify(staticInput.getArgs(), pathResolver), hasItems(linkWholeFlags.toArray(new String[linkWholeFlags.size()])));
// Test static-pic dep type.
NativeLinkableInput staticPicInput = library.getNativeLinkableInput(CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC_PIC);
assertThat(Arg.stringify(staticPicInput.getArgs(), pathResolver), hasItems(linkWholeFlags.toArray(new String[linkWholeFlags.size()])));
// Test shared dep type.
NativeLinkableInput sharedInput = library.getNativeLinkableInput(CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.SHARED);
assertThat(Arg.stringify(sharedInput.getArgs(), pathResolver), not(hasItems(linkWholeFlags.toArray(new String[linkWholeFlags.size()]))));
}
Aggregations