Search in sources :

Example 1 with Runfiles

use of com.google.devtools.build.lib.analysis.Runfiles in project bazel by bazelbuild.

the class CcBinary method collectRunfiles.

private static Runfiles collectRunfiles(RuleContext context, CcToolchainProvider toolchain, CcLinkingOutputs linkingOutputs, CcLibraryHelper.Info info, LinkStaticness linkStaticness, NestedSet<Artifact> filesToBuild, Iterable<Artifact> fakeLinkerInputs, boolean fake, ImmutableSet<CppSource> cAndCppSources, boolean linkCompileOutputSeparately) {
    Runfiles.Builder builder = new Runfiles.Builder(context.getWorkspaceName(), context.getConfiguration().legacyExternalRunfiles());
    Function<TransitiveInfoCollection, Runfiles> runfilesMapping = CppRunfilesProvider.runfilesFunction(linkStaticness != LinkStaticness.DYNAMIC);
    builder.addTransitiveArtifacts(filesToBuild);
    // Add the shared libraries to the runfiles. This adds any shared libraries that are in the
    // srcs of this target.
    builder.addArtifacts(linkingOutputs.getLibrariesForRunfiles(true));
    builder.addRunfiles(context, RunfilesProvider.DEFAULT_RUNFILES);
    builder.add(context, runfilesMapping);
    // Add the C++ runtime libraries if linking them dynamically.
    if (linkStaticness == LinkStaticness.DYNAMIC) {
        builder.addTransitiveArtifacts(toolchain.getDynamicRuntimeLinkInputs());
    }
    if (linkCompileOutputSeparately) {
        builder.addArtifacts(LinkerInputs.toLibraryArtifacts(info.getCcLinkingOutputs().getExecutionDynamicLibraries()));
    }
    // For cc_binary and cc_test rules, there is an implicit dependency on
    // the malloc library package, which is specified by the "malloc" attribute.
    // As the BUILD encyclopedia says, the "malloc" attribute should be ignored
    // if linkshared=1.
    boolean linkshared = isLinkShared(context);
    if (!linkshared) {
        TransitiveInfoCollection malloc = CppHelper.mallocForTarget(context);
        builder.addTarget(malloc, RunfilesProvider.DEFAULT_RUNFILES);
        builder.addTarget(malloc, runfilesMapping);
    }
    if (fake) {
        // Add the object files, libraries, and linker scripts that are used to
        // link this executable.
        builder.addSymlinksToArtifacts(Iterables.filter(fakeLinkerInputs, Artifact.MIDDLEMAN_FILTER));
        // The crosstool inputs for the link action are not sufficient; we also need the crosstool
        // inputs for compilation. Node that these cannot be middlemen because Runfiles does not
        // know how to expand them.
        builder.addTransitiveArtifacts(toolchain.getCrosstool());
        builder.addTransitiveArtifacts(toolchain.getLibcLink());
        // Add the sources files that are used to compile the object files.
        // We add the headers in the transitive closure and our own sources in the srcs
        // attribute. We do not provide the auxiliary inputs, because they are only used when we
        // do FDO compilation, and cc_fake_binary does not support FDO.
        ImmutableSet.Builder<Artifact> sourcesBuilder = ImmutableSet.<Artifact>builder();
        for (CppSource cppSource : cAndCppSources) {
            sourcesBuilder.add(cppSource.getSource());
        }
        builder.addSymlinksToArtifacts(sourcesBuilder.build());
        CppCompilationContext cppCompilationContext = info.getCppCompilationContext();
        builder.addSymlinksToArtifacts(cppCompilationContext.getDeclaredIncludeSrcs());
        // Add additional files that are referenced from the compile command, like module maps
        // or header modules.
        builder.addSymlinksToArtifacts(cppCompilationContext.getAdditionalInputs());
        builder.addSymlinksToArtifacts(cppCompilationContext.getTransitiveModules(CppHelper.usePic(context, !isLinkShared(context))));
    }
    return builder.build();
}
Also used : Runfiles(com.google.devtools.build.lib.analysis.Runfiles) ImmutableSet(com.google.common.collect.ImmutableSet) NestedSetBuilder(com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder) TransitiveInfoCollection(com.google.devtools.build.lib.analysis.TransitiveInfoCollection) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 2 with Runfiles

use of com.google.devtools.build.lib.analysis.Runfiles in project bazel by bazelbuild.

the class CcBinary method init.

