Search in sources :

Example 1 with LicensesProvider

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

the class CcToolchain method create.

@Override
public ConfiguredTarget create(RuleContext ruleContext) throws RuleErrorException, InterruptedException {
    TransitiveInfoCollection lipoContextCollector = ruleContext.getPrerequisite(":lipo_context_collector", Mode.DONT_CHECK);
    if (lipoContextCollector != null && lipoContextCollector.getProvider(LipoContextProvider.class) == null) {
        ruleContext.ruleError("--lipo_context must point to a cc_binary or a cc_test rule");
        return null;
    }
    CppConfiguration cppConfiguration = Preconditions.checkNotNull(ruleContext.getFragment(CppConfiguration.class));
    Path fdoZip = ruleContext.getConfiguration().getCompilationMode() == CompilationMode.OPT ? cppConfiguration.getFdoZip() : null;
    SkyKey fdoKey = FdoSupportValue.key(cppConfiguration.getLipoMode(), fdoZip, cppConfiguration.getFdoInstrument());
    SkyFunction.Environment skyframeEnv = ruleContext.getAnalysisEnvironment().getSkyframeEnv();
    FdoSupportValue fdoSupport;
    try {
        fdoSupport = (FdoSupportValue) skyframeEnv.getValueOrThrow(fdoKey, FdoException.class, IOException.class);
    } catch (FdoException | IOException e) {
        ruleContext.ruleError("cannot initialize FDO: " + e.getMessage());
        return null;
    }
    if (skyframeEnv.valuesMissing()) {
        return null;
    }
    final Label label = ruleContext.getLabel();
    final NestedSet<Artifact> crosstool = ruleContext.getPrerequisite("all_files", Mode.HOST).getProvider(FileProvider.class).getFilesToBuild();
    final NestedSet<Artifact> crosstoolMiddleman = getFiles(ruleContext, "all_files");
    final NestedSet<Artifact> compile = getFiles(ruleContext, "compiler_files");
    final NestedSet<Artifact> strip = getFiles(ruleContext, "strip_files");
    final NestedSet<Artifact> objcopy = getFiles(ruleContext, "objcopy_files");
    final NestedSet<Artifact> link = getFiles(ruleContext, "linker_files");
    final NestedSet<Artifact> dwp = getFiles(ruleContext, "dwp_files");
    final NestedSet<Artifact> libcLink = inputsForLibc(ruleContext);
    String purposePrefix = Actions.escapeLabel(label) + "_";
    String runtimeSolibDirBase = "_solib_" + "_" + Actions.escapeLabel(label);
    final PathFragment runtimeSolibDir = ruleContext.getConfiguration().getBinFragment().getRelative(runtimeSolibDirBase);
    // Static runtime inputs.
    TransitiveInfoCollection staticRuntimeLibDep = selectDep(ruleContext, "static_runtime_libs", cppConfiguration.getStaticRuntimeLibsLabel());
    final NestedSet<Artifact> staticRuntimeLinkInputs;
    final Artifact staticRuntimeLinkMiddleman;
    if (cppConfiguration.supportsEmbeddedRuntimes()) {
        staticRuntimeLinkInputs = staticRuntimeLibDep.getProvider(FileProvider.class).getFilesToBuild();
    } else {
        staticRuntimeLinkInputs = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
    }
    if (!staticRuntimeLinkInputs.isEmpty()) {
        NestedSet<Artifact> staticRuntimeLinkMiddlemanSet = CompilationHelper.getAggregatingMiddleman(ruleContext, purposePrefix + "static_runtime_link", staticRuntimeLibDep);
        staticRuntimeLinkMiddleman = staticRuntimeLinkMiddlemanSet.isEmpty() ? null : Iterables.getOnlyElement(staticRuntimeLinkMiddlemanSet);
    } else {
        staticRuntimeLinkMiddleman = null;
    }
    Preconditions.checkState((staticRuntimeLinkMiddleman == null) == staticRuntimeLinkInputs.isEmpty());
    // Dynamic runtime inputs.
    TransitiveInfoCollection dynamicRuntimeLibDep = selectDep(ruleContext, "dynamic_runtime_libs", cppConfiguration.getDynamicRuntimeLibsLabel());
    NestedSet<Artifact> dynamicRuntimeLinkSymlinks;
    List<Artifact> dynamicRuntimeLinkInputs = new ArrayList<>();
    Artifact dynamicRuntimeLinkMiddleman;
    if (cppConfiguration.supportsEmbeddedRuntimes()) {
        NestedSetBuilder<Artifact> dynamicRuntimeLinkSymlinksBuilder = NestedSetBuilder.stableOrder();
        for (Artifact artifact : dynamicRuntimeLibDep.getProvider(FileProvider.class).getFilesToBuild()) {
            if (CppHelper.SHARED_LIBRARY_FILETYPES.matches(artifact.getFilename())) {
                dynamicRuntimeLinkInputs.add(artifact);
                dynamicRuntimeLinkSymlinksBuilder.add(SolibSymlinkAction.getCppRuntimeSymlink(ruleContext, artifact, runtimeSolibDirBase, ruleContext.getConfiguration()));
            }
        }
        dynamicRuntimeLinkSymlinks = dynamicRuntimeLinkSymlinksBuilder.build();
    } else {
        dynamicRuntimeLinkSymlinks = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
    }
    if (!dynamicRuntimeLinkInputs.isEmpty()) {
        List<Artifact> dynamicRuntimeLinkMiddlemanSet = CppHelper.getAggregatingMiddlemanForCppRuntimes(ruleContext, purposePrefix + "dynamic_runtime_link", dynamicRuntimeLinkInputs, runtimeSolibDirBase, ruleContext.getConfiguration());
        dynamicRuntimeLinkMiddleman = dynamicRuntimeLinkMiddlemanSet.isEmpty() ? null : Iterables.getOnlyElement(dynamicRuntimeLinkMiddlemanSet);
    } else {
        dynamicRuntimeLinkMiddleman = null;
    }
    Preconditions.checkState((dynamicRuntimeLinkMiddleman == null) == dynamicRuntimeLinkSymlinks.isEmpty());
    CppCompilationContext.Builder contextBuilder = new CppCompilationContext.Builder(ruleContext);
    CppModuleMap moduleMap = createCrosstoolModuleMap(ruleContext);
    if (moduleMap != null) {
        contextBuilder.setCppModuleMap(moduleMap);
    }
    final CppCompilationContext context = contextBuilder.build();
    boolean supportsParamFiles = ruleContext.attributes().get("supports_param_files", BOOLEAN);
    boolean supportsHeaderParsing = ruleContext.attributes().get("supports_header_parsing", BOOLEAN);
    NestedSetBuilder<Pair<String, String>> coverageEnvironment = NestedSetBuilder.compileOrder();
    coverageEnvironment.add(Pair.of("COVERAGE_GCOV_PATH", cppConfiguration.getGcovExecutable().getPathString()));
    if (cppConfiguration.getFdoInstrument() != null) {
        coverageEnvironment.add(Pair.of("FDO_DIR", cppConfiguration.getFdoInstrument().getPathString()));
    }
    CcToolchainProvider provider = new CcToolchainProvider(cppConfiguration, crosstool, fullInputsForCrosstool(ruleContext, crosstoolMiddleman), compile, strip, objcopy, fullInputsForLink(ruleContext, link), ruleContext.getPrerequisiteArtifact("$interface_library_builder", Mode.HOST), dwp, libcLink, staticRuntimeLinkInputs, staticRuntimeLinkMiddleman, dynamicRuntimeLinkSymlinks, dynamicRuntimeLinkMiddleman, runtimeSolibDir, context, supportsParamFiles, supportsHeaderParsing, getBuildVariables(ruleContext), getBuiltinIncludes(ruleContext), coverageEnvironment.build(), ruleContext.getPrerequisiteArtifact("$link_dynamic_library_tool", Mode.HOST), getEnvironment(ruleContext));
    RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(ruleContext).add(CcToolchainProvider.class, provider).add(FdoSupportProvider.class, fdoSupport.getFdoSupport().createFdoSupportProvider(ruleContext)).setFilesToBuild(new NestedSetBuilder<Artifact>(Order.STABLE_ORDER).build()).add(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY));
    // If output_license is specified on the cc_toolchain rule, override the transitive licenses
    // with that one. This is necessary because cc_toolchain is used in the target configuration,
    // but it is sort-of-kind-of a tool, but various parts of it are linked into the output...
    // ...so we trust the judgment of the author of the cc_toolchain rule to figure out what
    // licenses should be propagated to C++ targets.
    // TODO(elenairina): Remove this and use Attribute.Builder.useOutputLicenses() on the
    // :cc_toolchain attribute instead.
    final License outputLicense = ruleContext.getRule().getToolOutputLicense(ruleContext.attributes());
    if (outputLicense != null && outputLicense != License.NO_LICENSE) {
        final NestedSet<TargetLicense> license = NestedSetBuilder.create(Order.STABLE_ORDER, new TargetLicense(ruleContext.getLabel(), outputLicense));
        LicensesProvider licensesProvider = new LicensesProvider() {

            @Override
            public NestedSet<TargetLicense> getTransitiveLicenses() {
                return license;
            }

            @Override
            public TargetLicense getOutputLicenses() {
                return new TargetLicense(label, outputLicense);
            }

            @Override
            public boolean hasOutputLicenses() {
                return true;
            }
        };
        builder.add(LicensesProvider.class, licensesProvider);
    }
    return builder.build();
}
Also used : NestedSetBuilder(com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder) Label(com.google.devtools.build.lib.cmdline.Label) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) ArrayList(java.util.ArrayList) License(com.google.devtools.build.lib.packages.License) TargetLicense(com.google.devtools.build.lib.analysis.LicensesProvider.TargetLicense) LicensesProvider(com.google.devtools.build.lib.analysis.LicensesProvider) Pair(com.google.devtools.build.lib.util.Pair) Path(com.google.devtools.build.lib.vfs.Path) SkyKey(com.google.devtools.build.skyframe.SkyKey) SkyFunction(com.google.devtools.build.skyframe.SkyFunction) IOException(java.io.IOException) Artifact(com.google.devtools.build.lib.actions.Artifact) TargetLicense(com.google.devtools.build.lib.analysis.LicensesProvider.TargetLicense) FileProvider(com.google.devtools.build.lib.analysis.FileProvider) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder) TransitiveInfoCollection(com.google.devtools.build.lib.analysis.TransitiveInfoCollection) FdoException(com.google.devtools.build.lib.rules.cpp.FdoSupport.FdoException)

