diff options
author | 2016-02-08 16:00:09 +0000 | |
---|---|---|
committer | 2016-02-09 12:17:02 +0000 | |
commit | 3dd9cc68d35b460c69bea66d4c4cbcbfe2b210be (patch) | |
tree | 9957db189f5983d5a203953aabc9d49afd8a2080 /src/main/java/com | |
parent | 913d0f5addc3b315bbd812e0496e564834fe9468 (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.java | 16 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java | 31 |
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. */ |