public static ConfiguredTarget init(CppSemantics semantics, RuleContext ruleContext, boolean fake) throws InterruptedException, RuleErrorException {
    ruleContext.checkSrcsSamePackage(true);
    CcCommon common = new CcCommon(ruleContext);
    CcToolchainProvider ccToolchain = common.getToolchain();
    FdoSupportProvider fdoSupport = common.getFdoSupport();
    FeatureConfiguration featureConfiguration = CcCommon.configureFeatures(ruleContext, ccToolchain);
    CppConfiguration cppConfiguration = ruleContext.getFragment(CppConfiguration.class);
    PrecompiledFiles precompiledFiles = new PrecompiledFiles(ruleContext);
    LinkTargetType linkType = isLinkShared(ruleContext) ? LinkTargetType.DYNAMIC_LIBRARY : LinkTargetType.EXECUTABLE;
    semantics.validateAttributes(ruleContext);
    if (ruleContext.hasErrors()) {
        return null;
    }
    List<String> linkopts = common.getLinkopts();
    LinkStaticness linkStaticness = getLinkStaticness(ruleContext, linkopts, cppConfiguration);
    // We currently only want link the dynamic library generated for test code separately.
    boolean linkCompileOutputSeparately = ruleContext.isTestTarget() && cppConfiguration.getLinkCompileOutputSeparately() && linkStaticness == LinkStaticness.DYNAMIC;
    CcLibraryHelper helper = new CcLibraryHelper(ruleContext, semantics, featureConfiguration, ccToolchain, fdoSupport).fromCommon(common).addSources(common.getSources()).addDeps(ImmutableList.of(CppHelper.mallocForTarget(ruleContext))).setFake(fake).addPrecompiledFiles(precompiledFiles).enableInterfaceSharedObjects();
    // When linking the object files directly into the resulting binary, we do not need
    // library-level link outputs; thus, we do not let CcLibraryHelper produce link outputs
    // (either shared object files or archives) for a non-library link type [*], and add
    // the object files explicitly in determineLinkerArguments.
    //
    // When linking the object files into their own library, we want CcLibraryHelper to
    // take care of creating the library link outputs for us, so we need to set the link
    // type to STATIC_LIBRARY.
    //
    // [*] The only library link type is STATIC_LIBRARY. EXECUTABLE specifies a normal
    // cc_binary output, while DYNAMIC_LIBRARY is a cc_binary rules that produces an
    // output matching a shared object, for example cc_binary(name="foo.so", ...) on linux.
    helper.setLinkType(linkCompileOutputSeparately ? LinkTargetType.STATIC_LIBRARY : linkType);
    CcLibraryHelper.Info info = helper.build();
    CppCompilationContext cppCompilationContext = info.getCppCompilationContext();
    CcCompilationOutputs ccCompilationOutputs = info.getCcCompilationOutputs();
    // if cc_binary includes "linkshared=1", then gcc will be invoked with
    // linkopt "-shared", which causes the result of linking to be a shared
    // library. In this case, the name of the executable target should end
    // in ".so" or "dylib" or ".dll".
    PathFragment binaryPath = new PathFragment(ruleContext.getTarget().getName());
    if (!isLinkShared(ruleContext)) {
        binaryPath = new PathFragment(binaryPath.getPathString() + OsUtils.executableExtension());
    }
    Artifact binary = ruleContext.getBinArtifact(binaryPath);
    if (isLinkShared(ruleContext) && !CppFileTypes.SHARED_LIBRARY.matches(binary.getFilename()) && !CppFileTypes.VERSIONED_SHARED_LIBRARY.matches(binary.getFilename())) {
        ruleContext.attributeError("linkshared", "'linkshared' used in non-shared library");
        return null;
    }
    CppLinkActionBuilder linkActionBuilder = determineLinkerArguments(ruleContext, ccToolchain, fdoSupport, common, precompiledFiles, info, cppCompilationContext.getTransitiveCompilationPrerequisites(), fake, binary, linkStaticness, linkopts, linkCompileOutputSeparately);
    linkActionBuilder.setUseTestOnlyFlags(ruleContext.isTestTarget());
    if (linkStaticness == LinkStaticness.DYNAMIC) {
        linkActionBuilder.setRuntimeInputs(ArtifactCategory.DYNAMIC_LIBRARY, ccToolchain.getDynamicRuntimeLinkMiddleman(), ccToolchain.getDynamicRuntimeLinkInputs());
    } else {
        linkActionBuilder.setRuntimeInputs(ArtifactCategory.STATIC_LIBRARY, ccToolchain.getStaticRuntimeLinkMiddleman(), ccToolchain.getStaticRuntimeLinkInputs());
        // TODO(bazel-team): Move this to CcToolchain.
        if (!ccToolchain.getStaticRuntimeLinkInputs().isEmpty()) {
            linkActionBuilder.addLinkopt("-static-libgcc");
        }
    }
    linkActionBuilder.setLinkType(linkType);
    linkActionBuilder.setLinkStaticness(linkStaticness);
    linkActionBuilder.setFake(fake);
    linkActionBuilder.setFeatureConfiguration(featureConfiguration);
    if (CppLinkAction.enableSymbolsCounts(cppConfiguration, fake, linkType)) {
        linkActionBuilder.setSymbolCountsOutput(ruleContext.getBinArtifact(CppLinkAction.symbolCountsFileName(binaryPath)));
    }
    if (isLinkShared(ruleContext)) {
        linkActionBuilder.setLibraryIdentifier(CcLinkingOutputs.libraryIdentifierOf(binary));
    }
    // Store immutable context for use in other *_binary rules that are implemented by
    // linking the interpreter (Java, Python, etc.) together with native deps.
    CppLinkAction.Context linkContext = new CppLinkAction.Context(linkActionBuilder);
    Iterable<LTOBackendArtifacts> ltoBackendArtifacts = ImmutableList.of();
    boolean usePic = CppHelper.usePic(ruleContext, !isLinkShared(ruleContext));
    if (featureConfiguration.isEnabled(CppRuleClasses.THIN_LTO)) {
        linkActionBuilder.setLTOIndexing(true);
        linkActionBuilder.setUsePicForLTOBackendActions(usePic);
        linkActionBuilder.setUseFissionForLTOBackendActions(cppConfiguration.useFission());
        CppLinkAction indexAction = linkActionBuilder.build();
        ruleContext.registerAction(indexAction);
        ltoBackendArtifacts = indexAction.getAllLTOBackendArtifacts();
        linkActionBuilder.setLTOIndexing(false);
    }
    CppLinkAction linkAction = linkActionBuilder.build();
    ruleContext.registerAction(linkAction);
    LibraryToLink outputLibrary = linkAction.getOutputLibrary();
    Iterable<Artifact> fakeLinkerInputs = fake ? linkAction.getInputs() : ImmutableList.<Artifact>of();
    Artifact executable = linkAction.getLinkOutput();
    CcLinkingOutputs.Builder linkingOutputsBuilder = new CcLinkingOutputs.Builder();
    if (isLinkShared(ruleContext)) {
        linkingOutputsBuilder.addDynamicLibrary(outputLibrary);
        linkingOutputsBuilder.addExecutionDynamicLibrary(outputLibrary);
    }
    // Also add all shared libraries from srcs.
    for (Artifact library : precompiledFiles.getSharedLibraries()) {
        Artifact symlink = common.getDynamicLibrarySymlink(library, true);
        LibraryToLink symlinkLibrary = LinkerInputs.solibLibraryToLink(symlink, library, CcLinkingOutputs.libraryIdentifierOf(library));
        linkingOutputsBuilder.addDynamicLibrary(symlinkLibrary);
        linkingOutputsBuilder.addExecutionDynamicLibrary(symlinkLibrary);
    }
    CcLinkingOutputs linkingOutputs = linkingOutputsBuilder.build();
    NestedSet<Artifact> filesToBuild = NestedSetBuilder.create(Order.STABLE_ORDER, executable);
    // Create the stripped binary, but don't add it to filesToBuild; it's only built when requested.
    Artifact strippedFile = ruleContext.getImplicitOutputArtifact(CppRuleClasses.CC_BINARY_STRIPPED);
    CppHelper.createStripAction(ruleContext, ccToolchain, cppConfiguration, executable, strippedFile);
    DwoArtifactsCollector dwoArtifacts = collectTransitiveDwoArtifacts(ruleContext, ccCompilationOutputs, linkStaticness, cppConfiguration.useFission(), usePic, ltoBackendArtifacts);
    Artifact dwpFile = ruleContext.getImplicitOutputArtifact(CppRuleClasses.CC_BINARY_DEBUG_PACKAGE);
    createDebugPackagerActions(ruleContext, ccToolchain, cppConfiguration, dwpFile, dwoArtifacts);
    // The debug package should include the dwp file only if it was explicitly requested.
    Artifact explicitDwpFile = dwpFile;
    if (!cppConfiguration.useFission()) {
        explicitDwpFile = null;
    } else {
        // built statically.
        if (TargetUtils.isTestRule(ruleContext.getRule()) && linkStaticness != LinkStaticness.DYNAMIC && cppConfiguration.shouldBuildTestDwp()) {
            filesToBuild = NestedSetBuilder.fromNestedSet(filesToBuild).add(dwpFile).build();
        }
    }
    // TODO(bazel-team): Do we need to put original shared libraries (along with
    // mangled symlinks) into the RunfilesSupport object? It does not seem
    // logical since all symlinked libraries will be linked anyway and would
    // not require manual loading but if we do, then we would need to collect
    // their names and use a different constructor below.
    Runfiles runfiles = collectRunfiles(ruleContext, ccToolchain, linkingOutputs, info, linkStaticness, filesToBuild, fakeLinkerInputs, fake, helper.getCompilationUnitSources(), linkCompileOutputSeparately);
    RunfilesSupport runfilesSupport = RunfilesSupport.withExecutable(ruleContext, runfiles, executable, ruleContext.getConfiguration().buildRunfiles());
    TransitiveLipoInfoProvider transitiveLipoInfo;
    if (cppConfiguration.isLipoContextCollector()) {
        transitiveLipoInfo = common.collectTransitiveLipoLabels(ccCompilationOutputs);
    } else {
        transitiveLipoInfo = TransitiveLipoInfoProvider.EMPTY;
    }
    RuleConfiguredTargetBuilder ruleBuilder = new RuleConfiguredTargetBuilder(ruleContext);
    addTransitiveInfoProviders(ruleContext, cppConfiguration, common, ruleBuilder, filesToBuild, ccCompilationOutputs, cppCompilationContext, linkingOutputs, dwoArtifacts, transitiveLipoInfo, fake);
    Map<Artifact, IncludeScannable> scannableMap = new LinkedHashMap<>();
    Map<PathFragment, Artifact> sourceFileMap = new LinkedHashMap<>();
    if (cppConfiguration.isLipoContextCollector()) {
        for (IncludeScannable scannable : transitiveLipoInfo.getTransitiveIncludeScannables()) {
            // These should all be CppCompileActions, which should have only one source file.
            // This is also checked when they are put into the nested set.
            Artifact source = Iterables.getOnlyElement(scannable.getIncludeScannerSources());
            scannableMap.put(source, scannable);
            sourceFileMap.put(source.getExecPath(), source);
        }
    }
    // Support test execution on darwin.
    if (Platform.isApplePlatform(cppConfiguration.getTargetCpu()) && TargetUtils.isTestRule(ruleContext.getRule())) {
        ruleBuilder.addNativeDeclaredProvider(new ExecutionInfoProvider(ImmutableMap.of(ExecutionRequirements.REQUIRES_DARWIN, "")));
    }
    return ruleBuilder.addProvider(RunfilesProvider.class, RunfilesProvider.simple(runfiles)).addProvider(CppDebugPackageProvider.class, new CppDebugPackageProvider(ruleContext.getLabel(), strippedFile, executable, explicitDwpFile)).setRunfilesSupport(runfilesSupport, executable).addProvider(LipoContextProvider.class, new LipoContextProvider(cppCompilationContext, ImmutableMap.copyOf(scannableMap), ImmutableMap.copyOf(sourceFileMap))).addProvider(CppLinkAction.Context.class, linkContext).addSkylarkTransitiveInfo(CcSkylarkApiProvider.NAME, new CcSkylarkApiProvider()).build();
}
Also used : NestedSetBuilder(com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) LinkedHashMap(java.util.LinkedHashMap) ExecutionInfoProvider(com.google.devtools.build.lib.rules.test.ExecutionInfoProvider) RunfilesSupport(com.google.devtools.build.lib.analysis.RunfilesSupport) RuleContext(com.google.devtools.build.lib.analysis.RuleContext) FeatureConfiguration(com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration) Artifact(com.google.devtools.build.lib.actions.Artifact) LinkTargetType(com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType) LibraryToLink(com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink) Runfiles(com.google.devtools.build.lib.analysis.Runfiles) LinkStaticness(com.google.devtools.build.lib.rules.cpp.Link.LinkStaticness) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)

