aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
authorGravatar Michael Staib <mstaib@google.com>2016-07-15 20:00:39 +0000
committerGravatar Yun Peng <pcloudy@google.com>2016-07-18 10:44:02 +0000
commita2770334ea3f3111026eb3e1368586921468710c (patch)
treefac21caba6f82c05c3a5bd496b39a1cd0b610fa8 /src/main/java/com/google/devtools
parentbdc2ecbb1b415161c45359d612ec60fa219c45fb (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.java51
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingOutputs.java18
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.
*