Search in sources :

Example 1 with LanguageDependentFragment

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

the class CcLibraryHelper method build.

/**
   * Create the C++ compile and link actions, and the corresponding C++-related providers.
   *
   * @throws RuleErrorException
   */
public Info build() throws RuleErrorException, InterruptedException {
    // Fail early if there is no lipo context collector on the rule - otherwise we end up failing
    // in lipo optimization.
    Preconditions.checkState(// 'cc_inc_library' rules do not compile, and thus are not affected by LIPO.
    ruleContext.getRule().getRuleClass().equals("cc_inc_library") || ruleContext.isAttrDefined(":lipo_context_collector", BuildType.LABEL));
    if (checkDepsGenerateCpp) {
        for (LanguageDependentFragment dep : AnalysisUtils.getProviders(deps, LanguageDependentFragment.class)) {
            LanguageDependentFragment.Checker.depSupportsLanguage(ruleContext, dep, CppRuleClasses.LANGUAGE);
        }
    }
    CppModel model = initializeCppModel();
    CppCompilationContext cppCompilationContext = initializeCppCompilationContext(model);
    model.setContext(cppCompilationContext);
    boolean compileHeaderModules = featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULES);
    Preconditions.checkState(!compileHeaderModules || cppCompilationContext.getCppModuleMap() != null, "All cc rules must support module maps.");
    // Create compile actions (both PIC and non-PIC).
    CcCompilationOutputs ccOutputs = model.createCcCompileActions();
    if (!objectFiles.isEmpty() || !picObjectFiles.isEmpty()) {
        // Merge the pre-compiled object files into the compiler outputs.
        ccOutputs = new CcCompilationOutputs.Builder().merge(ccOutputs).addLTOBitcodeFile(ccOutputs.getLtoBitcodeFiles()).addObjectFiles(objectFiles).addPicObjectFiles(picObjectFiles).build();
    }
    // Create link actions (only if there are object files or if explicitly requested).
    CcLinkingOutputs ccLinkingOutputs = CcLinkingOutputs.EMPTY;
    if (emitLinkActions && (emitLinkActionsIfEmpty || !ccOutputs.isEmpty())) {
        // generate any link actions, effectively disabling header checking in some cases.
        if (linkType.staticness() == Staticness.STATIC) {
            // TODO(bazel-team): This can't create the link action for a cc_binary yet.
            ccLinkingOutputs = model.createCcLinkActions(ccOutputs, nonCodeLinkerInputs);
        }
    }
    CcLinkingOutputs originalLinkingOutputs = ccLinkingOutputs;
    if (!(staticLibraries.isEmpty() && picStaticLibraries.isEmpty() && dynamicLibraries.isEmpty())) {
        CcLinkingOutputs.Builder newOutputsBuilder = new CcLinkingOutputs.Builder();
        if (!ccOutputs.isEmpty()) {
            // Add the linked outputs of this rule iff we had anything to put in them, but then
            // make sure we're not colliding with some library added from the inputs.
            newOutputsBuilder.merge(originalLinkingOutputs);
            ImmutableSetMultimap<String, LibraryToLink> precompiledLibraryMap = CcLinkingOutputs.getLibrariesByIdentifier(Iterables.concat(staticLibraries, picStaticLibraries, dynamicLibraries));
            ImmutableSetMultimap<String, LibraryToLink> linkedLibraryMap = originalLinkingOutputs.getLibrariesByIdentifier();
            for (String matchingIdentifier : Sets.intersection(precompiledLibraryMap.keySet(), linkedLibraryMap.keySet())) {
                Iterable<Artifact> matchingInputLibs = LinkerInputs.toNonSolibArtifacts(precompiledLibraryMap.get(matchingIdentifier));
                Iterable<Artifact> matchingOutputLibs = LinkerInputs.toNonSolibArtifacts(linkedLibraryMap.get(matchingIdentifier));
                ruleContext.ruleError("Can't put " + Joiner.on(", ").join(Iterables.transform(matchingInputLibs, FileType.TO_FILENAME)) + " into the srcs of a " + ruleContext.getRuleClassNameForLogging() + " with the same name (" + ruleContext.getRule().getName() + ") which also contains other code or objects to link; it shares a name with " + Joiner.on(", ").join(Iterables.transform(matchingOutputLibs, FileType.TO_FILENAME)) + " (output compiled and linked from the non-library sources of this rule), " + "which could cause confusion");
            }
        }
        // Merge the pre-compiled libraries (static & dynamic) into the linker outputs.
        ccLinkingOutputs = newOutputsBuilder.addStaticLibraries(staticLibraries).addPicStaticLibraries(picStaticLibraries).addDynamicLibraries(dynamicLibraries).addExecutionDynamicLibraries(dynamicLibraries).build();
    }
    DwoArtifactsCollector dwoArtifacts = DwoArtifactsCollector.transitiveCollector(ruleContext, ccOutputs, deps, /*generateDwo=*/
    false, /*ltoBackendArtifactsUsePic=*/
    false, /*ltoBackendArtifacts=*/
    ImmutableList.<LTOBackendArtifacts>of());
    Runfiles cppStaticRunfiles = collectCppRunfiles(ccLinkingOutputs, true);
    Runfiles cppSharedRunfiles = collectCppRunfiles(ccLinkingOutputs, false);
    // By very careful when adding new providers here - it can potentially affect a lot of rules.
    // We should consider merging most of these providers into a single provider.
    TransitiveInfoProviderMap.Builder providers = TransitiveInfoProviderMap.builder().add(new CppRunfilesProvider(cppStaticRunfiles, cppSharedRunfiles), cppCompilationContext, new CppDebugFileProvider(dwoArtifacts.getDwoArtifacts(), dwoArtifacts.getPicDwoArtifacts()), collectTransitiveLipoInfo(ccOutputs));
    Map<String, NestedSet<Artifact>> outputGroups = new TreeMap<>();
    if (shouldAddLinkerOutputArtifacts(ruleContext, ccOutputs)) {
        addLinkerOutputArtifacts(outputGroups, ccOutputs);
    }
    outputGroups.put(OutputGroupProvider.TEMP_FILES, getTemps(ccOutputs));
    CppConfiguration cppConfiguration = ruleContext.getFragment(CppConfiguration.class);
    if (emitCompileProviders) {
        boolean isLipoCollector = cppConfiguration.isLipoContextCollector();
        boolean processHeadersInDependencies = cppConfiguration.processHeadersInDependencies();
        boolean usePic = CppHelper.usePic(ruleContext, false);
        outputGroups.put(OutputGroupProvider.FILES_TO_COMPILE, ccOutputs.getFilesToCompile(isLipoCollector, processHeadersInDependencies, usePic));
        outputGroups.put(OutputGroupProvider.COMPILATION_PREREQUISITES, CcCommon.collectCompilationPrerequisites(ruleContext, cppCompilationContext));
    }
    // used.
    if (emitCcNativeLibrariesProvider) {
        providers.add(new CcNativeLibraryProvider(collectNativeCcLibraries(ccLinkingOutputs)));
    }
    providers.put(CcExecutionDynamicLibrariesProvider.class, collectExecutionDynamicLibraryArtifacts(ccLinkingOutputs.getExecutionDynamicLibraries()));
    boolean forcePic = cppConfiguration.forcePic();
    if (emitCcSpecificLinkParamsProvider) {
        providers.add(new CcSpecificLinkParamsProvider(createCcLinkParamsStore(ccLinkingOutputs, cppCompilationContext, forcePic)));
    } else {
        providers.add(new CcLinkParamsProvider(createCcLinkParamsStore(ccLinkingOutputs, cppCompilationContext, forcePic)));
    }
    return new Info(providers.build(), outputGroups, ccOutputs, ccLinkingOutputs, originalLinkingOutputs, cppCompilationContext);
}
Also used : TransitiveInfoProviderMap(com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap) NestedSet(com.google.devtools.build.lib.collect.nestedset.NestedSet) NestedSetBuilder(com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder) LanguageDependentFragment(com.google.devtools.build.lib.analysis.LanguageDependentFragment) TreeMap(java.util.TreeMap) 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)

Aggregations

Artifact (com.google.devtools.build.lib.actions.Artifact)1 LanguageDependentFragment (com.google.devtools.build.lib.analysis.LanguageDependentFragment)1 Runfiles (com.google.devtools.build.lib.analysis.Runfiles)1 TransitiveInfoProviderMap (com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap)1 NestedSet (com.google.devtools.build.lib.collect.nestedset.NestedSet)1 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)1 LibraryToLink (com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink)1 TreeMap (java.util.TreeMap)1