Example 3 with Runfiles

use of com.google.devtools.build.lib.analysis.Runfiles in project bazel by bazelbuild.

the class CcLibrary method init.

public static void init(CppSemantics semantics, RuleContext ruleContext, RuleConfiguredTargetBuilder targetBuilder, LinkTargetType linkType, boolean neverLink, boolean linkStatic, boolean collectLinkstamp, boolean addDynamicRuntimeInputArtifactsToRunfiles) throws RuleErrorException, InterruptedException {
    final CcCommon common = new CcCommon(ruleContext);
    CcToolchainProvider ccToolchain = common.getToolchain();
    FdoSupportProvider fdoSupport = common.getFdoSupport();
    FeatureConfiguration featureConfiguration = CcCommon.configureFeatures(ruleContext, ccToolchain);
    PrecompiledFiles precompiledFiles = new PrecompiledFiles(ruleContext);
    semantics.validateAttributes(ruleContext);
    if (ruleContext.hasErrors()) {
        return;
    }
    CcLibraryHelper helper = new CcLibraryHelper(ruleContext, semantics, featureConfiguration, ccToolchain, fdoSupport).fromCommon(common).addLinkopts(common.getLinkopts()).addSources(common.getSources()).addPublicHeaders(common.getHeaders()).enableCcNativeLibrariesProvider().enableCompileProviders().enableInterfaceSharedObjects().setGenerateLinkActionsIfEmpty(ruleContext.getRule().getImplicitOutputsFunction() != ImplicitOutputsFunction.NONE).setLinkType(linkType).setNeverLink(neverLink).addPrecompiledFiles(precompiledFiles);
    if (collectLinkstamp) {
        helper.addLinkstamps(ruleContext.getPrerequisites("linkstamp", Mode.TARGET));
    }
    Artifact soImplArtifact = null;
    boolean supportsDynamicLinker = ruleContext.getFragment(CppConfiguration.class).supportsDynamicLinker();
    // TODO(djasper): This is hacky. We should actually try to figure out whether we generate
    // ccOutputs.
    boolean createDynamicLibrary = !linkStatic && supportsDynamicLinker && (appearsToHaveObjectFiles(ruleContext.attributes()) || featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULE_CODEGEN));
    if (ruleContext.getRule().isAttrDefined("outs", Type.STRING_LIST)) {
        List<String> outs = ruleContext.attributes().get("outs", Type.STRING_LIST);
        if (outs.size() > 1) {
            ruleContext.attributeError("outs", "must be a singleton list");
        } else if (outs.size() == 1) {
            PathFragment soImplFilename = new PathFragment(ruleContext.getLabel().getName());
            soImplFilename = soImplFilename.replaceName(outs.get(0));
            if (!soImplFilename.getPathString().endsWith(".so")) {
                // Sanity check.
                ruleContext.attributeError("outs", "file name must end in '.so'");
            }
            if (createDynamicLibrary) {
                soImplArtifact = ruleContext.getBinArtifact(soImplFilename);
            }
        }
    }
    if (ruleContext.getRule().isAttrDefined("srcs", BuildType.LABEL_LIST)) {
        ruleContext.checkSrcsSamePackage(true);
    }
    if (ruleContext.getRule().isAttrDefined("textual_hdrs", BuildType.LABEL_LIST)) {
        helper.addPublicTextualHeaders(ruleContext.getPrerequisiteArtifacts("textual_hdrs", Mode.TARGET).list());
    }
    if (common.getLinkopts().contains("-static")) {
        ruleContext.attributeWarning("linkopts", "Using '-static' here won't work. " + "Did you mean to use 'linkstatic=1' instead?");
    }
    helper.setCreateDynamicLibrary(createDynamicLibrary);
    helper.setDynamicLibrary(soImplArtifact);
    // which only happens when some rule explicitly depends on the dynamic library.
    if (!createDynamicLibrary && !supportsDynamicLinker) {
        Artifact solibArtifact = CppHelper.getLinuxLinkedArtifact(ruleContext, ruleContext.getConfiguration(), LinkTargetType.DYNAMIC_LIBRARY);
        ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(), ImmutableList.of(solibArtifact), "Toolchain does not support dynamic linking"));
    } else if (!createDynamicLibrary && ruleContext.attributes().isConfigurable("srcs")) {
        // If "srcs" is configurable, the .so output is always declared because the logic that
        // determines implicit outs doesn't know which value of "srcs" will ultimately get chosen.
        // Here, where we *do* have the correct value, it may not contain any source files to
        // generate an .so with. If that's the case, register a fake generating action to prevent
        // a "no generating action for this artifact" error.
        Artifact solibArtifact = CppHelper.getLinuxLinkedArtifact(ruleContext, ruleContext.getConfiguration(), LinkTargetType.DYNAMIC_LIBRARY);
        ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(), ImmutableList.of(solibArtifact), "configurable \"srcs\" triggers an implicit .so output " + "even though there are no sources to compile in this configuration"));
    }
    /*
     * Add the libraries from srcs, if any. For static/mostly static
     * linking we setup the dynamic libraries if there are no static libraries
     * to choose from. Path to the libraries will be mangled to avoid using
     * absolute path names on the -rpath, but library filenames will be
     * preserved (since some libraries might have SONAME tag) - symlink will
     * be created to the parent directory instead.
     *
     * For compatibility with existing BUILD files, any ".a" or ".lo" files listed in
     * srcs are assumed to be position-independent code, or at least suitable for
     * inclusion in shared libraries, unless they end with ".nopic.a" or ".nopic.lo".
     *
     * Note that some target platforms do not require shared library code to be PIC.
     */
    Iterable<LibraryToLink> staticLibrariesFromSrcs = LinkerInputs.opaqueLibrariesToLink(ArtifactCategory.STATIC_LIBRARY, precompiledFiles.getStaticLibraries());
    Iterable<LibraryToLink> alwayslinkLibrariesFromSrcs = LinkerInputs.opaqueLibrariesToLink(ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY, precompiledFiles.getAlwayslinkStaticLibraries());
    Iterable<LibraryToLink> picStaticLibrariesFromSrcs = LinkerInputs.opaqueLibrariesToLink(ArtifactCategory.STATIC_LIBRARY, precompiledFiles.getPicStaticLibraries());
    Iterable<LibraryToLink> picAlwayslinkLibrariesFromSrcs = LinkerInputs.opaqueLibrariesToLink(ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY, precompiledFiles.getPicAlwayslinkLibraries());
    helper.addStaticLibraries(staticLibrariesFromSrcs);
    helper.addStaticLibraries(alwayslinkLibrariesFromSrcs);
    helper.addPicStaticLibraries(picStaticLibrariesFromSrcs);
    helper.addPicStaticLibraries(picAlwayslinkLibrariesFromSrcs);
    helper.addDynamicLibraries(Iterables.transform(precompiledFiles.getSharedLibraries(), new Function<Artifact, LibraryToLink>() {

        @Override
        public LibraryToLink apply(Artifact library) {
            return LinkerInputs.solibLibraryToLink(common.getDynamicLibrarySymlink(library, true), library, CcLinkingOutputs.libraryIdentifierOf(library));
        }
    }));
    CcLibraryHelper.Info info = helper.build();
    /*
     * We always generate a static library, even if there aren't any source files.
     * This keeps things simpler by avoiding special cases when making use of the library.
     * For example, this is needed to ensure that building a library with "bazel build"
     * will also build all of the library's "deps".
     * However, we only generate a dynamic library if there are source files.
     */
    // For now, we don't add the precompiled libraries to the files to build.
    CcLinkingOutputs linkedLibraries = info.getCcLinkingOutputsExcludingPrecompiledLibraries();
    NestedSetBuilder<Artifact> filesBuilder = NestedSetBuilder.stableOrder();
    filesBuilder.addAll(LinkerInputs.toLibraryArtifacts(linkedLibraries.getStaticLibraries()));
    filesBuilder.addAll(LinkerInputs.toLibraryArtifacts(linkedLibraries.getPicStaticLibraries()));
    filesBuilder.addAll(LinkerInputs.toNonSolibArtifacts(linkedLibraries.getDynamicLibraries()));
    filesBuilder.addAll(LinkerInputs.toNonSolibArtifacts(linkedLibraries.getExecutionDynamicLibraries()));
    CcLinkingOutputs linkingOutputs = info.getCcLinkingOutputs();
    if (!featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULE_CODEGEN)) {
        warnAboutEmptyLibraries(ruleContext, info.getCcCompilationOutputs(), linkStatic);
    }
    NestedSet<Artifact> filesToBuild = filesBuilder.build();
    Runfiles staticRunfiles = collectRunfiles(ruleContext, linkingOutputs, ccToolchain, neverLink, addDynamicRuntimeInputArtifactsToRunfiles, true);
    Runfiles sharedRunfiles = collectRunfiles(ruleContext, linkingOutputs, ccToolchain, neverLink, addDynamicRuntimeInputArtifactsToRunfiles, false);
    List<Artifact> instrumentedObjectFiles = new ArrayList<>();
    instrumentedObjectFiles.addAll(info.getCcCompilationOutputs().getObjectFiles(false));
    instrumentedObjectFiles.addAll(info.getCcCompilationOutputs().getObjectFiles(true));
    InstrumentedFilesProvider instrumentedFilesProvider = common.getInstrumentedFilesProvider(instrumentedObjectFiles, /*withBaselineCoverage=*/
    true);
    CppHelper.maybeAddStaticLinkMarkerProvider(targetBuilder, ruleContext);
    targetBuilder.setFilesToBuild(filesToBuild).addProviders(info.getProviders()).addSkylarkTransitiveInfo(CcSkylarkApiProvider.NAME, new CcSkylarkApiProvider()).addOutputGroups(info.getOutputGroups()).addProvider(InstrumentedFilesProvider.class, instrumentedFilesProvider).addProvider(RunfilesProvider.class, RunfilesProvider.withData(staticRunfiles, sharedRunfiles)).addProvider(CppRunfilesProvider.class, new CppRunfilesProvider(staticRunfiles, sharedRunfiles)).addOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL, collectHiddenTopLevelArtifacts(ruleContext, info.getCcCompilationOutputs())).addOutputGroup(CcLibraryHelper.HIDDEN_HEADER_TOKENS, CcLibraryHelper.collectHeaderTokens(ruleContext, info.getCcCompilationOutputs()));
}
Also used : FailAction(com.google.devtools.build.lib.actions.FailAction) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) ArrayList(java.util.ArrayList) Function(com.google.common.base.Function) ImplicitOutputsFunction(com.google.devtools.build.lib.packages.ImplicitOutputsFunction) InstrumentedFilesProvider(com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider) FeatureConfiguration(com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration) RunfilesProvider(com.google.devtools.build.lib.analysis.RunfilesProvider) Artifact(com.google.devtools.build.lib.actions.Artifact) LibraryToLink(com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink) Runfiles(com.google.devtools.build.lib.analysis.Runfiles)

