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