diff options
author | 2016-07-15 20:00:39 +0000 | |
---|---|---|
committer | 2016-07-18 10:44:02 +0000 | |
commit | a2770334ea3f3111026eb3e1368586921468710c (patch) | |
tree | fac21caba6f82c05c3a5bd496b39a1cd0b610fa8 /src/main/java/com/google/devtools | |
parent | bdc2ecbb1b415161c45359d612ec60fa219c45fb (diff) |
Stop input and output of cc_library from clobbering each other.
Before this change:
Any given cc_library can only contribute one library with a given name to
targets which depend on it. If an input library has the same name as the
cc_library which it is an input to, the decision of which to use is based
on the link mode. e.g.,
cc_library(
name = "foo",
srcs = ["foo.c", "libfoo.so"],
)
will only contribute libfoo.a (a static library containing foo.o) in static mode,
while it will only contribute libfoo.so (the precompiled shared library) in dynamic
mode.
This change alters cc_library's behavior in this case:
* If libfoo.a would be empty (i.e., there are no linkable sources), then
this is allowed. The libfoo.so from srcs is simply passed through. (Previously,
the empty libfoo.a would be forwarded.)
* Otherwise, this is an error.
In the case where there are multiple libraries in the srcs with the same
library identifier (lib[name].[a|so|lo]), cc_library will still choose one
based on the link mode. This behavior has not changed.
Similarly, cc_library will still choose one of its own outputs based on the
link mode. That behavior has not changed either.
RELNOTES[INC]: It is now an error to include a precompiled library (.a, .lo, .so)
in a cc_library which would generate a library with the same name
(e.g., libfoo.so in cc_library foo) if that library also contains other linkable
sources.
--
MOS_MIGRATED_REVID=127569615
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java | 51 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingOutputs.java | 18 |
2 files changed, 62 insertions, 7 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java index d6b6a2b2f1..c43404e3b9 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.rules.cpp; import com.google.common.base.Function; +import com.google.common.base.Joiner; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -913,14 +914,50 @@ public final class CcLibraryHelper { 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); + Iterable<LibraryToLink> allLibraries = + Iterables.concat(staticLibraries, picStaticLibraries, dynamicLibraries); + for (LibraryToLink precompiledLibrary : allLibraries) { + List<LibraryToLink> matchingLibs = + originalLinkingOutputs.getLibrariesWithSameIdentifierAs(precompiledLibrary); + if (!matchingLibs.isEmpty()) { + Iterable<String> matchingLibArtifactNames = + Iterables.transform( + matchingLibs, + new Function<LibraryToLink, String>() { + @Override + public String apply(LibraryToLink input) { + return input.getOriginalLibraryArtifact().getFilename(); + } + }); + ruleContext.ruleError( + "Can't put " + + precompiledLibrary.getArtifact().getFilename() + + " 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(matchingLibArtifactNames) + + " (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 = new CcLinkingOutputs.Builder() - .merge(ccLinkingOutputs) - .addStaticLibraries(staticLibraries) - .addPicStaticLibraries(picStaticLibraries) - .addDynamicLibraries(dynamicLibraries) - .addExecutionDynamicLibraries(dynamicLibraries) - .build(); + ccLinkingOutputs = + newOutputsBuilder + .addStaticLibraries(staticLibraries) + .addPicStaticLibraries(picStaticLibraries) + .addDynamicLibraries(dynamicLibraries) + .addExecutionDynamicLibraries(dynamicLibraries) + .build(); } DwoArtifactsCollector dwoArtifacts = diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingOutputs.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingOutputs.java index 9d2ef270cf..aab459989c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingOutputs.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingOutputs.java @@ -69,6 +69,24 @@ public class CcLinkingOutputs { } /** + * Returns all libraries in this CcLinkingOutputs with the same library identifier - i.e., those + * which would be considered different forms of the same library by getPreferredLibrary. + */ + public List<LibraryToLink> getLibrariesWithSameIdentifierAs(LibraryToLink input) { + Iterable<LibraryToLink> allLibraries = + Iterables.concat( + staticLibraries, picStaticLibraries, dynamicLibraries, executionDynamicLibraries); + ImmutableList.Builder<LibraryToLink> result = new ImmutableList.Builder<>(); + for (LibraryToLink library : allLibraries) { + if (libraryIdentifierOf(library.getOriginalLibraryArtifact()) + .equals(libraryIdentifierOf(input.getOriginalLibraryArtifact()))) { + result.add(library); + } + } + return result.build(); + } + + /** * Add the ".a", ".pic.a" and/or ".so" files in appropriate order of preference depending on the * link preferences. * |