Example 2 with LicensesProvider

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

the class BuildTool method validateLicensingForTargets.

/**
   * Takes a set of configured targets, and checks if the distribution methods
   * declared for the targets are compatible with the constraints imposed by
   * their prerequisites' licenses.
   *
   * @param configuredTargets the targets to check
   * @param keepGoing if false, and a licensing error is encountered, both
   *        generates an error message on the reporter, <em>and</em> throws an
   *        exception. If true, then just generates a message on the reporter.
   * @throws ViewCreationFailedException if the license checking failed (and not
   *         --keep_going)
   */
private void validateLicensingForTargets(Iterable<ConfiguredTarget> configuredTargets, boolean keepGoing) throws ViewCreationFailedException {
    for (ConfiguredTarget configuredTarget : configuredTargets) {
        final Target target = configuredTarget.getTarget();
        if (TargetUtils.isTestRule(target)) {
            // Tests are exempt from license checking
            continue;
        }
        final Set<DistributionType> distribs = target.getDistributions();
        StaticallyLinkedMarkerProvider markerProvider = configuredTarget.getProvider(StaticallyLinkedMarkerProvider.class);
        boolean staticallyLinked = markerProvider != null && markerProvider.isLinkedStatically();
        LicensesProvider provider = configuredTarget.getProvider(LicensesProvider.class);
        if (provider != null) {
            NestedSet<TargetLicense> licenses = provider.getTransitiveLicenses();
            for (TargetLicense targetLicense : licenses) {
                if (!targetLicense.getLicense().checkCompatibility(distribs, target, targetLicense.getLabel(), getReporter(), staticallyLinked)) {
                    if (!keepGoing) {
                        throw new ViewCreationFailedException("Build aborted due to licensing error");
                    }
                }
            }
        } else if (configuredTarget.getTarget() instanceof InputFile) {
            // Input file targets do not provide licenses because they do not
            // depend on the rule where their license is taken from. This is usually
            // not a problem, because the transitive collection of licenses always
            // hits the rule they come from, except when the input file is a
            // top-level target. Thus, we need to handle that case specially here.
            //
            // See FileTarget#getLicense for more information about the handling of
            // license issues with File targets.
            License license = configuredTarget.getTarget().getLicense();
            if (!license.checkCompatibility(distribs, target, configuredTarget.getLabel(), getReporter(), staticallyLinked)) {
                if (!keepGoing) {
                    throw new ViewCreationFailedException("Build aborted due to licensing error");
                }
            }
        }
    }
}
Also used : ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) Target(com.google.devtools.build.lib.packages.Target) ViewCreationFailedException(com.google.devtools.build.lib.analysis.ViewCreationFailedException) TargetLicense(com.google.devtools.build.lib.analysis.LicensesProvider.TargetLicense) TargetLicense(com.google.devtools.build.lib.analysis.LicensesProvider.TargetLicense) License(com.google.devtools.build.lib.packages.License) LicensesProvider(com.google.devtools.build.lib.analysis.LicensesProvider) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) StaticallyLinkedMarkerProvider(com.google.devtools.build.lib.analysis.StaticallyLinkedMarkerProvider) DistributionType(com.google.devtools.build.lib.packages.License.DistributionType) InputFile(com.google.devtools.build.lib.packages.InputFile)

