aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
diff options
context:
space:
mode:
authorGravatar Yun Peng <pcloudy@google.com>2017-09-15 15:59:14 +0200
committerGravatar László Csomor <laszlocsomor@google.com>2017-09-18 11:25:37 +0200
commit394211bf88b88c25036429e99894fa7c60eaaace (patch)
treea5a99354a9f3b8530bb0d98d61d8844b21348ecd /src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
parentf8480fac37692083b2f9c4e69b9b9e9e2c9b1853 (diff)
Bazel now can build dynamic library from cc_library
Working towards: https://github.com/bazelbuild/bazel/issues/3311 When building dynamic library on Windows, Bazel builds an import library and a DLL. Bazel provides a feature called windows_export_all_symbols, if this feature is enabled(and no_windows_export_all_symbols is not) for a cc_library, then Bazel parses object files of that cc_library to generate a DEF file that will be used during linking time to export symbols from DLL. This feature can be specified at crosstool, package, target and command line level. A few differences from Unix platforms: 1. We don't build the shared library on Windows by default, users have to specifiy --output_groups=dynamic_library for building dynamic libraries. This output group is also available on other platforms. 2. By default, cc_test is dynamically linked on Unix, but it will be statically linked on Windows by default. (meaning the default value of linkstatic in cc_test is 1 on Windows, and 0 on other platforms) 3. For global data symbols, __declspec(dllimport) must still be used in source files. Remaining issues: 1. Extensions for import library and DLL are not correct yet. 2. DLLs are not guaranteed to be available during runtime yet. 3. Diamond problem If a cc_library A is specified as linkstatic=0, then no dynamic library will be built for it, so if another cc_library B depends on it, A will be statically linked into B, and if a cc_binary C depends on B, A will also be statically linked into C and B will be dynamically linked to C. This is wrong because A is duplicated in both B and C. It is essentially a diamond problem describled in C++ Transitive Library. (https://docs.google.com/document/d/1-tv0_79zGyBoDmaP_pYWaBVUwHUteLpAs90_rUl-VY8/edit?usp=sharing) Hopefully, we can avoid this by using cc_shared_library rule in future. Change-Id: I23640d4caf8afe65d60b1522af6368536d7a8408 PiperOrigin-RevId: 168829958
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java33
1 files changed, 24 insertions, 9 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 b846dfaef3..e90dda7c54 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
@@ -187,11 +187,17 @@ public abstract class CcLibrary implements RuleConfiguredTargetFactory {
// 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 =
+ ImmutableList.Builder<Artifact> dynamicLibraries = ImmutableList.builder();
+ dynamicLibraries.add(
+ CppHelper.getLinuxLinkedArtifact(
+ ruleContext, ruleContext.getConfiguration(), LinkTargetType.DYNAMIC_LIBRARY));
+ if (ccToolchain.getCppConfiguration().useInterfaceSharedObjects()) {
+ dynamicLibraries.add(
CppHelper.getLinuxLinkedArtifact(
- ruleContext, ruleContext.getConfiguration(), LinkTargetType.DYNAMIC_LIBRARY);
+ ruleContext, ruleContext.getConfiguration(), LinkTargetType.INTERFACE_DYNAMIC_LIBRARY));
+ }
ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(),
- ImmutableList.of(solibArtifact), "Toolchain does not support dynamic linking"));
+ dynamicLibraries.build(), "Toolchain does not support dynamic linking"));
} else if (!createDynamicLibrary
&& ruleContext.attributes().isConfigurable("srcs")) {
// If "srcs" is configurable, the .so output is always declared because the logic that
@@ -199,11 +205,17 @@ public abstract class CcLibrary implements RuleConfiguredTargetFactory {
// 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.
- Artifact solibArtifact =
+ ImmutableList.Builder<Artifact> dynamicLibraries = ImmutableList.builder();
+ dynamicLibraries.add(
+ CppHelper.getLinuxLinkedArtifact(
+ ruleContext, ruleContext.getConfiguration(), LinkTargetType.DYNAMIC_LIBRARY));
+ if (ccToolchain.getCppConfiguration().useInterfaceSharedObjects()) {
+ dynamicLibraries.add(
CppHelper.getLinuxLinkedArtifact(
- ruleContext, ruleContext.getConfiguration(), LinkTargetType.DYNAMIC_LIBRARY);
+ ruleContext, ruleContext.getConfiguration(), LinkTargetType.INTERFACE_DYNAMIC_LIBRARY));
+ }
ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(),
- ImmutableList.of(solibArtifact), "configurable \"srcs\" triggers an implicit .so output "
+ dynamicLibraries.build(), "configurable \"srcs\" triggers an implicit .so output "
+ "even though there are no sources to compile in this configuration"));
}
@@ -258,9 +270,12 @@ public abstract class CcLibrary implements RuleConfiguredTargetFactory {
NestedSetBuilder<Artifact> filesBuilder = NestedSetBuilder.stableOrder();
filesBuilder.addAll(LinkerInputs.toLibraryArtifacts(linkedLibraries.getStaticLibraries()));
filesBuilder.addAll(LinkerInputs.toLibraryArtifacts(linkedLibraries.getPicStaticLibraries()));
- filesBuilder.addAll(LinkerInputs.toNonSolibArtifacts(linkedLibraries.getDynamicLibraries()));
- filesBuilder.addAll(
- LinkerInputs.toNonSolibArtifacts(linkedLibraries.getExecutionDynamicLibraries()));
+
+ if (!featureConfiguration.isEnabled(CppRuleClasses.TARGETS_WINDOWS)) {
+ filesBuilder.addAll(LinkerInputs.toNonSolibArtifacts(linkedLibraries.getDynamicLibraries()));
+ filesBuilder.addAll(
+ LinkerInputs.toNonSolibArtifacts(linkedLibraries.getExecutionDynamicLibraries()));
+ }
CcLinkingOutputs linkingOutputs = info.getCcLinkingOutputs();
if (!featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULE_CODEGEN)) {