Search in sources :

Example 1 with SourcePathArg

use of com.facebook.buck.rules.args.SourcePathArg in project buck by facebook.

the class SwiftLibraryIntegrationTest method testSwiftCompileAndLinkArgs.

@Test
public void testSwiftCompileAndLinkArgs() throws NoSuchBuildTargetException {
    BuildTarget buildTarget = BuildTargetFactory.newInstance("//foo:bar#iphoneos-x86_64");
    BuildTarget swiftCompileTarget = buildTarget.withAppendedFlavors(SwiftLibraryDescription.SWIFT_COMPILE_FLAVOR);
    BuildRuleParams params = new FakeBuildRuleParamsBuilder(swiftCompileTarget).build();
    SwiftLibraryDescription.Arg args = createDummySwiftArg();
    SwiftCompile buildRule = (SwiftCompile) FakeAppleRuleDescriptions.SWIFT_LIBRARY_DESCRIPTION.createBuildRule(TargetGraph.EMPTY, params, resolver, args);
    resolver.addToIndex(buildRule);
    ImmutableList<Arg> astArgs = buildRule.getAstLinkArgs();
    assertThat(astArgs, Matchers.hasSize(3));
    assertThat(astArgs.get(0), Matchers.equalTo(StringArg.of("-Xlinker")));
    assertThat(astArgs.get(1), Matchers.equalTo(StringArg.of("-add_ast_path")));
    assertThat(astArgs.get(2), Matchers.instanceOf(SourcePathArg.class));
    SourcePathArg sourcePathArg = (SourcePathArg) astArgs.get(2);
    assertThat(sourcePathArg.getPath(), Matchers.equalTo(new ExplicitBuildTargetSourcePath(swiftCompileTarget, pathResolver.getRelativePath(buildRule.getSourcePathToOutput()).resolve("bar.swiftmodule"))));
    Arg objArg = buildRule.getFileListLinkArg();
    assertThat(objArg, Matchers.instanceOf(FileListableLinkerInputArg.class));
    FileListableLinkerInputArg fileListArg = (FileListableLinkerInputArg) objArg;
    ExplicitBuildTargetSourcePath fileListSourcePath = new ExplicitBuildTargetSourcePath(swiftCompileTarget, pathResolver.getRelativePath(buildRule.getSourcePathToOutput()).resolve("bar.o"));
    assertThat(fileListArg.getPath(), Matchers.equalTo(fileListSourcePath));
    BuildTarget linkTarget = buildTarget.withAppendedFlavors(CxxDescriptionEnhancer.SHARED_FLAVOR);
    CxxLink linkRule = (CxxLink) FakeAppleRuleDescriptions.SWIFT_LIBRARY_DESCRIPTION.createBuildRule(TargetGraphFactory.newInstance(FakeTargetNodeBuilder.build(buildRule)), params.withBuildTarget(linkTarget), resolver, args);
    assertThat(linkRule.getArgs(), Matchers.hasItem(objArg));
    assertThat(linkRule.getArgs(), Matchers.not(Matchers.hasItem(SourcePathArg.of(fileListSourcePath))));
}
Also used : SourcePathArg(com.facebook.buck.rules.args.SourcePathArg) BuildRuleParams(com.facebook.buck.rules.BuildRuleParams) FileListableLinkerInputArg(com.facebook.buck.rules.args.FileListableLinkerInputArg) BuildTarget(com.facebook.buck.model.BuildTarget) SourcePathArg(com.facebook.buck.rules.args.SourcePathArg) StringArg(com.facebook.buck.rules.args.StringArg) FileListableLinkerInputArg(com.facebook.buck.rules.args.FileListableLinkerInputArg) Arg(com.facebook.buck.rules.args.Arg) FakeBuildRuleParamsBuilder(com.facebook.buck.rules.FakeBuildRuleParamsBuilder) CxxLink(com.facebook.buck.cxx.CxxLink) ExplicitBuildTargetSourcePath(com.facebook.buck.rules.ExplicitBuildTargetSourcePath) Test(org.junit.Test)

Example 2 with SourcePathArg

use of com.facebook.buck.rules.args.SourcePathArg in project buck by facebook.

the class CxxLibrary method getNativeLinkableInputUncached.

