Search in sources :

Example 1 with RuleContext

use of com.google.devtools.build.lib.analysis.RuleContext 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 RuleContext

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

the class FileWriteActionTest method testTransparentCompressionFlagOff.

@Test
public void testTransparentCompressionFlagOff() throws Exception {
    Artifact outputArtifact = getBinArtifactWithNoOwner("destination.txt");
    String contents = generateLongRandomString();
    useConfiguration("--experimental_transparent_compression=false");
    ConfiguredTarget target = scratchConfiguredTarget("a", "a", "filegroup(name='a', srcs=[])");
    RuleContext context = getRuleContext(target);
    FileWriteAction action = FileWriteAction.create(context, outputArtifact, contents, /*makeExecutable=*/
    false);
    assertThat(action.usesCompression()).isFalse();
}
Also used : RuleContext(com.google.devtools.build.lib.analysis.RuleContext) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) LazyString(com.google.devtools.build.lib.util.LazyString) Artifact(com.google.devtools.build.lib.actions.Artifact) Test(org.junit.Test)

Example 3 with RuleContext

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

the class CppLinkActionTest method testComputeKeyStatic.

/**
   * This mainly checks that static library links don't have identical keys, and it also compares
   * them with simple dynamic library links.
   */
@Test
public void testComputeKeyStatic() throws Exception {
    final RuleContext ruleContext = createDummyRuleContext();
    final PathFragment staticOutputPath = new PathFragment("dummyRuleContext/output/path.a");
    final PathFragment dynamicOutputPath = new PathFragment("dummyRuleContext/output/path.so");
    final Artifact staticOutputFile = getBinArtifactWithNoOwner(staticOutputPath.getPathString());
    final Artifact dynamicOutputFile = getBinArtifactWithNoOwner(dynamicOutputPath.getPathString());
    final Artifact oFile = getSourceArtifact("cc/a.o");
    final Artifact oFile2 = getSourceArtifact("cc/a2.o");
    final FeatureConfiguration featureConfiguration = getMockFeatureConfiguration();
    ActionTester.runTest(4, new ActionCombinationFactory() {

        @Override
        public Action generate(int i) throws InterruptedException {
            CppLinkActionBuilder builder = new CppLinkActionBuilder(ruleContext, (i & 2) == 0 ? staticOutputFile : dynamicOutputFile, CppHelper.getToolchain(ruleContext, ":cc_toolchain"), CppHelper.getFdoSupport(ruleContext, ":cc_toolchain")) {
            };
            builder.addCompilationInputs((i & 1) == 0 ? ImmutableList.of(oFile) : ImmutableList.of(oFile2));
            builder.setLinkType((i & 2) == 0 ? LinkTargetType.STATIC_LIBRARY : LinkTargetType.DYNAMIC_LIBRARY);
            builder.setLibraryIdentifier("foo");
            builder.setFeatureConfiguration(featureConfiguration);
            return builder.build();
        }
    });
}
Also used : ActionCombinationFactory(com.google.devtools.build.lib.analysis.util.ActionTester.ActionCombinationFactory) Action(com.google.devtools.build.lib.actions.Action) RuleContext(com.google.devtools.build.lib.analysis.RuleContext) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) FeatureConfiguration(com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration) Artifact(com.google.devtools.build.lib.actions.Artifact) Test(org.junit.Test)

Example 4 with RuleContext

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

the class JavaSkylarkCommon method getDefaultJavacOpts.

@SkylarkCallable(name = "default_javac_opts", // This function is experimental for now.
documented = false, // There's only one mandatory positional,the Skylark context
mandatoryPositionals = 1, parameters = { @Param(name = "java_toolchain_attr", positional = false, named = true, type = String.class) })
public static List<String> getDefaultJavacOpts(SkylarkRuleContext skylarkRuleContext, String javaToolchainAttr) {
    RuleContext ruleContext = skylarkRuleContext.getRuleContext();
    ConfiguredTarget javaToolchainConfigTarget = (ConfiguredTarget) checkNotNull(skylarkRuleContext.getAttr().getValue(javaToolchainAttr));
    JavaToolchainProvider toolchain = checkNotNull(javaToolchainConfigTarget.getProvider(JavaToolchainProvider.class));
    return ImmutableList.copyOf(Iterables.concat(toolchain.getJavacOptions(), ruleContext.getTokenizedStringListAttr("javacopts")));
}
Also used : RuleContext(com.google.devtools.build.lib.analysis.RuleContext) SkylarkRuleContext(com.google.devtools.build.lib.rules.SkylarkRuleContext) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) SkylarkCallable(com.google.devtools.build.lib.skylarkinterface.SkylarkCallable)

Example 5 with RuleContext

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

the class CppLinkActionTest method createLinkBuilder.

private CppLinkActionBuilder createLinkBuilder(Link.LinkTargetType type, String outputPath, Iterable<Artifact> nonLibraryInputs, ImmutableList<LibraryToLink> libraryInputs, FeatureConfiguration featureConfiguration) throws Exception {
    RuleContext ruleContext = createDummyRuleContext();
    CppLinkActionBuilder builder = new CppLinkActionBuilder(ruleContext, new Artifact(new PathFragment(outputPath), getTargetConfiguration().getBinDirectory(ruleContext.getRule().getRepository())), ruleContext.getConfiguration(), CppHelper.getToolchain(ruleContext, ":cc_toolchain"), CppHelper.getFdoSupport(ruleContext, ":cc_toolchain")).addObjectFiles(nonLibraryInputs).addLibraries(NestedSetBuilder.wrap(Order.LINK_ORDER, libraryInputs)).setLinkType(type).setCrosstoolInputs(NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER)).setLinkStaticness(type.staticness() == Staticness.STATIC ? LinkStaticness.FULLY_STATIC : LinkStaticness.MOSTLY_STATIC).setFeatureConfiguration(featureConfiguration);
    return builder;
}
Also used : RuleContext(com.google.devtools.build.lib.analysis.RuleContext) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Artifact(com.google.devtools.build.lib.actions.Artifact)

Aggregations

RuleContext (com.google.devtools.build.lib.analysis.RuleContext)8 Artifact (com.google.devtools.build.lib.actions.Artifact)7 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)5 Test (org.junit.Test)5 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)3 FeatureConfiguration (com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration)3 Action (com.google.devtools.build.lib.actions.Action)2 ActionCombinationFactory (com.google.devtools.build.lib.analysis.util.ActionTester.ActionCombinationFactory)2 LazyString (com.google.devtools.build.lib.util.LazyString)2 RuleConfiguredTargetBuilder (com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)1 Runfiles (com.google.devtools.build.lib.analysis.Runfiles)1 RunfilesSupport (com.google.devtools.build.lib.analysis.RunfilesSupport)1 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)1 SkylarkRuleContext (com.google.devtools.build.lib.rules.SkylarkRuleContext)1 LinkStaticness (com.google.devtools.build.lib.rules.cpp.Link.LinkStaticness)1 LinkTargetType (com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType)1 LibraryToLink (com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink)1 ExecutionInfoProvider (com.google.devtools.build.lib.rules.test.ExecutionInfoProvider)1 SkylarkCallable (com.google.devtools.build.lib.skylarkinterface.SkylarkCallable)1 LinkedHashMap (java.util.LinkedHashMap)1