Search in sources :

Example 1 with FeatureConfiguration

use of com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration 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 2 with FeatureConfiguration

use of com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration in project bazel by bazelbuild.

the class CcIncLibrary method create.

@Override
public ConfiguredTarget create(final RuleContext ruleContext) throws RuleErrorException, InterruptedException {
    CcToolchainProvider ccToolchain = CppHelper.getToolchain(ruleContext, ":cc_toolchain");
    FeatureConfiguration featureConfiguration = CcCommon.configureFeatures(ruleContext, ccToolchain);
    PathFragment packageFragment = ruleContext.getPackageDirectory();
    // The rule needs a unique location for the include directory, which doesn't conflict with any
    // other rule. For that reason, the include directory is at:
    // configuration/package_name/_/target_name
    // And then the symlink is placed at:
    // configuration/package_name/_/target_name/package_name
    // So that these inclusions can be resolved correctly:
    // #include "package_name/a.h"
    //
    // The target of the symlink is:
    // package_name/targetPrefix/
    // All declared header files must be below that directory.
    String expandedIncSymlinkAttr = ruleContext.attributes().get("prefix", Type.STRING);
    // We use an additional "_" directory here to avoid conflicts between this and previous Blaze
    // versions. Previous Blaze versions created a directory symlink; the new version does not
    // detect that the output directory isn't a directory, and tries to put the symlinks into what
    // is actually a symlink into the source tree.
    PathFragment includeDirectory = new PathFragment("_").getRelative(ruleContext.getTarget().getName());
    Root configIncludeDirectory = ruleContext.getConfiguration().getIncludeDirectory(ruleContext.getRule().getRepository());
    PathFragment includePath = configIncludeDirectory.getExecPath().getRelative(packageFragment).getRelative(includeDirectory);
    Path includeRoot = configIncludeDirectory.getPath().getRelative(packageFragment).getRelative(includeDirectory);
    // For every source artifact, we compute a virtual artifact that is below the include directory.
    // These are used for include checking.
    PathFragment prefixFragment = packageFragment.getRelative(expandedIncSymlinkAttr);
    if (!prefixFragment.isNormalized()) {
        ruleContext.attributeWarning("prefix", "should not contain '.' or '..' elements");
    }
    ImmutableSortedMap.Builder<Artifact, Artifact> virtualArtifactMapBuilder = ImmutableSortedMap.orderedBy(Artifact.EXEC_PATH_COMPARATOR);
    prefixFragment = prefixFragment.normalize();
    ImmutableList<Artifact> hdrs = ruleContext.getPrerequisiteArtifacts("hdrs", Mode.TARGET).list();
    for (Artifact src : hdrs) {
        // All declared header files must start with package/targetPrefix.
        if (!src.getRootRelativePath().startsWith(prefixFragment)) {
            ruleContext.attributeError("hdrs", src + " does not start with '" + prefixFragment.getPathString() + "'");
            return null;
        }
        // Remove the targetPrefix from within the exec path of the source file, and prepend the
        // unique directory prefix, e.g.:
        // third_party/foo/1.2/bar/a.h -> third_party/foo/name/third_party/foo/bar/a.h
        PathFragment suffix = src.getRootRelativePath().relativeTo(prefixFragment);
        PathFragment virtualPath = includeDirectory.getRelative(packageFragment).getRelative(suffix);
        // These virtual artifacts have the symlink action as generating action.
        Artifact virtualArtifact = ruleContext.getPackageRelativeArtifact(virtualPath, configIncludeDirectory);
        virtualArtifactMapBuilder.put(virtualArtifact, src);
    }
    ImmutableSortedMap<Artifact, Artifact> virtualArtifactMap = virtualArtifactMapBuilder.build();
    ruleContext.registerAction(new CreateIncSymlinkAction(ruleContext.getActionOwner(), virtualArtifactMap, includeRoot));
    FdoSupportProvider fdoSupport = CppHelper.getFdoSupport(ruleContext, ":cc_toolchain");
    CcLibraryHelper.Info info = new CcLibraryHelper(ruleContext, semantics, featureConfiguration, ccToolchain, fdoSupport).addIncludeDirs(Arrays.asList(includePath)).addPublicHeaders(virtualArtifactMap.keySet()).addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET)).build();
    // cc_inc_library doesn't compile any file - no compilation outputs available.
    InstrumentedFilesProvider instrumentedFilesProvider = new CcCommon(ruleContext).getInstrumentedFilesProvider(new ArrayList<Artifact>(), /*withBaselineCoverage=*/
    true);
    return new RuleConfiguredTargetBuilder(ruleContext).addProviders(info.getProviders()).addSkylarkTransitiveInfo(CcSkylarkApiProvider.NAME, new CcSkylarkApiProvider()).addOutputGroups(info.getOutputGroups()).add(InstrumentedFilesProvider.class, instrumentedFilesProvider).add(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY)).build();
}
Also used : Path(com.google.devtools.build.lib.vfs.Path) Root(com.google.devtools.build.lib.actions.Root) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) 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) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)