public NativeLinkableInput getNativeLinkableInputUncached(CxxPlatform cxxPlatform, Linker.LinkableDepType type) throws NoSuchBuildTargetException {
    if (!isPlatformSupported(cxxPlatform)) {
        return NativeLinkableInput.of();
    }
    // Build up the arguments used to link this library.  If we're linking the
    // whole archive, wrap the library argument in the necessary "ld" flags.
    ImmutableList.Builder<Arg> linkerArgsBuilder = ImmutableList.builder();
    linkerArgsBuilder.addAll(Preconditions.checkNotNull(exportedLinkerFlags.apply(cxxPlatform)));
    if (!headerOnly.apply(cxxPlatform) && propagateLinkables) {
        boolean isStatic;
        switch(linkage) {
            case STATIC:
                isStatic = true;
                break;
            case SHARED:
                isStatic = false;
                break;
            case ANY:
                isStatic = type != Linker.LinkableDepType.SHARED;
                break;
            default:
                throw new IllegalStateException("unhandled linkage type: " + linkage);
        }
        if (isStatic) {
            Archive archive = (Archive) requireBuildRule(cxxPlatform.getFlavor(), type == Linker.LinkableDepType.STATIC ? CxxDescriptionEnhancer.STATIC_FLAVOR : CxxDescriptionEnhancer.STATIC_PIC_FLAVOR);
            if (linkWhole) {
                Linker linker = cxxPlatform.getLd().resolve(ruleResolver);
                linkerArgsBuilder.addAll(linker.linkWhole(archive.toArg()));
            } else {
                Arg libraryArg = archive.toArg();
                if (libraryArg instanceof SourcePathArg) {
                    linkerArgsBuilder.add(FileListableLinkerInputArg.withSourcePathArg((SourcePathArg) libraryArg));
                } else {
                    linkerArgsBuilder.add(libraryArg);
                }
            }
        } else {
            BuildRule rule = requireBuildRule(cxxPlatform.getFlavor(), cxxPlatform.getSharedLibraryInterfaceFactory().isPresent() ? CxxLibraryDescription.Type.SHARED_INTERFACE.getFlavor() : CxxLibraryDescription.Type.SHARED.getFlavor());
            linkerArgsBuilder.add(SourcePathArg.of(Preconditions.checkNotNull(rule.getSourcePathToOutput())));
        }
    }
    final ImmutableList<Arg> linkerArgs = linkerArgsBuilder.build();
    return NativeLinkableInput.of(linkerArgs, Preconditions.checkNotNull(frameworks), Preconditions.checkNotNull(libraries));
}
Also used : SourcePathArg(com.facebook.buck.rules.args.SourcePathArg) ImmutableList(com.google.common.collect.ImmutableList) SourcePathArg(com.facebook.buck.rules.args.SourcePathArg) FileListableLinkerInputArg(com.facebook.buck.rules.args.FileListableLinkerInputArg) Arg(com.facebook.buck.rules.args.Arg) BuildRule(com.facebook.buck.rules.BuildRule) NoopBuildRule(com.facebook.buck.rules.NoopBuildRule)

Example 3 with SourcePathArg

use of com.facebook.buck.rules.args.SourcePathArg in project buck by facebook.

the class PrebuiltCxxLibraryDescription method createBuildRule.

