aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2016-02-08 16:00:09 +0000
committerGravatar Dmitry Lomov <dslomov@google.com>2016-02-09 12:17:02 +0000
commit3dd9cc68d35b460c69bea66d4c4cbcbfe2b210be (patch)
tree9957db189f5983d5a203953aabc9d49afd8a2080 /src/main/java/com
parent913d0f5addc3b315bbd812e0496e564834fe9468 (diff)
Add supportsDynamicLinker to CppConfiguration
Rather than a new protobuf field, this enabling flag is presence of a section with DYNAMIC linking mode in the CROSSTOOL file, whether or not it needs to specify any linker flags. RELNOTES[NEW]: Better support for toolchains that don't have a dynamic linker. -- MOS_MIGRATED_REVID=114110200
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java31
2 files changed, 42 insertions, 5 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
index 700de93de5..fe6428b1b7 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
@@ -138,8 +138,10 @@ public abstract class CcLibrary implements RuleConfiguredTargetFactory {
}
Artifact soImplArtifact = null;
+ boolean supportsDynamicLinker =
+ ruleContext.getFragment(CppConfiguration.class).supportsDynamicLinker();
boolean createDynamicLibrary =
- !linkStatic && appearsToHaveObjectFiles(ruleContext.attributes());
+ !linkStatic && appearsToHaveObjectFiles(ruleContext.attributes()) && supportsDynamicLinker;
if (ruleContext.getRule().isAttrDefined("outs", Type.STRING_LIST)) {
List<String> outs = ruleContext.attributes().get("outs", Type.STRING_LIST);
if (outs.size() > 1) {
@@ -178,13 +180,21 @@ public abstract class CcLibrary implements RuleConfiguredTargetFactory {
helper.setCreateDynamicLibrary(createDynamicLibrary);
helper.setDynamicLibrary(soImplArtifact);
+ // If the reason we're not creating a dynamic library is that the toolchain
+ // doesn't support it, then register an action which complains when triggered,
+ // which only happens when some rule explicitly depends on the dynamic library.
+ if (!createDynamicLibrary && !supportsDynamicLinker) {
+ Artifact solibArtifact = CppHelper.getLinkedArtifact(
+ ruleContext, LinkTargetType.DYNAMIC_LIBRARY);
+ ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(),
+ ImmutableList.of(solibArtifact), "Toolchain does not support dynamic linking"));
+ } else if (!createDynamicLibrary
+ && ruleContext.attributes().isConfigurable("srcs", BuildType.LABEL_LIST)) {
// If "srcs" is configurable, the .so output is always declared because the logic that
// determines implicit outs doesn't know which value of "srcs" will ultimately get chosen. Here,
// where we *do* have the correct value, it may not contain any source files to generate an
// .so with. If that's the case, register a fake generating action to prevent a "no generating
// action for this artifact" error.
- if (!createDynamicLibrary
- && ruleContext.attributes().isConfigurable("srcs", BuildType.LABEL_LIST)) {
Artifact solibArtifact = CppHelper.getLinkedArtifact(
ruleContext, LinkTargetType.DYNAMIC_LIBRARY);
ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
index 2b9dca28ef..d67f0058d1 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
@@ -284,6 +284,7 @@ public class CppConfiguration extends BuildConfiguration.Fragment {
private final boolean supportsGoldLinker;
private final boolean supportsThinArchives;
private final boolean supportsStartEndLib;
+ private final boolean supportsDynamicLinker;
private final boolean supportsInterfaceSharedObjects;
private final boolean supportsEmbeddedRuntimes;
private final boolean supportsFission;
@@ -507,16 +508,35 @@ public class CppConfiguration extends BuildConfiguration.Fragment {
}
linkOptionsFromLinkingMode = ArrayListMultimap.create();
+
+ // If a toolchain supports dynamic libraries at all, there must be at least one
+ // of the following:
+ // - a "DYNAMIC" section in linking_mode_flags (even if no flags are needed)
+ // - a non-empty list in one of the dynamicLibraryLinkerFlag fields
+ // If none of the above contain data, then the toolchain can't do dynamic linking.
+ boolean haveDynamicMode = false;
+
for (LinkingModeFlags flags : toolchain.getLinkingModeFlagsList()) {
LinkingMode realmode = importLinkingMode(flags.getMode());
+ if (realmode == LinkingMode.DYNAMIC) {
+ haveDynamicMode = true;
+ }
linkOptionsFromLinkingMode.putAll(realmode, flags.getLinkerFlagList());
}
this.commonLinkOptions = ImmutableList.copyOf(toolchain.getLinkerFlagList());
+ List<String> linkerFlagList = toolchain.getDynamicLibraryLinkerFlagList();
+ List<CToolchain.OptionalFlag> optionalLinkerFlagList =
+ toolchain.getOptionalDynamicLibraryLinkerFlagList();
+ if (!linkerFlagList.isEmpty() || !optionalLinkerFlagList.isEmpty()) {
+ haveDynamicMode = true;
+ }
+ this.supportsDynamicLinker = haveDynamicMode;
dynamicLibraryLinkFlags = new FlagList(
- ImmutableList.copyOf(toolchain.getDynamicLibraryLinkerFlagList()),
- convertOptionalOptions(toolchain.getOptionalDynamicLibraryLinkerFlagList()),
+ ImmutableList.copyOf(linkerFlagList),
+ convertOptionalOptions(optionalLinkerFlagList),
ImmutableList.<String>of());
+
this.objcopyOptions = ImmutableList.copyOf(toolchain.getObjcopyEmbedFlagList());
this.ldOptions = ImmutableList.copyOf(toolchain.getLdEmbedFlagList());
this.arOptions = copyOrDefaultIfEmpty(toolchain.getArFlagList(), "rcsD");
@@ -1093,6 +1113,13 @@ public class CppConfiguration extends BuildConfiguration.Fragment {
}
/**
+ * Returns whether the toolchain supports dynamic linking.
+ */
+ public boolean supportsDynamicLinker() {
+ return supportsDynamicLinker;
+ }
+
+ /**
* Returns whether build_interface_so can build interface shared objects for this toolchain.
* Should be true if this toolchain generates ELF objects.
*/