Example 4 with Runfiles

use of com.google.devtools.build.lib.analysis.Runfiles in project bazel by bazelbuild.

the class JavaBinary method create.

@Override
public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException, RuleErrorException {
    final JavaCommon common = new JavaCommon(ruleContext, semantics);
    DeployArchiveBuilder deployArchiveBuilder = new DeployArchiveBuilder(semantics, ruleContext);
    Runfiles.Builder runfilesBuilder = new Runfiles.Builder(ruleContext.getWorkspaceName(), ruleContext.getConfiguration().legacyExternalRunfiles());
    List<String> jvmFlags = new ArrayList<>();
    JavaTargetAttributes.Builder attributesBuilder = common.initCommon();
    attributesBuilder.addClassPathResources(ruleContext.getPrerequisiteArtifacts("classpath_resources", Mode.TARGET).list());
    // Add Java8 timezone resource data
    addTimezoneResourceForJavaBinaries(ruleContext, attributesBuilder);
    List<String> userJvmFlags = JavaCommon.getJvmFlags(ruleContext);
    ruleContext.checkSrcsSamePackage(true);
    boolean createExecutable = ruleContext.attributes().get("create_executable", Type.BOOLEAN);
    if (!createExecutable) {
        // TODO(cushon): disallow combining launcher=JDK_LAUNCHER_LABEL with create_executable=0
        // and use isAttributeExplicitlySpecified here
        Label launcherAttribute = ruleContext.attributes().get("launcher", BuildType.LABEL);
        if (launcherAttribute != null && !JavaHelper.isJdkLauncher(ruleContext, launcherAttribute)) {
            ruleContext.ruleError("launcher specified but create_executable is false");
        }
    }
    semantics.checkRule(ruleContext, common);
    semantics.checkForProtoLibraryAndJavaProtoLibraryOnSameProto(ruleContext, common);
    String mainClass = semantics.getMainClass(ruleContext, common.getSrcsArtifacts());
    String originalMainClass = mainClass;
    if (ruleContext.hasErrors()) {
        return null;
    }
    // Collect the transitive dependencies.
    JavaCompilationHelper helper = new JavaCompilationHelper(ruleContext, semantics, common.getJavacOpts(), attributesBuilder);
    List<TransitiveInfoCollection> deps = // Do not remove <TransitiveInfoCollection>: workaround for Java 7 type inference.
    Lists.<TransitiveInfoCollection>newArrayList(common.targetsTreatedAsDeps(ClasspathType.COMPILE_ONLY));
    helper.addLibrariesToAttributes(deps);
    attributesBuilder.addNativeLibraries(collectNativeLibraries(common.targetsTreatedAsDeps(ClasspathType.BOTH)));
    // deploy_env is valid for java_binary, but not for java_test.
    if (ruleContext.getRule().isAttrDefined("deploy_env", BuildType.LABEL_LIST)) {
        for (JavaRuntimeClasspathProvider envTarget : ruleContext.getPrerequisites("deploy_env", Mode.TARGET, JavaRuntimeClasspathProvider.class)) {
            attributesBuilder.addExcludedArtifacts(envTarget.getRuntimeClasspath());
        }
    }
    Artifact srcJar = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_SOURCE_JAR);
    JavaSourceJarsProvider.Builder javaSourceJarsProviderBuilder = JavaSourceJarsProvider.builder().addSourceJar(srcJar).addAllTransitiveSourceJars(common.collectTransitiveSourceJars(srcJar));
    Artifact classJar = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_CLASS_JAR);
    JavaRuleOutputJarsProvider.Builder ruleOutputJarsProviderBuilder = JavaRuleOutputJarsProvider.builder().addOutputJar(classJar, null, /* iJar */
    ImmutableList.of(srcJar));
    CppConfiguration cppConfiguration = ruleContext.getConfiguration().getFragment(CppConfiguration.class);
    boolean stripAsDefault = cppConfiguration.useFission() && cppConfiguration.getCompilationMode() == CompilationMode.OPT;
    Artifact launcher = semantics.getLauncher(ruleContext, common, deployArchiveBuilder, runfilesBuilder, jvmFlags, attributesBuilder, stripAsDefault);
    DeployArchiveBuilder unstrippedDeployArchiveBuilder = null;
    Artifact unstrippedLauncher = null;
    if (stripAsDefault) {
        unstrippedDeployArchiveBuilder = new DeployArchiveBuilder(semantics, ruleContext);
        unstrippedLauncher = semantics.getLauncher(ruleContext, common, unstrippedDeployArchiveBuilder, runfilesBuilder, jvmFlags, attributesBuilder, false);
    }
    JavaCompilationArtifacts.Builder javaArtifactsBuilder = new JavaCompilationArtifacts.Builder();
    Artifact instrumentationMetadata = helper.createInstrumentationMetadata(classJar, javaArtifactsBuilder);
    NestedSetBuilder<Artifact> filesBuilder = NestedSetBuilder.stableOrder();
    Artifact executableForRunfiles = null;
    if (createExecutable) {
        // This artifact is named as the rule itself, e.g. //foo:bar_bin -> bazel-bin/foo/bar_bin
        executableForRunfiles = ruleContext.createOutputArtifact();
        filesBuilder.add(classJar).add(executableForRunfiles);
        if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
            mainClass = semantics.addCoverageSupport(helper, attributesBuilder, executableForRunfiles, instrumentationMetadata, javaArtifactsBuilder, mainClass);
        }
    } else {
        filesBuilder.add(classJar);
    }
    JavaTargetAttributes attributes = helper.getAttributes();
    List<Artifact> nativeLibraries = attributes.getNativeLibraries();
    if (!nativeLibraries.isEmpty()) {
        jvmFlags.add("-Djava.library.path=" + JavaCommon.javaLibraryPath(nativeLibraries, ruleContext.getRule().getPackage().getWorkspaceName()));
    }
    JavaConfiguration javaConfig = ruleContext.getFragment(JavaConfiguration.class);
    if (attributes.hasMessages()) {
        helper.setTranslations(semantics.translate(ruleContext, javaConfig, attributes.getMessages()));
    }
    if (attributes.hasSourceFiles() || attributes.hasSourceJars() || attributes.hasResources() || attributes.hasClassPathResources()) {
        // We only want to add a jar to the classpath of a dependent rule if it has content.
        javaArtifactsBuilder.addRuntimeJar(classJar);
    }
    GeneratedExtensionRegistryProvider generatedExtensionRegistryProvider = semantics.createGeneratedExtensionRegistry(ruleContext, common, filesBuilder, javaArtifactsBuilder, ruleOutputJarsProviderBuilder, javaSourceJarsProviderBuilder);
    Artifact outputDepsProto = helper.createOutputDepsProtoArtifact(classJar, javaArtifactsBuilder);
    ruleOutputJarsProviderBuilder.setJdeps(outputDepsProto);
    JavaCompilationArtifacts javaArtifacts = javaArtifactsBuilder.build();
    common.setJavaCompilationArtifacts(javaArtifacts);
    Artifact manifestProtoOutput = helper.createManifestProtoOutput(classJar);
    // The gensrc jar is created only if the target uses annotation processing. Otherwise,
    // it is null, and the source jar action will not depend on the compile action.
    Artifact genSourceJar = null;
    Artifact genClassJar = null;
    if (helper.usesAnnotationProcessing()) {
        genClassJar = helper.createGenJar(classJar);
        genSourceJar = helper.createGensrcJar(classJar);
        helper.createGenJarAction(classJar, manifestProtoOutput, genClassJar);
    }
    helper.createCompileAction(classJar, manifestProtoOutput, genSourceJar, outputDepsProto, instrumentationMetadata);
    helper.createSourceJarAction(srcJar, genSourceJar);
    common.setClassPathFragment(new ClasspathConfiguredFragment(javaArtifacts, attributes, false, helper.getBootclasspathOrDefault()));
    // Collect the action inputs for the runfiles collector here because we need to access the
    // analysis environment, and that may no longer be safe when the runfiles collector runs.
    Iterable<Artifact> dynamicRuntimeActionInputs = CppHelper.getToolchain(ruleContext, ":cc_toolchain").getDynamicRuntimeLinkInputs();
    Iterables.addAll(jvmFlags, semantics.getJvmFlags(ruleContext, common.getSrcsArtifacts(), userJvmFlags));
    if (ruleContext.hasErrors()) {
        return null;
    }
    Artifact executableToRun = executableForRunfiles;
    if (createExecutable) {
        // Create a shell stub for a Java application
        executableToRun = semantics.createStubAction(ruleContext, common, jvmFlags, executableForRunfiles, mainClass, JavaCommon.getJavaBinSubstitution(ruleContext, launcher));
        if (!executableToRun.equals(executableForRunfiles)) {
            filesBuilder.add(executableToRun);
            runfilesBuilder.addArtifact(executableToRun);
        }
    }
    JavaSourceJarsProvider sourceJarsProvider = javaSourceJarsProviderBuilder.build();
    NestedSet<Artifact> transitiveSourceJars = sourceJarsProvider.getTransitiveSourceJars();
    // TODO(bazel-team): if (getOptions().sourceJars) then make this a dummy prerequisite for the
    // DeployArchiveAction ? Needs a few changes there as we can't pass inputs
    SingleJarActionBuilder.createSourceJarAction(ruleContext, ImmutableMap.<PathFragment, Artifact>of(), transitiveSourceJars.toCollection(), ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_DEPLOY_SOURCE_JAR));
    RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(ruleContext);
    builder.add(JavaPrimaryClassProvider.class, new JavaPrimaryClassProvider(semantics.getPrimaryClass(ruleContext, common.getSrcsArtifacts())));
    semantics.addProviders(ruleContext, common, jvmFlags, classJar, srcJar, genClassJar, genSourceJar, ImmutableMap.<Artifact, Artifact>of(), filesBuilder, builder);
    if (generatedExtensionRegistryProvider != null) {
        builder.add(GeneratedExtensionRegistryProvider.class, generatedExtensionRegistryProvider);
    }
    Artifact deployJar = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_DEPLOY_JAR);
    boolean runProguard = applyProguardIfRequested(ruleContext, deployJar, common.getBootClasspath(), mainClass, semantics, filesBuilder);
    if (javaConfig.isEnforceOneVersion()) {
        Artifact oneVersionOutput = ruleContext.getAnalysisEnvironment().getDerivedArtifact(replaceExtension(classJar.getRootRelativePath(), "-one-version.txt"), classJar.getRoot());
        filesBuilder.add(oneVersionOutput);
        NestedSet<Artifact> transitiveDependencies = NestedSetBuilder.fromNestedSet(attributes.getRuntimeClassPath()).add(classJar).build();
        OneVersionCheckActionBuilder.build(ruleContext, transitiveDependencies, oneVersionOutput);
    }
    NestedSet<Artifact> filesToBuild = filesBuilder.build();
    // Need not include normal runtime classpath in runfiles if Proguard is used because _deploy.jar
    // is used as classpath instead.  Keeping runfiles unchanged has however the advantage that
    // manually running executable without --singlejar works (although it won't depend on Proguard).
    collectDefaultRunfiles(runfilesBuilder, ruleContext, common, javaArtifacts, filesToBuild, launcher, dynamicRuntimeActionInputs);
    Runfiles defaultRunfiles = runfilesBuilder.build();
    RunfilesSupport runfilesSupport = null;
    if (createExecutable) {
        List<String> extraArgs = new ArrayList<>(semantics.getExtraArguments(ruleContext, common.getSrcsArtifacts()));
        if (runProguard) {
            // Instead of changing the classpath written into the wrapper script, pass --singlejar when
            // running the script (which causes the deploy.jar written by Proguard to be used instead of
            // the normal classpath). It's a bit odd to do this b/c manually running the script wouldn't
            // use Proguard's output unless --singlejar is explicitly supplied.  On the other hand the
            // behavior of the script is more consistent: the (proguarded) deploy.jar is only used with
            // --singlejar.  Moreover, people will almost always run tests using blaze test, which does
            // use Proguard's output thanks to this extra arg when enabled.  Also, it's actually hard to
            // get the classpath changed in the wrapper script (would require calling
            // JavaCommon.setClasspathFragment with a new fragment at the *end* of this method because
            // the classpath is evaluated lazily when generating the wrapper script) and the wrapper
            // script would essentially have an if (--singlejar was set), set classpath to deploy jar,
            // otherwise, set classpath to deploy jar.
            extraArgs.add("--wrapper_script_flag=--singlejar");
        }
        // The executable we pass here will be used when creating the runfiles directory. E.g. for the
        // stub script called bazel-bin/foo/bar_bin, the runfiles directory will be created under
        // bazel-bin/foo/bar_bin.runfiles . On platforms where there's an extra stub script (Windows)
        // which dispatches to this one, we still create the runfiles directory for the shell script,
        // but use the dispatcher script (a batch file) as the RunfilesProvider's executable.
        runfilesSupport = RunfilesSupport.withExecutable(ruleContext, defaultRunfiles, executableForRunfiles, extraArgs);
    }
    RunfilesProvider runfilesProvider = RunfilesProvider.withData(defaultRunfiles, new Runfiles.Builder(ruleContext.getWorkspaceName(), ruleContext.getConfiguration().legacyExternalRunfiles()).merge(runfilesSupport).build());
    ImmutableList<String> deployManifestLines = getDeployManifestLines(ruleContext, originalMainClass);
    // When running Proguard:
    // (1) write single jar to intermediate destination; Proguard will write _deploy.jar file
    // (2) Don't depend on runfiles to avoid circular dependency, since _deploy.jar is itself part
    //     of runfiles when Proguard runs (because executable then needs it) and _deploy.jar depends
    //     on this single jar.
    // (3) Don't bother with compression since Proguard will write the final jar anyways
    deployArchiveBuilder.setOutputJar(runProguard ? ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_MERGED_JAR) : deployJar).setJavaStartClass(mainClass).setDeployManifestLines(deployManifestLines).setAttributes(attributes).addRuntimeJars(javaArtifacts.getRuntimeJars()).setIncludeBuildData(true).setRunfilesMiddleman(runProguard || runfilesSupport == null ? null : runfilesSupport.getRunfilesMiddleman()).setCompression(runProguard ? UNCOMPRESSED : COMPRESSED).setLauncher(launcher).build();
    Artifact unstrippedDeployJar = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_UNSTRIPPED_BINARY_DEPLOY_JAR);
    if (stripAsDefault) {
        unstrippedDeployArchiveBuilder.setOutputJar(unstrippedDeployJar).setJavaStartClass(mainClass).setDeployManifestLines(deployManifestLines).setAttributes(attributes).addRuntimeJars(javaArtifacts.getRuntimeJars()).setIncludeBuildData(true).setRunfilesMiddleman(runfilesSupport == null ? null : runfilesSupport.getRunfilesMiddleman()).setCompression(COMPRESSED).setLauncher(unstrippedLauncher);
        unstrippedDeployArchiveBuilder.build();
    } else {
        // Write an empty file as the name_deploy.jar.unstripped when the default output jar is not
        // stripped.
        ruleContext.registerAction(FileWriteAction.create(ruleContext, unstrippedDeployJar, "", false));
    }
    JavaRuleOutputJarsProvider ruleOutputJarsProvider = ruleOutputJarsProviderBuilder.build();
    JavaSkylarkApiProvider.Builder skylarkApiProvider = JavaSkylarkApiProvider.builder().setRuleOutputJarsProvider(ruleOutputJarsProvider).setSourceJarsProvider(sourceJarsProvider);
    common.addTransitiveInfoProviders(builder, skylarkApiProvider, filesToBuild, classJar);
    common.addGenJarsProvider(builder, skylarkApiProvider, genClassJar, genSourceJar);
    return builder.setFilesToBuild(filesToBuild).addSkylarkTransitiveInfo(JavaSkylarkApiProvider.NAME, skylarkApiProvider.build()).add(JavaRuleOutputJarsProvider.class, ruleOutputJarsProvider).add(RunfilesProvider.class, runfilesProvider).setRunfilesSupport(runfilesSupport, executableToRun).add(JavaRuntimeClasspathProvider.class, new JavaRuntimeClasspathProvider(common.getRuntimeClasspath())).add(JavaSourceInfoProvider.class, JavaSourceInfoProvider.fromJavaTargetAttributes(attributes, semantics)).add(JavaSourceJarsProvider.class, sourceJarsProvider).addOutputGroup(JavaSemantics.SOURCE_JARS_OUTPUT_GROUP, transitiveSourceJars).build();
}
Also used : NestedSetBuilder(com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder) ArrayList(java.util.ArrayList) Label(com.google.devtools.build.lib.cmdline.Label) RunfilesSupport(com.google.devtools.build.lib.analysis.RunfilesSupport) RunfilesProvider(com.google.devtools.build.lib.analysis.RunfilesProvider) Artifact(com.google.devtools.build.lib.actions.Artifact) Runfiles(com.google.devtools.build.lib.analysis.Runfiles) CppConfiguration(com.google.devtools.build.lib.rules.cpp.CppConfiguration) GeneratedExtensionRegistryProvider(com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder) TransitiveInfoCollection(com.google.devtools.build.lib.analysis.TransitiveInfoCollection)