@Override
public <A extends Arg> BuildRule createBuildRule(TargetGraph targetGraph, final BuildRuleParams params, final BuildRuleResolver ruleResolver, final A args) throws NoSuchBuildTargetException {
    // See if we're building a particular "type" of this library, and if so, extract
    // it as an enum.
    Optional<Map.Entry<Flavor, Type>> type = LIBRARY_TYPE.getFlavorAndValue(params.getBuildTarget());
    Optional<Map.Entry<Flavor, CxxPlatform>> platform = cxxPlatforms.getFlavorAndValue(params.getBuildTarget());
    Optional<ImmutableMap<BuildTarget, Version>> selectedVersions = targetGraph.get(params.getBuildTarget()).getSelectedVersions();
    final Optional<String> versionSubdir = selectedVersions.isPresent() && args.versionedSubDir.isPresent() ? Optional.of(args.versionedSubDir.get().getOnlyMatchingValue(selectedVersions.get())) : Optional.empty();
    // pre-existing static lib, which we do here.
    if (type.isPresent()) {
        Preconditions.checkState(platform.isPresent());
        BuildTarget baseTarget = params.getBuildTarget().withoutFlavors(type.get().getKey(), platform.get().getKey());
        if (type.get().getValue() == Type.EXPORTED_HEADERS) {
            return createExportedHeaderSymlinkTreeBuildRule(params, ruleResolver, platform.get().getValue(), args);
        } else if (type.get().getValue() == Type.SHARED) {
            return createSharedLibraryBuildRule(params, ruleResolver, platform.get().getValue(), selectedVersions, args);
        } else if (type.get().getValue() == Type.SHARED_INTERFACE) {
            return createSharedLibraryInterface(baseTarget, params, ruleResolver, platform.get().getValue(), versionSubdir, args);
        }
    }
    if (selectedVersions.isPresent() && args.versionedSubDir.isPresent()) {
        ImmutableList<String> versionSubDirs = args.versionedSubDir.orElse(VersionMatchedCollection.<String>of()).getMatchingValues(selectedVersions.get());
        if (versionSubDirs.size() != 1) {
            throw new HumanReadableException("%s: could not get a single version sub dir: %s, %s, %s", params.getBuildTarget(), args.versionedSubDir, versionSubDirs, selectedVersions);
        }
    }
    // Otherwise, we return the generic placeholder of this library, that dependents can use
    // get the real build rules via querying the action graph.
    final SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(ruleResolver));
    final boolean headerOnly = args.headerOnly.orElse(false);
    final boolean forceStatic = args.forceStatic.orElse(false);
    return new PrebuiltCxxLibrary(params) {

        private final Map<Pair<Flavor, Linker.LinkableDepType>, NativeLinkableInput> nativeLinkableCache = new HashMap<>();

        private final LoadingCache<CxxPreprocessables.CxxPreprocessorInputCacheKey, ImmutableMap<BuildTarget, CxxPreprocessorInput>> transitiveCxxPreprocessorInputCache = CxxPreprocessables.getTransitiveCxxPreprocessorInputCache(this);

        private boolean hasHeaders(CxxPlatform cxxPlatform) {
            if (!args.exportedHeaders.isEmpty()) {
                return true;
            }
            for (SourceList sourceList : args.exportedPlatformHeaders.getMatchingValues(cxxPlatform.getFlavor().toString())) {
                if (!sourceList.isEmpty()) {
                    return true;
                }
            }
            return false;
        }

        private ImmutableListMultimap<CxxSource.Type, String> getExportedPreprocessorFlags(CxxPlatform cxxPlatform) {
            return CxxFlags.getLanguageFlags(args.exportedPreprocessorFlags, args.exportedPlatformPreprocessorFlags, args.exportedLangPreprocessorFlags, cxxPlatform);
        }

        @Override
        public ImmutableList<String> getExportedLinkerFlags(CxxPlatform cxxPlatform) {
            return CxxFlags.getFlagsWithPlatformMacroExpansion(args.exportedLinkerFlags, args.exportedPlatformLinkerFlags, cxxPlatform);
        }

        private String getSoname(CxxPlatform cxxPlatform) {
            return PrebuiltCxxLibraryDescription.getSoname(getBuildTarget(), params.getCellRoots(), ruleResolver, cxxPlatform, args.soname, args.libName);
        }

        private boolean isPlatformSupported(CxxPlatform cxxPlatform) {
            return !args.supportedPlatformsRegex.isPresent() || args.supportedPlatformsRegex.get().matcher(cxxPlatform.getFlavor().toString()).find();
        }

        /**
       * Makes sure all build rules needed to produce the shared library are added to the action
       * graph.
       *
       * @return the {@link SourcePath} representing the actual shared library.
       */
        private SourcePath requireSharedLibrary(CxxPlatform cxxPlatform, boolean link) throws NoSuchBuildTargetException {
            if (link && args.supportsSharedLibraryInterface && cxxPlatform.getSharedLibraryInterfaceFactory().isPresent()) {
                BuildTarget target = params.getBuildTarget().withAppendedFlavors(cxxPlatform.getFlavor(), Type.SHARED_INTERFACE.getFlavor());
                BuildRule rule = ruleResolver.requireRule(target);
                return Preconditions.checkNotNull(rule.getSourcePathToOutput());
            }
            return PrebuiltCxxLibraryDescription.this.requireSharedLibrary(params.getBuildTarget(), ruleResolver, pathResolver, params.getCellRoots(), params.getProjectFilesystem(), cxxPlatform, versionSubdir, args);
        }

        /**
       * @return the {@link Optional} containing a {@link SourcePath} representing the actual
       * static PIC library.
       */
        private Optional<SourcePath> getStaticPicLibrary(CxxPlatform cxxPlatform) {
            SourcePath staticPicLibraryPath = PrebuiltCxxLibraryDescription.getStaticPicLibraryPath(getBuildTarget(), params.getCellRoots(), params.getProjectFilesystem(), ruleResolver, cxxPlatform, versionSubdir, args.libDir, args.libName);
            if (params.getProjectFilesystem().exists(pathResolver.getAbsolutePath(staticPicLibraryPath))) {
                return Optional.of(staticPicLibraryPath);
            }
            // If a specific static-pic variant isn't available, then just use the static variant.
            SourcePath staticLibraryPath = PrebuiltCxxLibraryDescription.getStaticLibraryPath(getBuildTarget(), params.getCellRoots(), getProjectFilesystem(), ruleResolver, cxxPlatform, versionSubdir, args.libDir, args.libName);
            if (params.getProjectFilesystem().exists(pathResolver.getAbsolutePath(staticLibraryPath))) {
                return Optional.of(staticLibraryPath);
            }
            return Optional.empty();
        }

        @Override
        public Iterable<? extends CxxPreprocessorDep> getCxxPreprocessorDeps(CxxPlatform cxxPlatform) {
            if (!isPlatformSupported(cxxPlatform)) {
                return ImmutableList.of();
            }
            return FluentIterable.from(getDeps()).filter(CxxPreprocessorDep.class);
        }

        @Override
        public CxxPreprocessorInput getCxxPreprocessorInput(final CxxPlatform cxxPlatform, HeaderVisibility headerVisibility) throws NoSuchBuildTargetException {
            CxxPreprocessorInput.Builder builder = CxxPreprocessorInput.builder();
            switch(headerVisibility) {
                case PUBLIC:
                    if (hasHeaders(cxxPlatform)) {
                        CxxPreprocessables.addHeaderSymlinkTree(builder, getBuildTarget(), ruleResolver, cxxPlatform, headerVisibility, CxxPreprocessables.IncludeType.SYSTEM);
                    }
                    builder.putAllPreprocessorFlags(Preconditions.checkNotNull(getExportedPreprocessorFlags(cxxPlatform)));
                    builder.addAllFrameworks(args.frameworks);
                    final Iterable<SourcePath> includePaths = args.includeDirs.stream().map(input -> PrebuiltCxxLibraryDescription.getApplicableSourcePath(params.getBuildTarget(), params.getCellRoots(), params.getProjectFilesystem(), ruleResolver, cxxPlatform, versionSubdir, input, Optional.empty())).collect(MoreCollectors.toImmutableList());
                    for (SourcePath includePath : includePaths) {
                        builder.addIncludes(CxxHeadersDir.of(CxxPreprocessables.IncludeType.SYSTEM, includePath));
                    }
                    return builder.build();
                case PRIVATE:
                    return builder.build();
            }
            // want the compiler to warn if someone modifies the HeaderVisibility enum.
            throw new RuntimeException("Invalid header visibility: " + headerVisibility);
        }

        @Override
        public Optional<HeaderSymlinkTree> getExportedHeaderSymlinkTree(CxxPlatform cxxPlatform) {
            if (hasHeaders(cxxPlatform)) {
                return Optional.of(CxxPreprocessables.requireHeaderSymlinkTreeForLibraryTarget(ruleResolver, getBuildTarget(), cxxPlatform.getFlavor()));
            } else {
                return Optional.empty();
            }
        }

        @Override
        public ImmutableMap<BuildTarget, CxxPreprocessorInput> getTransitiveCxxPreprocessorInput(CxxPlatform cxxPlatform, HeaderVisibility headerVisibility) throws NoSuchBuildTargetException {
            return transitiveCxxPreprocessorInputCache.getUnchecked(ImmutableCxxPreprocessorInputCacheKey.of(cxxPlatform, headerVisibility));
        }

        @Override
        public Iterable<NativeLinkable> getNativeLinkableDeps() {
            return getDeclaredDeps().stream().filter(r -> r instanceof NativeLinkable).map(r -> (NativeLinkable) r).collect(MoreCollectors.toImmutableList());
        }

        @Override
        public Iterable<NativeLinkable> getNativeLinkableDepsForPlatform(CxxPlatform cxxPlatform) {
            if (!isPlatformSupported(cxxPlatform)) {
                return ImmutableList.of();
            }
            return getNativeLinkableDeps();
        }

        @Override
        public Iterable<? extends NativeLinkable> getNativeLinkableExportedDeps() {
            return args.exportedDeps.stream().map(ruleResolver::getRule).filter(r -> r instanceof NativeLinkable).map(r -> (NativeLinkable) r).collect(MoreCollectors.toImmutableList());
        }

        @Override
        public Iterable<? extends NativeLinkable> getNativeLinkableExportedDepsForPlatform(CxxPlatform cxxPlatform) {
            if (!isPlatformSupported(cxxPlatform)) {
                return ImmutableList.of();
            }
            return getNativeLinkableExportedDeps();
        }

        private NativeLinkableInput getNativeLinkableInputUncached(CxxPlatform cxxPlatform, Linker.LinkableDepType type) throws NoSuchBuildTargetException {
            if (!isPlatformSupported(cxxPlatform)) {
                return NativeLinkableInput.of();
            }
            // Build the library path and linker arguments that we pass through the
            // {@link NativeLinkable} interface for linking.
            ImmutableList.Builder<com.facebook.buck.rules.args.Arg> linkerArgsBuilder = ImmutableList.builder();
            linkerArgsBuilder.addAll(StringArg.from(Preconditions.checkNotNull(getExportedLinkerFlags(cxxPlatform))));
            if (!headerOnly) {
                if (type == Linker.LinkableDepType.SHARED) {
                    Preconditions.checkState(getPreferredLinkage(cxxPlatform) != Linkage.STATIC);
                    final SourcePath sharedLibrary = requireSharedLibrary(cxxPlatform, true);
                    if (args.linkWithoutSoname) {
                        if (!(sharedLibrary instanceof PathSourcePath)) {
                            throw new HumanReadableException("%s: can only link prebuilt DSOs without sonames", getBuildTarget());
                        }
                        linkerArgsBuilder.add(new RelativeLinkArg((PathSourcePath) sharedLibrary));
                    } else {
                        linkerArgsBuilder.add(SourcePathArg.of(requireSharedLibrary(cxxPlatform, true)));
                    }
                } else {
                    Preconditions.checkState(getPreferredLinkage(cxxPlatform) != Linkage.SHARED);
                    SourcePath staticLibraryPath = type == Linker.LinkableDepType.STATIC_PIC ? getStaticPicLibrary(cxxPlatform).get() : PrebuiltCxxLibraryDescription.getStaticLibraryPath(getBuildTarget(), params.getCellRoots(), params.getProjectFilesystem(), ruleResolver, cxxPlatform, versionSubdir, args.libDir, args.libName);
                    SourcePathArg staticLibrary = SourcePathArg.of(staticLibraryPath);
                    if (args.linkWhole) {
                        Linker linker = cxxPlatform.getLd().resolve(ruleResolver);
                        linkerArgsBuilder.addAll(linker.linkWhole(staticLibrary));
                    } else {
                        linkerArgsBuilder.add(FileListableLinkerInputArg.withSourcePathArg(staticLibrary));
                    }
                }
            }
            final ImmutableList<com.facebook.buck.rules.args.Arg> linkerArgs = linkerArgsBuilder.build();
            return NativeLinkableInput.of(linkerArgs, args.frameworks, args.libraries);
        }

        @Override
        public NativeLinkableInput getNativeLinkableInput(CxxPlatform cxxPlatform, Linker.LinkableDepType type) throws NoSuchBuildTargetException {
            Pair<Flavor, Linker.LinkableDepType> key = new Pair<>(cxxPlatform.getFlavor(), type);
            NativeLinkableInput input = nativeLinkableCache.get(key);
            if (input == null) {
                input = getNativeLinkableInputUncached(cxxPlatform, type);
                nativeLinkableCache.put(key, input);
            }
            return input;
        }

        @Override
        public NativeLinkable.Linkage getPreferredLinkage(CxxPlatform cxxPlatform) {
            if (headerOnly) {
                return Linkage.ANY;
            }
            if (forceStatic) {
                return Linkage.STATIC;
            }
            if (args.provided || !getStaticPicLibrary(cxxPlatform).isPresent()) {
                return Linkage.SHARED;
            }
            return Linkage.ANY;
        }

        @Override
        public Iterable<AndroidPackageable> getRequiredPackageables() {
            return AndroidPackageableCollector.getPackageableRules(params.getDeps());
        }

        @Override
        public void addToCollector(AndroidPackageableCollector collector) {
            if (args.canBeAsset) {
                collector.addNativeLinkableAsset(this);
            } else {
                collector.addNativeLinkable(this);
            }
        }

        @Override
        public ImmutableMap<String, SourcePath> getSharedLibraries(CxxPlatform cxxPlatform) throws NoSuchBuildTargetException {
            if (!isPlatformSupported(cxxPlatform)) {
                return ImmutableMap.of();
            }
            String resolvedSoname = getSoname(cxxPlatform);
            ImmutableMap.Builder<String, SourcePath> solibs = ImmutableMap.builder();
            if (!headerOnly && !args.provided) {
                SourcePath sharedLibrary = requireSharedLibrary(cxxPlatform, false);
                solibs.put(resolvedSoname, sharedLibrary);
            }
            return solibs.build();
        }

        @Override
        public Optional<NativeLinkTarget> getNativeLinkTarget(CxxPlatform cxxPlatform) {
            if (getPreferredLinkage(cxxPlatform) == Linkage.SHARED) {
                return Optional.empty();
            }
            return Optional.of(new NativeLinkTarget() {

                @Override
                public BuildTarget getBuildTarget() {
                    return params.getBuildTarget();
                }

                @Override
                public NativeLinkTargetMode getNativeLinkTargetMode(CxxPlatform cxxPlatform) {
                    return NativeLinkTargetMode.library(getSoname(cxxPlatform));
                }

                @Override
                public Iterable<? extends NativeLinkable> getNativeLinkTargetDeps(CxxPlatform cxxPlatform) {
                    return Iterables.concat(getNativeLinkableDepsForPlatform(cxxPlatform), getNativeLinkableExportedDepsForPlatform(cxxPlatform));
                }

                @Override
                public NativeLinkableInput getNativeLinkTargetInput(CxxPlatform cxxPlatform) throws NoSuchBuildTargetException {
                    return NativeLinkableInput.builder().addAllArgs(StringArg.from(getExportedLinkerFlags(cxxPlatform))).addAllArgs(cxxPlatform.getLd().resolve(ruleResolver).linkWhole(SourcePathArg.of(getStaticPicLibrary(cxxPlatform).get()))).build();
                }

                @Override
                public Optional<Path> getNativeLinkTargetOutputPath(CxxPlatform cxxPlatform) {
                    return Optional.empty();
                }
            });
        }
    };
}
Also used : LoadingCache(com.google.common.cache.LoadingCache) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) PatternMatchedCollection(com.facebook.buck.rules.coercer.PatternMatchedCollection) AndroidPackageableCollector(com.facebook.buck.android.AndroidPackageableCollector) InternalFlavor(com.facebook.buck.model.InternalFlavor) ProjectFilesystem(com.facebook.buck.io.ProjectFilesystem) FlavorDomain(com.facebook.buck.model.FlavorDomain) VersionMatchedCollection(com.facebook.buck.rules.coercer.VersionMatchedCollection) FluentIterable(com.google.common.collect.FluentIterable) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) MacroFinder(com.facebook.buck.model.MacroFinder) StringArg(com.facebook.buck.rules.args.StringArg) Map(java.util.Map) Pair(com.facebook.buck.model.Pair) SourceList(com.facebook.buck.rules.coercer.SourceList) BuildRuleParams(com.facebook.buck.rules.BuildRuleParams) Path(java.nio.file.Path) Optionals(com.facebook.buck.util.Optionals) ImmutableSet(com.google.common.collect.ImmutableSet) FlavorConvertible(com.facebook.buck.model.FlavorConvertible) ImmutableMap(com.google.common.collect.ImmutableMap) TargetGraph(com.facebook.buck.rules.TargetGraph) Version(com.facebook.buck.versions.Version) MacroException(com.facebook.buck.model.MacroException) BuildTarget(com.facebook.buck.model.BuildTarget) SuppressFieldNotInitialized(com.facebook.infer.annotation.SuppressFieldNotInitialized) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) PathSourcePath(com.facebook.buck.rules.PathSourcePath) Optional(java.util.Optional) BuildRuleResolver(com.facebook.buck.rules.BuildRuleResolver) Pattern(java.util.regex.Pattern) Description(com.facebook.buck.rules.Description) Iterables(com.google.common.collect.Iterables) CellPathResolver(com.facebook.buck.rules.CellPathResolver) SourcePathArg(com.facebook.buck.rules.args.SourcePathArg) FrameworkPath(com.facebook.buck.rules.coercer.FrameworkPath) SourcePath(com.facebook.buck.rules.SourcePath) HashMap(java.util.HashMap) VersionPropagator(com.facebook.buck.versions.VersionPropagator) BuildRule(com.facebook.buck.rules.BuildRule) ImmutableList(com.google.common.collect.ImmutableList) NoSuchBuildTargetException(com.facebook.buck.parser.NoSuchBuildTargetException) ImplicitDepsInferringDescription(com.facebook.buck.rules.ImplicitDepsInferringDescription) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) StringExpander(com.facebook.buck.rules.macros.StringExpander) MoreCollectors(com.facebook.buck.util.MoreCollectors) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) FileListableLinkerInputArg(com.facebook.buck.rules.args.FileListableLinkerInputArg) ExplicitBuildTargetSourcePath(com.facebook.buck.rules.ExplicitBuildTargetSourcePath) AndroidPackageable(com.facebook.buck.android.AndroidPackageable) HumanReadableException(com.facebook.buck.util.HumanReadableException) AbstractDescriptionArg(com.facebook.buck.rules.AbstractDescriptionArg) Paths(java.nio.file.Paths) LocationMacroExpander(com.facebook.buck.rules.macros.LocationMacroExpander) Preconditions(com.google.common.base.Preconditions) Flavor(com.facebook.buck.model.Flavor) MacroHandler(com.facebook.buck.rules.macros.MacroHandler) BuildTargets(com.facebook.buck.model.BuildTargets) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) ExplicitBuildTargetSourcePath(com.facebook.buck.rules.ExplicitBuildTargetSourcePath) BuildTarget(com.facebook.buck.model.BuildTarget) LoadingCache(com.google.common.cache.LoadingCache) BuildRule(com.facebook.buck.rules.BuildRule) SourcePathArg(com.facebook.buck.rules.args.SourcePathArg) Optional(java.util.Optional) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) InternalFlavor(com.facebook.buck.model.InternalFlavor) Flavor(com.facebook.buck.model.Flavor) ImmutableMap(com.google.common.collect.ImmutableMap) AndroidPackageableCollector(com.facebook.buck.android.AndroidPackageableCollector) StringArg(com.facebook.buck.rules.args.StringArg) SourcePathArg(com.facebook.buck.rules.args.SourcePathArg) FileListableLinkerInputArg(com.facebook.buck.rules.args.FileListableLinkerInputArg) AbstractDescriptionArg(com.facebook.buck.rules.AbstractDescriptionArg) NoSuchBuildTargetException(com.facebook.buck.parser.NoSuchBuildTargetException) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) FluentIterable(com.google.common.collect.FluentIterable) ImmutableList(com.google.common.collect.ImmutableList) Pair(com.facebook.buck.model.Pair) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) AndroidPackageable(com.facebook.buck.android.AndroidPackageable) HumanReadableException(com.facebook.buck.util.HumanReadableException) SourceList(com.facebook.buck.rules.coercer.SourceList)