Example 3 with FeatureConfiguration

use of com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration 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 FeatureConfiguration

use of com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration in project bazel by bazelbuild.

the class CcToolchainFeaturesTest method testActivateActionConfigDirectly.

@Test
public void testActivateActionConfigDirectly() throws Exception {
    CcToolchainFeatures toolchainFeatures = buildFeatures("action_config {", "  config_name: 'action-a'", "  action_name: 'action-a'", "  tool {", "    tool_path: 'toolchain/feature-a'", "    with_feature: { feature: 'feature-a' }", "  }", "}");
    FeatureConfiguration featureConfiguration = toolchainFeatures.getFeatureConfiguration("action-a");
    assertThat(featureConfiguration.actionIsConfigured("action-a")).isTrue();
}
Also used : FeatureConfiguration(com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration) Test(org.junit.Test)

Example 5 with FeatureConfiguration

use of com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration in project bazel by bazelbuild.

the class CcToolchainFeaturesTest method testSuppressionViaMissingBuildVariable.

@Test
public void testSuppressionViaMissingBuildVariable() throws Exception {
    FeatureConfiguration configuration = buildFeatures("feature {", "  name: 'a'", "  flag_set {", "     action: 'c++-compile'", "     expand_if_all_available: 'v'", "     flag_group { flag: '%{v}' }", "  }", "  flag_set {", "     action: 'c++-compile'", "     expand_if_all_available: 'v'", "     expand_if_all_available: 'w'", "     flag_group { flag: '%{v}%{w}' }", "  }", "  flag_set {", "     action: 'c++-compile'", "     flag_group { flag: 'unconditional' }", "  }", "}").getFeatureConfiguration("a");
    assertThat(configuration.getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())).containsExactly("unconditional");
    assertThat(configuration.getCommandLine(CppCompileAction.CPP_COMPILE, createVariables("v", "1"))).containsExactly("1", "unconditional");
    assertThat(configuration.getCommandLine(CppCompileAction.CPP_COMPILE, createVariables("v", "1", "v", "2"))).containsExactly("1", "2", "unconditional").inOrder();
    assertThat(configuration.getCommandLine(CppCompileAction.CPP_COMPILE, createVariables("v", "1", "v", "2", "w", "3"))).containsExactly("1", "2", "13", "23", "unconditional").inOrder();
}
Also used : FeatureConfiguration(com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration) Test(org.junit.Test)

Aggregations

FeatureConfiguration (com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration)23 Test (org.junit.Test)17 Artifact (com.google.devtools.build.lib.actions.Artifact)8 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)8 LibraryToLink (com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink)4 RuleContext (com.google.devtools.build.lib.analysis.RuleContext)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 Action (com.google.devtools.build.lib.actions.Action)2 RuleConfiguredTargetBuilder (com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)2 Runfiles (com.google.devtools.build.lib.analysis.Runfiles)2 RunfilesProvider (com.google.devtools.build.lib.analysis.RunfilesProvider)2 ActionCombinationFactory (com.google.devtools.build.lib.analysis.util.ActionTester.ActionCombinationFactory)2 InstrumentedFilesProvider (com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider)2 Function (com.google.common.base.Function)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)1 FailAction (com.google.devtools.build.lib.actions.FailAction)1 ResourceSet (com.google.devtools.build.lib.actions.ResourceSet)1 Root (com.google.devtools.build.lib.actions.Root)1 RunfilesSupport (com.google.devtools.build.lib.analysis.RunfilesSupport)1