Example 5 with Runfiles

use of com.google.devtools.build.lib.analysis.Runfiles in project bazel by bazelbuild.

the class JavaImport method create.

@Override
public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException, RuleErrorException {
    ImmutableList<Artifact> srcJars = ImmutableList.of();
    ImmutableList<Artifact> jars = collectJars(ruleContext);
    Artifact srcJar = ruleContext.getPrerequisiteArtifact("srcjar", Mode.TARGET);
    if (ruleContext.hasErrors()) {
        return null;
    }
    ImmutableList<TransitiveInfoCollection> targets = ImmutableList.<TransitiveInfoCollection>builder().addAll(ruleContext.getPrerequisites("deps", Mode.TARGET)).addAll(ruleContext.getPrerequisites("exports", Mode.TARGET)).build();
    final JavaCommon common = new JavaCommon(ruleContext, semantics, /*srcs=*/
    ImmutableList.<Artifact>of(), targets, targets, targets);
    semantics.checkRule(ruleContext, common);
    // No need for javac options - no compilation happening here.
    ImmutableBiMap.Builder<Artifact, Artifact> compilationToRuntimeJarMapBuilder = ImmutableBiMap.builder();
    ImmutableList<Artifact> interfaceJars = processWithIjar(jars, ruleContext, compilationToRuntimeJarMapBuilder);
    JavaCompilationArtifacts javaArtifacts = collectJavaArtifacts(jars, interfaceJars);
    common.setJavaCompilationArtifacts(javaArtifacts);
    CppCompilationContext transitiveCppDeps = common.collectTransitiveCppDeps();
    NestedSet<LinkerInput> transitiveJavaNativeLibraries = common.collectTransitiveJavaNativeLibraries();
    boolean neverLink = JavaCommon.isNeverLink(ruleContext);
    JavaCompilationArgs javaCompilationArgs = common.collectJavaCompilationArgs(false, neverLink, false);
    JavaCompilationArgs recursiveJavaCompilationArgs = common.collectJavaCompilationArgs(true, neverLink, false);
    NestedSet<Artifact> transitiveJavaSourceJars = collectTransitiveJavaSourceJars(ruleContext, srcJar);
    if (srcJar != null) {
        srcJars = ImmutableList.of(srcJar);
    }
    // The "neverlink" attribute is transitive, so if it is enabled, we don't add any
    // runfiles from this target or its dependencies.
    Runfiles runfiles = neverLink ? Runfiles.EMPTY : new Runfiles.Builder(ruleContext.getWorkspaceName(), ruleContext.getConfiguration().legacyExternalRunfiles()).addArtifacts(javaArtifacts.getRuntimeJars()).addTargets(targets, RunfilesProvider.DEFAULT_RUNFILES).addRunfiles(ruleContext, RunfilesProvider.DEFAULT_RUNFILES).addTargets(targets, JavaRunfilesProvider.TO_RUNFILES).add(ruleContext, JavaRunfilesProvider.TO_RUNFILES).build();
    CcLinkParamsStore ccLinkParamsStore = new CcLinkParamsStore() {

        @Override
        protected void collect(CcLinkParams.Builder builder, boolean linkingStatically, boolean linkShared) {
            builder.addTransitiveTargets(common.targetsTreatedAsDeps(ClasspathType.BOTH), JavaCcLinkParamsProvider.TO_LINK_PARAMS, CcLinkParamsProvider.TO_LINK_PARAMS);
        }
    };
    RuleConfiguredTargetBuilder ruleBuilder = new RuleConfiguredTargetBuilder(ruleContext);
    NestedSetBuilder<Artifact> filesBuilder = NestedSetBuilder.stableOrder();
    filesBuilder.addAll(jars);
    ImmutableBiMap<Artifact, Artifact> compilationToRuntimeJarMap = compilationToRuntimeJarMapBuilder.build();
    semantics.addProviders(ruleContext, common, ImmutableList.<String>of(), null, /* classJar */
    srcJar, /* srcJar */
    null, /* genJar */
    null, /* gensrcJar */
    compilationToRuntimeJarMap, filesBuilder, ruleBuilder);
    NestedSet<Artifact> filesToBuild = filesBuilder.build();
    JavaSourceInfoProvider javaSourceInfoProvider = new JavaSourceInfoProvider.Builder().setJarFiles(jars).setSourceJarsForJarFiles(srcJars).build();
    JavaRuleOutputJarsProvider.Builder ruleOutputJarsProviderBuilder = JavaRuleOutputJarsProvider.builder();
    for (Artifact jar : jars) {
        ruleOutputJarsProviderBuilder.addOutputJar(jar, compilationToRuntimeJarMap.inverse().get(jar), srcJars);
    }
    NestedSet<Artifact> proguardSpecs = new ProguardLibrary(ruleContext).collectProguardSpecs();
    JavaRuleOutputJarsProvider ruleOutputJarsProvider = ruleOutputJarsProviderBuilder.build();
    JavaSourceJarsProvider sourceJarsProvider = JavaSourceJarsProvider.create(transitiveJavaSourceJars, srcJars);
    JavaCompilationArgsProvider compilationArgsProvider = JavaCompilationArgsProvider.create(javaCompilationArgs, recursiveJavaCompilationArgs);
    JavaSkylarkApiProvider.Builder skylarkApiProvider = JavaSkylarkApiProvider.builder().setRuleOutputJarsProvider(ruleOutputJarsProvider).setSourceJarsProvider(sourceJarsProvider).setCompilationArgsProvider(compilationArgsProvider);
    common.addTransitiveInfoProviders(ruleBuilder, skylarkApiProvider, filesToBuild, null);
    return ruleBuilder.setFilesToBuild(filesToBuild).addSkylarkTransitiveInfo(JavaSkylarkApiProvider.NAME, skylarkApiProvider.build()).add(JavaRuleOutputJarsProvider.class, ruleOutputJarsProvider).add(JavaRuntimeJarProvider.class, new JavaRuntimeJarProvider(javaArtifacts.getRuntimeJars())).add(JavaNeverlinkInfoProvider.class, new JavaNeverlinkInfoProvider(neverLink)).add(RunfilesProvider.class, RunfilesProvider.simple(runfiles)).add(CcLinkParamsProvider.class, new CcLinkParamsProvider(ccLinkParamsStore)).add(JavaCompilationArgsProvider.class, compilationArgsProvider).add(JavaNativeLibraryProvider.class, new JavaNativeLibraryProvider(transitiveJavaNativeLibraries)).add(CppCompilationContext.class, transitiveCppDeps).add(JavaSourceInfoProvider.class, javaSourceInfoProvider).add(JavaSourceJarsProvider.class, sourceJarsProvider).add(ProguardSpecProvider.class, new ProguardSpecProvider(proguardSpecs)).addOutputGroup(JavaSemantics.SOURCE_JARS_OUTPUT_GROUP, transitiveJavaSourceJars).addOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL, proguardSpecs).build();
}
Also used : NestedSetBuilder(com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder) CcLinkParamsProvider(com.google.devtools.build.lib.rules.cpp.CcLinkParamsProvider) LinkerInput(com.google.devtools.build.lib.rules.cpp.LinkerInput) CcLinkParamsStore(com.google.devtools.build.lib.rules.cpp.CcLinkParamsStore) Artifact(com.google.devtools.build.lib.actions.Artifact) Runfiles(com.google.devtools.build.lib.analysis.Runfiles) ImmutableBiMap(com.google.common.collect.ImmutableBiMap) CppCompilationContext(com.google.devtools.build.lib.rules.cpp.CppCompilationContext) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder) TransitiveInfoCollection(com.google.devtools.build.lib.analysis.TransitiveInfoCollection)