Example 4 with SourcePathArg

use of com.facebook.buck.rules.args.SourcePathArg in project buck by facebook.

the class RustLibraryDescription method createBuildRule.

@Override
public <A extends Arg> BuildRule createBuildRule(TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, A args) throws NoSuchBuildTargetException {
    final BuildTarget buildTarget = params.getBuildTarget();
    SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
    SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
    ImmutableList.Builder<String> rustcArgs = ImmutableList.builder();
    RustCompileUtils.addFeatures(buildTarget, args.features, rustcArgs);
    rustcArgs.addAll(args.rustcFlags);
    rustcArgs.addAll(rustBuckConfig.getRustLibraryFlags());
    String crate = args.crate.orElse(ruleToCrateName(params.getBuildTarget().getShortName()));
    // See if we're building a particular "type" and "platform" of this library, and if so, extract
    // them from the flavors attached to the build target.
    Optional<Map.Entry<Flavor, RustDescriptionEnhancer.Type>> type = LIBRARY_TYPE.getFlavorAndValue(buildTarget);
    Optional<CxxPlatform> cxxPlatform = cxxPlatforms.getValue(buildTarget);
    if (type.isPresent()) {
        // Uncommon case - someone explicitly invoked buck to build a specific flavor as the
        // direct target.
        CrateType crateType = type.get().getValue().getCrateType();
        Linker.LinkableDepType depType;
        if (crateType.isDynamic()) {
            depType = Linker.LinkableDepType.SHARED;
        } else {
            if (crateType.isPic()) {
                depType = Linker.LinkableDepType.STATIC_PIC;
            } else {
                depType = Linker.LinkableDepType.STATIC;
            }
        }
        return requireBuild(params, resolver, pathResolver, ruleFinder, cxxPlatform.orElse(defaultCxxPlatform), rustBuckConfig, rustcArgs.build(), /* linkerArgs */
        ImmutableList.of(), /* linkerInputs */
        ImmutableList.of(), crate, crateType, depType, args);
    }
    // Common case - we're being invoked to satisfy some other rule's dependency.
    return new RustLibrary(params) {

        // RustLinkable
        @Override
        public com.facebook.buck.rules.args.Arg getLinkerArg(boolean direct, CxxPlatform cxxPlatform, Linker.LinkableDepType depType) {
            BuildRule rule;
            CrateType crateType;
            // the use of -rpath will break with flavored paths containing ','.
            switch(args.preferredLinkage) {
                case ANY:
                default:
                    switch(depType) {
                        case SHARED:
                            crateType = CrateType.DYLIB;
                            break;
                        case STATIC_PIC:
                            crateType = CrateType.RLIB_PIC;
                            break;
                        case STATIC:
                        default:
                            crateType = CrateType.RLIB;
                            break;
                    }
                    break;
                case SHARED:
                    crateType = CrateType.DYLIB;
                    break;
                case STATIC:
                    if (depType == Linker.LinkableDepType.STATIC) {
                        crateType = CrateType.RLIB;
                    } else {
                        crateType = CrateType.RLIB_PIC;
                    }
                    break;
            }
            try {
                rule = requireBuild(params, resolver, pathResolver, ruleFinder, cxxPlatform, rustBuckConfig, rustcArgs.build(), /* linkerArgs */
                ImmutableList.of(), /* linkerInputs */
                ImmutableList.of(), crate, crateType, depType, args);
            } catch (NoSuchBuildTargetException e) {
                throw new RuntimeException(e);
            }
            SourcePath rlib = rule.getSourcePathToOutput();
            return new RustLibraryArg(pathResolver, crate, rlib, direct, params.getDeps());
        }

        @Override
        public Linkage getPreferredLinkage() {
            return args.preferredLinkage;
        }

        @Override
        public ImmutableMap<String, SourcePath> getRustSharedLibraries(CxxPlatform cxxPlatform) throws NoSuchBuildTargetException {
            ImmutableMap.Builder<String, SourcePath> libs = ImmutableMap.builder();
            String sharedLibrarySoname = CrateType.DYLIB.filenameFor(crate, cxxPlatform);
            BuildRule sharedLibraryBuildRule = requireBuild(params, resolver, pathResolver, ruleFinder, cxxPlatform, rustBuckConfig, rustcArgs.build(), /* linkerArgs */
            ImmutableList.of(), /* linkerInputs */
            ImmutableList.of(), crate, CrateType.DYLIB, Linker.LinkableDepType.SHARED, args);
            libs.put(sharedLibrarySoname, sharedLibraryBuildRule.getSourcePathToOutput());
            return libs.build();
        }

        // NativeLinkable
        @Override
        public Iterable<? extends NativeLinkable> getNativeLinkableDeps() {
            return ImmutableList.of();
        }

        @Override
        public Iterable<? extends NativeLinkable> getNativeLinkableExportedDeps() {
            return FluentIterable.from(getDeps()).filter(NativeLinkable.class);
        }

        @Override
        public NativeLinkableInput getNativeLinkableInput(CxxPlatform cxxPlatform, Linker.LinkableDepType depType) throws NoSuchBuildTargetException {
            CrateType crateType;
            switch(depType) {
                case SHARED:
                    crateType = CrateType.CDYLIB;
                    break;
                case STATIC_PIC:
                    crateType = CrateType.STATIC_PIC;
                    break;
                case STATIC:
                default:
                    crateType = CrateType.STATIC;
                    break;
            }
            BuildRule rule = requireBuild(params, resolver, pathResolver, ruleFinder, cxxPlatform, rustBuckConfig, rustcArgs.build(), /* linkerArgs */
            ImmutableList.of(), /* linkerInputs */
            ImmutableList.of(), crate, crateType, depType, args);
            SourcePath lib = rule.getSourcePathToOutput();
            SourcePathArg arg = SourcePathArg.of(lib);
            return NativeLinkableInput.builder().addArgs(arg).build();
        }

        @Override
        public Linkage getPreferredLinkage(CxxPlatform cxxPlatform) {
            return args.preferredLinkage;
        }

        @Override
        public ImmutableMap<String, SourcePath> getSharedLibraries(CxxPlatform cxxPlatform) throws NoSuchBuildTargetException {
            ImmutableMap.Builder<String, SourcePath> libs = ImmutableMap.builder();
            String sharedLibrarySoname = CxxDescriptionEnhancer.getSharedLibrarySoname(Optional.empty(), getBuildTarget(), cxxPlatform);
            BuildRule sharedLibraryBuildRule = requireBuild(params, resolver, pathResolver, ruleFinder, cxxPlatform, rustBuckConfig, rustcArgs.build(), /* linkerArgs */
            ImmutableList.of(), /* linkerInputs */
            ImmutableList.of(), crate, CrateType.CDYLIB, Linker.LinkableDepType.SHARED, args);
            libs.put(sharedLibrarySoname, sharedLibraryBuildRule.getSourcePathToOutput());
            return libs.build();
        }
    };
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) SourcePath(com.facebook.buck.rules.SourcePath) BuildTarget(com.facebook.buck.model.BuildTarget) BuildRule(com.facebook.buck.rules.BuildRule) SourcePathArg(com.facebook.buck.rules.args.SourcePathArg) CxxPlatform(com.facebook.buck.cxx.CxxPlatform) Linker(com.facebook.buck.cxx.Linker) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) ImmutableMap(com.google.common.collect.ImmutableMap) NoSuchBuildTargetException(com.facebook.buck.parser.NoSuchBuildTargetException)

