Skip to content

Commit

Permalink
Allow setting supports_embedded_runtimes crosstool capability using f…
Browse files Browse the repository at this point in the history
…eature

`supports_embedded_runtimes` can now be expressed using 'static_link_cpp_runtimes' feature (should be enabled for it to take effect).

This cl allows toolchain owners to express that toolchain supports embedded runtimes in the same way as other crosstool capabilities are expressed.

This cl is a step towards #5883. Also
see the rollout doc here:
https://docs.google.com/document/d/1uv4c1zag6KvdI31qdx8C6jiTognXPQrxgsUpVefm9fM/edit#.

Flag removing legacy behavior is #6861

RELNOTES: None.
PiperOrigin-RevId: 227024509
  • Loading branch information
hlopko authored and Copybara-Service committed Dec 27, 2018
1 parent a600138 commit d717118
Show file tree
Hide file tree
Showing 18 changed files with 150 additions and 76 deletions.
10 changes: 10 additions & 0 deletions site/docs/crosstool-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1042,4 +1042,14 @@ conditions.
libraries.
</td>
</tr>
<tr>
<td><strong><code>static_link_cpp_runtimes</code></strong>
</td>
<td>If enabled, Bazel will link the C++ runtime statically in static linking
mode and dynamically in dynamic linking mode. Artifacts
specified in the <code>cc_toolchain.static_runtime_lib</code> or
<code>cc_toolchain.dynamic_runtime_lib</code> attribute (depending on the
linking mode) will be added to the linking actions.
</td>
</tr>
</table>
1 change: 1 addition & 0 deletions src/main/java/com/google/devtools/build/lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,7 @@ java_library(
),
deps = [
":build-base",
":packages-internal",
":util",
"//src/main/java/com/google/devtools/build/lib/actions",
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.cpp.CcLinkParams;
import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider;
import com.google.devtools.build.lib.rules.cpp.CppFileTypes;
Expand Down Expand Up @@ -60,7 +61,7 @@ public static NativeLibs fromLinkedNativeDeps(
ImmutableList<String> depsAttributes,
String nativeDepsFileName,
CppSemantics cppSemantics)
throws InterruptedException {
throws InterruptedException, RuleErrorException {
Map<String, CcToolchainProvider> toolchainsByCpu = getToolchainsByCpu(ruleContext);
Map<String, BuildConfiguration> configurationMap = getBuildConfigurationsByCpu(ruleContext);
Map<String, NestedSet<Artifact>> result = new LinkedHashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ private static Runfiles collectRunfiles(
Iterable<Artifact> fakeLinkerInputs,
boolean fake,
ImmutableSet<CppSource> cAndCppSources,
boolean linkCompileOutputSeparately) {
boolean linkCompileOutputSeparately)
throws RuleErrorException {
Runfiles.Builder builder =
new Runfiles.Builder(
ruleContext.getWorkspaceName(),
Expand All @@ -189,7 +190,8 @@ private static Runfiles collectRunfiles(
builder.add(ruleContext, runfilesMapping);
// Add the C++ runtime libraries if linking them dynamically.
if (linkingMode == Link.LinkingMode.DYNAMIC) {
builder.addTransitiveArtifacts(toolchain.getDynamicRuntimeLinkInputs(featureConfiguration));
builder.addTransitiveArtifacts(
toolchain.getDynamicRuntimeLinkInputs(ruleContext, featureConfiguration));
}
if (linkCompileOutputSeparately) {
builder.addArtifacts(
Expand Down Expand Up @@ -664,7 +666,7 @@ public static Pair<CcLinkingOutputs, CcLauncherInfo> createTransitiveLinkingActi
// Only force a static link of libgcc if static runtime linking is enabled (which
// can't be true if runtimeInputs is empty).
// TODO(bazel-team): Move this to CcToolchain.
if (!ccToolchain.getStaticRuntimeLinkInputs(featureConfiguration).isEmpty()) {
if (!ccToolchain.getStaticRuntimeLinkInputs(ruleContext, featureConfiguration).isEmpty()) {
ccLinkParamsBuilder.addLinkOpts(ImmutableList.of("-static-libgcc"));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -826,10 +826,16 @@ public static FeatureConfiguration configureFeaturesOrThrowEvalException(
if (toolchain.getCcInfo().getCcCompilationContext().getCppModuleMap() == null) {
unsupportedFeaturesBuilder.add(CppRuleClasses.MODULE_MAPS);
}
if (enableStaticLinkCppRuntimesFeature(requestedFeatures, unsupportedFeatures, toolchain)) {
allRequestedFeaturesBuilder.add(CppRuleClasses.STATIC_LINK_CPP_RUNTIMES);
} else {
unsupportedFeaturesBuilder.add(CppRuleClasses.STATIC_LINK_CPP_RUNTIMES);
// If we're not using legacy crosstool fields, we assume 'static_link_cpp_runtimes' feature
// is enabled by default for toolchains that support it, and can be disabled by the user
// when needed using --feature=-static_link_cpp_runtimes option or
// features = [ '-static_link_cpp_runtimes' ] rule attribute.
if (!cppConfiguration.disableLegacyCrosstoolFields()) {
if (enableStaticLinkCppRuntimesFeature(requestedFeatures, unsupportedFeatures, toolchain)) {
allRequestedFeaturesBuilder.add(CppRuleClasses.STATIC_LINK_CPP_RUNTIMES);
} else {
unsupportedFeaturesBuilder.add(CppRuleClasses.STATIC_LINK_CPP_RUNTIMES);
}
}

ImmutableSet<String> allUnsupportedFeatures = unsupportedFeaturesBuilder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,8 @@ public static void init(
builder.addDataDeps(ruleContext);
builder.add(ruleContext, RunfilesProvider.DEFAULT_RUNFILES);
if (addDynamicRuntimeInputArtifactsToRunfiles) {
builder.addTransitiveArtifacts(ccToolchain.getDynamicRuntimeLinkInputs(featureConfiguration));
builder.addTransitiveArtifacts(
ccToolchain.getDynamicRuntimeLinkInputs(ruleContext, featureConfiguration));
}
Runfiles runfiles = builder.build();
Runfiles.Builder defaultRunfiles =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -647,13 +647,13 @@ private void createDynamicLibrary(
if (linkingMode == LinkingMode.DYNAMIC) {
dynamicLinkActionBuilder.setRuntimeInputs(
ArtifactCategory.DYNAMIC_LIBRARY,
ccToolchain.getDynamicRuntimeLinkMiddleman(featureConfiguration),
ccToolchain.getDynamicRuntimeLinkInputs(featureConfiguration));
ccToolchain.getDynamicRuntimeLinkMiddleman(ruleContext, featureConfiguration),
ccToolchain.getDynamicRuntimeLinkInputs(ruleContext, featureConfiguration));
} else {
dynamicLinkActionBuilder.setRuntimeInputs(
ArtifactCategory.STATIC_LIBRARY,
ccToolchain.getStaticRuntimeLinkMiddleman(featureConfiguration),
ccToolchain.getStaticRuntimeLinkInputs(featureConfiguration));
ccToolchain.getStaticRuntimeLinkMiddleman(ruleContext, featureConfiguration),
ccToolchain.getStaticRuntimeLinkInputs(ruleContext, featureConfiguration));
}

if (CppLinkAction.enableSymbolsCounts(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.LicensesProvider;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
Expand All @@ -29,6 +30,8 @@
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.packages.RuleErrorConsumer;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
import com.google.devtools.build.lib.rules.cpp.FdoProvider.FdoMode;
Expand Down Expand Up @@ -105,9 +108,9 @@ public final class CcToolchainProvider extends ToolchainInfo
private final NestedSet<Artifact> dwpFiles;
private final NestedSet<Artifact> coverageFiles;
private final NestedSet<Artifact> libcLink;
private final NestedSet<Artifact> staticRuntimeLinkInputs;
@Nullable private final NestedSet<Artifact> staticRuntimeLinkInputs;
@Nullable private final Artifact staticRuntimeLinkMiddleman;
private final NestedSet<Artifact> dynamicRuntimeLinkInputs;
@Nullable private final NestedSet<Artifact> dynamicRuntimeLinkInputs;
@Nullable private final Artifact dynamicRuntimeLinkMiddleman;
private final PathFragment dynamicRuntimeSolibDir;
private final CcInfo ccInfo;
Expand Down Expand Up @@ -189,9 +192,9 @@ public CcToolchainProvider(
this.dwpFiles = Preconditions.checkNotNull(dwpFiles);
this.coverageFiles = Preconditions.checkNotNull(coverageFiles);
this.libcLink = Preconditions.checkNotNull(libcLink);
this.staticRuntimeLinkInputs = Preconditions.checkNotNull(staticRuntimeLinkInputs);
this.staticRuntimeLinkInputs = staticRuntimeLinkInputs;
this.staticRuntimeLinkMiddleman = staticRuntimeLinkMiddleman;
this.dynamicRuntimeLinkInputs = Preconditions.checkNotNull(dynamicRuntimeLinkInputs);
this.dynamicRuntimeLinkInputs = dynamicRuntimeLinkInputs;
this.dynamicRuntimeLinkMiddleman = dynamicRuntimeLinkMiddleman;
this.dynamicRuntimeSolibDir = Preconditions.checkNotNull(dynamicRuntimeSolibDir);
this.ccInfo =
Expand Down Expand Up @@ -437,8 +440,15 @@ public boolean shouldStaticallyLinkCppRuntimes(FeatureConfiguration featureConfi
}

/** Returns the static runtime libraries. */
public NestedSet<Artifact> getStaticRuntimeLinkInputs(FeatureConfiguration featureConfiguration) {
public NestedSet<Artifact> getStaticRuntimeLinkInputs(
RuleContext ruleContext, FeatureConfiguration featureConfiguration)
throws RuleErrorException {
if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
if (staticRuntimeLinkInputs == null) {
throw ruleContext.throwWithRuleError(
"Toolchain supports embedded runtimes, but didn't "
+ "provide static_runtime_lib attribute.");
}
return staticRuntimeLinkInputs;
} else {
return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
Expand All @@ -447,8 +457,15 @@ public NestedSet<Artifact> getStaticRuntimeLinkInputs(FeatureConfiguration featu

/** Returns an aggregating middleman that represents the static runtime libraries. */
@Nullable
public Artifact getStaticRuntimeLinkMiddleman(FeatureConfiguration featureConfiguration) {
public Artifact getStaticRuntimeLinkMiddleman(
RuleContext ruleContext, FeatureConfiguration featureConfiguration)
throws RuleErrorException {
if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
if (staticRuntimeLinkInputs == null) {
throw ruleContext.throwWithRuleError(
"Toolchain supports embedded runtimes, but didn't "
+ "provide static_runtime_lib attribute.");
}
return staticRuntimeLinkMiddleman;
} else {
return null;
Expand All @@ -457,8 +474,14 @@ public Artifact getStaticRuntimeLinkMiddleman(FeatureConfiguration featureConfig

/** Returns the dynamic runtime libraries. */
public NestedSet<Artifact> getDynamicRuntimeLinkInputs(
FeatureConfiguration featureConfiguration) {
RuleErrorConsumer ruleContext, FeatureConfiguration featureConfiguration)
throws RuleErrorException {
if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
if (dynamicRuntimeLinkInputs == null) {
throw ruleContext.throwWithRuleError(
"Toolchain supports embedded runtimes, but didn't "
+ "provide dynamic_runtime_lib attribute.");
}
return dynamicRuntimeLinkInputs;
} else {
return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
Expand All @@ -467,8 +490,15 @@ public NestedSet<Artifact> getDynamicRuntimeLinkInputs(

/** Returns an aggregating middleman that represents the dynamic runtime libraries. */
@Nullable
public Artifact getDynamicRuntimeLinkMiddleman(FeatureConfiguration featureConfiguration) {
public Artifact getDynamicRuntimeLinkMiddleman(
RuleErrorConsumer ruleContext, FeatureConfiguration featureConfiguration)
throws RuleErrorException {
if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
if (dynamicRuntimeLinkInputs == null) {
throw ruleContext.throwWithRuleError(
"Toolchain supports embedded runtimes, but didn't "
+ "provide dynamic_runtime_lib attribute.");
}
return dynamicRuntimeLinkMiddleman;
} else {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,33 +487,28 @@ static CcToolchainProvider getCcToolchainProvider(
attributes.getStaticRuntimesLibs(), toolchainInfo.getStaticRuntimeLibsLabel());
final NestedSet<Artifact> staticRuntimeLinkInputs;
final Artifact staticRuntimeLinkMiddleman;
if (toolchainInfo.supportsEmbeddedRuntimes()) {
if (staticRuntimeLibDep == null) {
throw ruleContext.throwWithRuleError(
"Toolchain supports embedded runtimes, but didn't "
+ "provide static_runtime_lib attribute.");
}

if (staticRuntimeLibDep != null) {
staticRuntimeLinkInputs =
staticRuntimeLibDep.getProvider(FileProvider.class).getFilesToBuild();
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());
} 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 {
staticRuntimeLinkInputs = null;
staticRuntimeLinkMiddleman = null;
}

Preconditions.checkState(
(staticRuntimeLinkMiddleman == null) == staticRuntimeLinkInputs.isEmpty());

// Dynamic runtime inputs.
if (cppConfiguration.disableRuntimesFilegroups()
&& !attributes.getDynamicRuntimesLibs().isEmpty()) {
Expand All @@ -530,12 +525,7 @@ static CcToolchainProvider getCcToolchainProvider(
NestedSet<Artifact> dynamicRuntimeLinkSymlinks;
List<Artifact> dynamicRuntimeLinkInputs = new ArrayList<>();
Artifact dynamicRuntimeLinkMiddleman;
if (toolchainInfo.supportsEmbeddedRuntimes()) {
if (dynamicRuntimeLibDep == null) {
throw ruleContext.throwWithRuleError(
"Toolchain supports embedded runtimes, but didn't "
+ "provide dynamic_runtime_lib attribute.");
}
if (dynamicRuntimeLibDep != null) {
NestedSetBuilder<Artifact> dynamicRuntimeLinkSymlinksBuilder = NestedSetBuilder.stableOrder();
for (Artifact artifact :
dynamicRuntimeLibDep.getProvider(FileProvider.class).getFilesToBuild()) {
Expand All @@ -550,9 +540,14 @@ static CcToolchainProvider getCcToolchainProvider(
configuration));
}
}
dynamicRuntimeLinkSymlinks = dynamicRuntimeLinkSymlinksBuilder.build();
if (dynamicRuntimeLinkInputs.isEmpty()) {
dynamicRuntimeLinkSymlinks = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
} else {
dynamicRuntimeLinkSymlinks = dynamicRuntimeLinkSymlinksBuilder.build();
}

} else {
dynamicRuntimeLinkSymlinks = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
dynamicRuntimeLinkSymlinks = null;
}

if (!dynamicRuntimeLinkInputs.isEmpty()) {
Expand All @@ -573,7 +568,8 @@ static CcToolchainProvider getCcToolchainProvider(
}

Preconditions.checkState(
(dynamicRuntimeLinkMiddleman == null) == dynamicRuntimeLinkSymlinks.isEmpty());
(dynamicRuntimeLinkMiddleman == null)
== (dynamicRuntimeLinkSymlinks == null || dynamicRuntimeLinkSymlinks.isEmpty()));

CcCompilationContext.Builder ccCompilationContextBuilder =
new CcCompilationContext.Builder(ruleContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,18 @@ Currently unused (<a href="https://github.com/bazelbuild/bazel/issues/6928">#692
Static library artifact for the C++ runtime library (e.g. libstdc++.a).
<p>When specified, this will take precedence over 'static_runtime_libs'.</p>
<p>This will be used when 'static_link_cpp_runtimes' feature is enabled, and we're linking
dependencies statically.</p>
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("static_runtime_lib", LABEL).legacyAllowAnyFileType())
/* <!-- #BLAZE_RULE(cc_toolchain).ATTRIBUTE(dynamic_runtime_lib) -->
Dynamic library artifact for the C++ runtime library (e.g. libstdc++.so).
<p>When specified, this will take precedence over 'dynamic_runtime_libs'.</p>
<p>This will be used when 'static_link_cpp_runtimes' feature is enabled, and we're linking
dependencies dynamically.</p>
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("dynamic_runtime_lib", LABEL).legacyAllowAnyFileType())
/* <!-- #BLAZE_RULE(cc_toolchain).ATTRIBUTE(static_runtime_libs) -->
Expand All @@ -234,6 +240,9 @@ Currently unused (<a href="https://github.com/bazelbuild/bazel/issues/6928">#692
<p>cc_toolchain will select one of these libraries based on the label from
crosstool_proto.static_runtimes_filegroup field.</p>
<p>This will be used when 'static_link_cpp_runtimes' feature is enabled, and we're linking
dependencies statically.</p>
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("static_runtime_libs", LABEL_LIST).legacyAllowAnyFileType())
/* <!-- #BLAZE_RULE(cc_toolchain).ATTRIBUTE(dynamic_runtime_libs) -->
Expand All @@ -244,6 +253,9 @@ Currently unused (<a href="https://github.com/bazelbuild/bazel/issues/6928">#692
<p>cc_toolchain will select one of these libraries based on the label from
crosstool_proto.dynamic_runtimes_filegroup field.</p>
<p>This will be used when 'static_link_cpp_runtimes' feature is enabled, and we're linking
dependencies dynamically.</p>
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("dynamic_runtime_libs", LABEL_LIST).legacyAllowAnyFileType())
/* <!-- #BLAZE_RULE(cc_toolchain).ATTRIBUTE(module_map) -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ public static ImmutableList<CToolchain.Feature> getLegacyFeatures(
" }",
" }")));
}
if (supportsEmbeddedRuntimes && !existingFeatureNames.contains("static_libgcc")) {
if (!existingFeatureNames.contains("static_libgcc")) {
featureBuilder.add(
getFeature(
Joiner.on("\n")
Expand Down
Loading

0 comments on commit d717118

Please sign in to comment.