use of com.facebook.buck.cxx.NativeLinkableInput in project buck by facebook.
the class NdkLibraryDescription method generateMakefile.
/**
* @return a {@link BuildRule} which generates a Android.mk which pulls in the local Android.mk
* file and also appends relevant preprocessor and linker flags to use C/C++ library deps.
*/
private Pair<String, Iterable<BuildRule>> generateMakefile(BuildRuleParams params, BuildRuleResolver resolver) throws NoSuchBuildTargetException {
SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
ImmutableList.Builder<String> outputLinesBuilder = ImmutableList.builder();
ImmutableSortedSet.Builder<BuildRule> deps = ImmutableSortedSet.naturalOrder();
for (Map.Entry<NdkCxxPlatforms.TargetCpuType, NdkCxxPlatform> entry : cxxPlatforms.entrySet()) {
CxxPlatform cxxPlatform = entry.getValue().getCxxPlatform();
// Collect the preprocessor input for all C/C++ library deps. We search *through* other
// NDK library rules.
CxxPreprocessorInput cxxPreprocessorInput = CxxPreprocessorInput.concat(CxxPreprocessables.getTransitiveCxxPreprocessorInput(cxxPlatform, params.getDeps(), NdkLibrary.class::isInstance));
// We add any dependencies from the C/C++ preprocessor input to this rule, even though
// it technically should be added to the top-level rule.
deps.addAll(cxxPreprocessorInput.getDeps(resolver, ruleFinder));
// Add in the transitive preprocessor flags contributed by C/C++ library rules into the
// NDK build.
ImmutableList.Builder<String> ppFlags = ImmutableList.builder();
ppFlags.addAll(cxxPreprocessorInput.getPreprocessorFlags().get(CxxSource.Type.C));
Preprocessor preprocessor = CxxSourceTypes.getPreprocessor(cxxPlatform, CxxSource.Type.C).resolve(resolver);
ppFlags.addAll(CxxHeaders.getArgs(cxxPreprocessorInput.getIncludes(), pathResolver, Optional.empty(), preprocessor));
String localCflags = Joiner.on(' ').join(escapeForMakefile(params.getProjectFilesystem(), ppFlags.build()));
// Collect the native linkable input for all C/C++ library deps. We search *through* other
// NDK library rules.
NativeLinkableInput nativeLinkableInput = NativeLinkables.getTransitiveNativeLinkableInput(cxxPlatform, params.getDeps(), Linker.LinkableDepType.SHARED, NdkLibrary.class::isInstance);
// We add any dependencies from the native linkable input to this rule, even though
// it technically should be added to the top-level rule.
deps.addAll(nativeLinkableInput.getArgs().stream().flatMap(arg -> arg.getDeps(ruleFinder).stream()).iterator());
// Add in the transitive native linkable flags contributed by C/C++ library rules into the
// NDK build.
String localLdflags = Joiner.on(' ').join(escapeForMakefile(params.getProjectFilesystem(), com.facebook.buck.rules.args.Arg.stringify(nativeLinkableInput.getArgs(), pathResolver)));
// Write the relevant lines to the generated makefile.
if (!localCflags.isEmpty() || !localLdflags.isEmpty()) {
NdkCxxPlatforms.TargetCpuType targetCpuType = entry.getKey();
String targetArchAbi = getTargetArchAbi(targetCpuType);
outputLinesBuilder.add(String.format("ifeq ($(TARGET_ARCH_ABI),%s)", targetArchAbi));
if (!localCflags.isEmpty()) {
outputLinesBuilder.add("BUCK_DEP_CFLAGS=" + localCflags);
}
if (!localLdflags.isEmpty()) {
outputLinesBuilder.add("BUCK_DEP_LDFLAGS=" + localLdflags);
}
outputLinesBuilder.add("endif");
outputLinesBuilder.add("");
}
}
// GCC-only magic that rewrites non-deterministic parts of builds
String ndksubst = NdkCxxPlatforms.ANDROID_NDK_ROOT;
outputLinesBuilder.addAll(ImmutableList.copyOf(new String[] { // We're evaluated once per architecture, but want to add the cflags only once.
"ifeq ($(BUCK_ALREADY_HOOKED_CFLAGS),)", "BUCK_ALREADY_HOOKED_CFLAGS := 1", // Only GCC supports -fdebug-prefix-map
"ifeq ($(filter clang%,$(NDK_TOOLCHAIN_VERSION)),)", // Replace absolute paths with machine-relative ones.
"NDK_APP_CFLAGS += -fdebug-prefix-map=$(NDK_ROOT)/=" + ndksubst + "/", "NDK_APP_CFLAGS += -fdebug-prefix-map=$(abspath $(BUCK_PROJECT_DIR))/=./", // repository root.
"NDK_APP_CFLAGS += -fdebug-prefix-map=$(BUCK_PROJECT_DIR)/=./", "NDK_APP_CFLAGS += -fdebug-prefix-map=./=" + ".$(subst $(abspath $(BUCK_PROJECT_DIR)),,$(abspath $(CURDIR)))/", "NDK_APP_CFLAGS += -fno-record-gcc-switches", "ifeq ($(filter 4.6,$(TOOLCHAIN_VERSION)),)", // headers either.
"NDK_APP_CPPFLAGS += -fno-canonical-system-headers", // detailed command line argument information anyway.
"NDK_APP_CFLAGS += -gno-record-gcc-switches", // !GCC 4.6
"endif", // !clang
"endif", // absolute path, but only for modules under the project root.
"BUCK_SAVED_IMPORTS := $(__ndk_import_dirs)", "__ndk_import_dirs :=", "$(foreach __dir,$(BUCK_SAVED_IMPORTS),\\", "$(call import-add-path-optional,\\", "$(if $(filter $(abspath $(BUCK_PROJECT_DIR))%,$(__dir)),\\", "$(BUCK_PROJECT_DIR)$(patsubst $(abspath $(BUCK_PROJECT_DIR))%,%,$(__dir)),\\", "$(__dir))))", // !already hooked
"endif", // generic paths.
"NDK_APP_CFLAGS += -fdebug-prefix-map=$(TOOLCHAIN_PREBUILT_ROOT)/=" + "@ANDROID_NDK_ROOT@/toolchains/$(TOOLCHAIN_NAME)/prebuilt/@BUILD_HOST@/" }));
outputLinesBuilder.add("include Android.mk");
String contents = Joiner.on(System.lineSeparator()).join(outputLinesBuilder.build());
return new Pair<String, Iterable<BuildRule>>(contents, deps.build());
}
use of com.facebook.buck.cxx.NativeLinkableInput in project buck by facebook.
the class HaskellPrebuiltLibraryDescription method createBuildRule.
@Override
public <A extends Arg> BuildRule createBuildRule(TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, final A args) throws NoSuchBuildTargetException {
return new PrebuiltHaskellLibrary(params) {
private final LoadingCache<CxxPreprocessables.CxxPreprocessorInputCacheKey, ImmutableMap<BuildTarget, CxxPreprocessorInput>> transitiveCxxPreprocessorInputCache = CxxPreprocessables.getTransitiveCxxPreprocessorInputCache(this);
@Override
public HaskellCompileInput getCompileInput(CxxPlatform cxxPlatform, Linker.LinkableDepType depType) throws NoSuchBuildTargetException {
return HaskellCompileInput.builder().addAllFlags(args.exportedCompilerFlags).addPackages(HaskellPackage.builder().setInfo(HaskellPackageInfo.of(getBuildTarget().getShortName(), args.version, args.id.orElse(String.format("%s-%s", getBuildTarget().getShortName(), args.version)))).setPackageDb(args.db).addAllInterfaces(args.importDirs).addAllLibraries(depType == Linker.LinkableDepType.SHARED ? args.sharedLibs.values() : args.staticLibs).build()).build();
}
@Override
public Iterable<? extends NativeLinkable> getNativeLinkableDeps() {
return ImmutableList.of();
}
@Override
public Iterable<? extends NativeLinkable> getNativeLinkableExportedDeps() {
return FluentIterable.from(getDeclaredDeps()).filter(NativeLinkable.class);
}
@Override
public NativeLinkableInput getNativeLinkableInput(CxxPlatform cxxPlatform, Linker.LinkableDepType type) {
NativeLinkableInput.Builder builder = NativeLinkableInput.builder();
builder.addAllArgs(StringArg.from(args.exportedLinkerFlags));
if (type == Linker.LinkableDepType.SHARED) {
builder.addAllArgs(SourcePathArg.from(args.sharedLibs.values()));
} else {
builder.addAllArgs(SourcePathArg.from(args.staticLibs));
}
return builder.build();
}
@Override
public Linkage getPreferredLinkage(CxxPlatform cxxPlatform) {
return Linkage.ANY;
}
@Override
public ImmutableMap<String, SourcePath> getSharedLibraries(CxxPlatform cxxPlatform) {
return args.sharedLibs;
}
@Override
public Iterable<? extends CxxPreprocessorDep> getCxxPreprocessorDeps(CxxPlatform cxxPlatform) {
return FluentIterable.from(getDeps()).filter(CxxPreprocessorDep.class);
}
@Override
public Optional<HeaderSymlinkTree> getExportedHeaderSymlinkTree(CxxPlatform cxxPlatform) {
return Optional.empty();
}
@Override
public CxxPreprocessorInput getCxxPreprocessorInput(CxxPlatform cxxPlatform, HeaderVisibility headerVisibility) throws NoSuchBuildTargetException {
CxxPreprocessorInput.Builder builder = CxxPreprocessorInput.builder();
for (SourcePath headerDir : args.cxxHeaderDirs) {
builder.addIncludes(CxxHeadersDir.of(CxxPreprocessables.IncludeType.SYSTEM, headerDir));
}
return builder.build();
}
@Override
public ImmutableMap<BuildTarget, CxxPreprocessorInput> getTransitiveCxxPreprocessorInput(CxxPlatform cxxPlatform, HeaderVisibility headerVisibility) throws NoSuchBuildTargetException {
return transitiveCxxPreprocessorInputCache.getUnchecked(ImmutableCxxPreprocessorInputCacheKey.of(cxxPlatform, headerVisibility));
}
};
}
use of com.facebook.buck.cxx.NativeLinkableInput in project buck by facebook.
the class OcamlRuleBuilder method getBytecodeLinkableInput.
private static NativeLinkableInput getBytecodeLinkableInput(Iterable<BuildRule> deps) {
List<NativeLinkableInput> inputs = Lists.newArrayList();
// Add in the linkable input from OCaml libraries.
ImmutableList<BuildRule> ocamlDeps = getTransitiveOcamlLibraryDeps(deps);
for (BuildRule dep : ocamlDeps) {
inputs.add(((OcamlLibrary) dep).getBytecodeLinkableInput());
}
return NativeLinkableInput.concat(inputs);
}
use of com.facebook.buck.cxx.NativeLinkableInput in project buck by facebook.
the class OcamlStaticLibrary method getLinkableInput.
private NativeLinkableInput getLinkableInput(boolean isBytecode) {
NativeLinkableInput.Builder inputBuilder = NativeLinkableInput.builder();
// Add linker flags.
inputBuilder.addAllArgs(StringArg.from(linkerFlags));
// Add arg and input for static library.
UnflavoredBuildTarget staticBuildTarget = staticLibraryTarget.getUnflavoredBuildTarget();
inputBuilder.addArgs(SourcePathArg.of(new ExplicitBuildTargetSourcePath(ocamlLibraryBuild.getBuildTarget(), isBytecode ? OcamlBuildContext.getBytecodeOutputPath(staticBuildTarget, getProjectFilesystem(), /* isLibrary */
true) : OcamlBuildContext.getNativeOutputPath(staticBuildTarget, getProjectFilesystem(), /* isLibrary */
true))));
// Add args and inputs for C object files.
for (SourcePath objFile : objFiles) {
inputBuilder.addArgs(SourcePathArg.of(objFile));
}
return inputBuilder.build();
}
use of com.facebook.buck.cxx.NativeLinkableInput in project buck by facebook.
the class SwiftLibrary method getNativeLinkableInput.
@Override
public NativeLinkableInput getNativeLinkableInput(CxxPlatform cxxPlatform, Linker.LinkableDepType type) throws NoSuchBuildTargetException {
SwiftCompile rule = requireSwiftCompileRule(cxxPlatform.getFlavor());
NativeLinkableInput.Builder inputBuilder = NativeLinkableInput.builder();
inputBuilder.addAllArgs(rule.getAstLinkArgs()).addAllFrameworks(frameworks).addAllLibraries(libraries);
boolean isDynamic;
Linkage preferredLinkage = getPreferredLinkage(cxxPlatform);
switch(preferredLinkage) {
case STATIC:
isDynamic = false;
break;
case SHARED:
isDynamic = true;
break;
case ANY:
isDynamic = type == Linker.LinkableDepType.SHARED;
break;
default:
throw new IllegalStateException("unhandled linkage type: " + preferredLinkage);
}
if (isDynamic) {
CxxLink swiftLinkRule = requireSwiftLinkRule(cxxPlatform.getFlavor());
inputBuilder.addArgs(FileListableLinkerInputArg.withSourcePathArg(SourcePathArg.of(swiftLinkRule.getSourcePathToOutput())));
} else {
inputBuilder.addArgs(rule.getFileListLinkArg());
}
return inputBuilder.build();
}
Aggregations