Aggregations

SourcePathArg (com.facebook.buck.rules.args.SourcePathArg)4 BuildTarget (com.facebook.buck.model.BuildTarget)3 BuildRule (com.facebook.buck.rules.BuildRule)3 FileListableLinkerInputArg (com.facebook.buck.rules.args.FileListableLinkerInputArg)3 ImmutableList (com.google.common.collect.ImmutableList)3 NoSuchBuildTargetException (com.facebook.buck.parser.NoSuchBuildTargetException)2 BuildRuleParams (com.facebook.buck.rules.BuildRuleParams)2 ExplicitBuildTargetSourcePath (com.facebook.buck.rules.ExplicitBuildTargetSourcePath)2 SourcePath (com.facebook.buck.rules.SourcePath)2 SourcePathResolver (com.facebook.buck.rules.SourcePathResolver)2 SourcePathRuleFinder (com.facebook.buck.rules.SourcePathRuleFinder)2 Arg (com.facebook.buck.rules.args.Arg)2 StringArg (com.facebook.buck.rules.args.StringArg)2 ImmutableMap (com.google.common.collect.ImmutableMap)2 AndroidPackageable (com.facebook.buck.android.AndroidPackageable)1 AndroidPackageableCollector (com.facebook.buck.android.AndroidPackageableCollector)1 CxxLink (com.facebook.buck.cxx.CxxLink)1 CxxPlatform (com.facebook.buck.cxx.CxxPlatform)1 Linker (com.facebook.buck.cxx.Linker)1 ProjectFilesystem (com.facebook.buck.io.ProjectFilesystem)1