Aggregations

LicensesProvider (com.google.devtools.build.lib.analysis.LicensesProvider)2 TargetLicense (com.google.devtools.build.lib.analysis.LicensesProvider.TargetLicense)2 License (com.google.devtools.build.lib.packages.License)2 Artifact (com.google.devtools.build.lib.actions.Artifact)1 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)1 FileProvider (com.google.devtools.build.lib.analysis.FileProvider)1 RuleConfiguredTargetBuilder (com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)1 StaticallyLinkedMarkerProvider (com.google.devtools.build.lib.analysis.StaticallyLinkedMarkerProvider)1 TransitiveInfoCollection (com.google.devtools.build.lib.analysis.TransitiveInfoCollection)1 ViewCreationFailedException (com.google.devtools.build.lib.analysis.ViewCreationFailedException)1 Label (com.google.devtools.build.lib.cmdline.Label)1 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)1 InputFile (com.google.devtools.build.lib.packages.InputFile)1 DistributionType (com.google.devtools.build.lib.packages.License.DistributionType)1 Target (com.google.devtools.build.lib.packages.Target)1 FdoException (com.google.devtools.build.lib.rules.cpp.FdoSupport.FdoException)1 Pair (com.google.devtools.build.lib.util.Pair)1 Path (com.google.devtools.build.lib.vfs.Path)1 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)1 SkyFunction (com.google.devtools.build.skyframe.SkyFunction)1