use of com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder in project bazel by bazelbuild.
the class ShBinary method create.
@Override
public ConfiguredTarget create(RuleContext ruleContext) throws RuleErrorException {
ImmutableList<Artifact> srcs = ruleContext.getPrerequisiteArtifacts("srcs", Mode.TARGET).list();
if (srcs.size() != 1) {
ruleContext.attributeError("srcs", "you must specify exactly one file in 'srcs'");
return null;
}
Artifact symlink = ruleContext.createOutputArtifact();
// Note that src is used as the executable script too
Artifact src = srcs.get(0);
// The interpretation of this deceptively simple yet incredibly generic rule is complicated
// by the distinction between targets and (not properly encapsulated) artifacts. It depends
// on the notion of other rule's "files-to-build" sets, which are undocumented, making it
// impossible to give a precise definition of what this rule does in all cases (e.g. what
// happens when srcs = ['x', 'y'] but 'x' is an empty filegroup?). This is a pervasive
// problem in Blaze.
ruleContext.registerAction(new ExecutableSymlinkAction(ruleContext.getActionOwner(), src, symlink));
NestedSet<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder().add(src).add(symlink).build();
Runfiles runfiles = new Runfiles.Builder(ruleContext.getWorkspaceName(), ruleContext.getConfiguration().legacyExternalRunfiles()).addTransitiveArtifacts(filesToBuild).addRunfiles(ruleContext, RunfilesProvider.DEFAULT_RUNFILES).build();
RunfilesSupport runfilesSupport = RunfilesSupport.withExecutable(ruleContext, runfiles, symlink);
return new RuleConfiguredTargetBuilder(ruleContext).setFilesToBuild(filesToBuild).setRunfilesSupport(runfilesSupport, symlink).addProvider(RunfilesProvider.class, RunfilesProvider.simple(runfiles)).build();
}
use of com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder in project bazel by bazelbuild.
the class ShLibrary method create.
@Override
public ConfiguredTarget create(RuleContext ruleContext) throws RuleErrorException {
NestedSet<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder().addAll(ruleContext.getPrerequisiteArtifacts("srcs", Mode.TARGET).list()).addAll(ruleContext.getPrerequisiteArtifacts("deps", Mode.TARGET).list()).addAll(ruleContext.getPrerequisiteArtifacts("data", Mode.DATA).list()).build();
Runfiles runfiles = new Runfiles.Builder(ruleContext.getWorkspaceName(), ruleContext.getConfiguration().legacyExternalRunfiles()).addTransitiveArtifacts(filesToBuild).build();
return new RuleConfiguredTargetBuilder(ruleContext).setFilesToBuild(filesToBuild).addProvider(RunfilesProvider.class, RunfilesProvider.simple(runfiles)).build();
}
use of com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder 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();
}
use of com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder 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();
}
use of com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder 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();
}
Aggregations