Aggregations

Runfiles (com.google.devtools.build.lib.analysis.Runfiles)28 Artifact (com.google.devtools.build.lib.actions.Artifact)24 RuleConfiguredTargetBuilder (com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)15 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)11 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)10 RunfilesProvider (com.google.devtools.build.lib.analysis.RunfilesProvider)9 RunfilesSupplierImpl (com.google.devtools.build.lib.analysis.RunfilesSupplierImpl)7 TransitiveInfoCollection (com.google.devtools.build.lib.analysis.TransitiveInfoCollection)7 Test (org.junit.Test)7 ActionInputFileCache (com.google.devtools.build.lib.actions.ActionInputFileCache)6 EmptyRunfilesSupplier (com.google.devtools.build.lib.actions.EmptyRunfilesSupplier)6 RunfilesSupplier (com.google.devtools.build.lib.actions.RunfilesSupplier)6 RunfilesSupport (com.google.devtools.build.lib.analysis.RunfilesSupport)6 ArrayList (java.util.ArrayList)5 ImmutableMap (com.google.common.collect.ImmutableMap)3 SkylarkClassObject (com.google.devtools.build.lib.packages.SkylarkClassObject)3 LibraryToLink (com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink)3 InstrumentedFilesProvider (com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider)3 Label (com.google.devtools.build.lib.cmdline.Label)2 NestedSet (com.google.devtools.build.lib.collect.nestedset.NestedSet)2