aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build
diff options
context:
space:
mode:
authorGravatar Yun Peng <pcloudy@google.com>2017-09-28 08:23:57 -0400
committerGravatar John Cater <jcater@google.com>2017-09-28 08:55:26 -0400
commit90a4a18c62778def22641b4df06e58b3cc7dfc3e (patch)
treefb6fb4ef0d5fa83d18eb0c71a7a487ba58bc74f7 /src/main/java/com/google/devtools/build
parent6ee36ef239b25f66afa83e2657bd0b529b1ff50e (diff)
Make windows_export_all_symbols feature work for cc_binary
Now Bazel can also export symbols when building dynamic library from cc_binary. The interface library generated can be accessed by interface_library output group. The DEF file can still be accessed by def_file output group even when windows_export_all_symbols feature is not specified. This is useful when users want to filter symbols in DEF file before using it, for example, working around the 64K symbols number limit. Change-Id: I5b4dae0840e20037c00d500181c40b5faedfdcd8 PiperOrigin-RevId: 170330409
Diffstat (limited to 'src/main/java/com/google/devtools/build')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java40
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java63
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java73
3 files changed, 110 insertions, 66 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
index 742e5dd37c..6b00ae0d69 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
@@ -290,8 +290,40 @@ public abstract class CcBinary implements RuleConfiguredTargetFactory {
CppLinkAction.symbolCountsFileName(binaryPath)));
}
+ Artifact defFile = null;
+ Artifact interfaceLibrary = null;
if (isLinkShared(ruleContext)) {
linkActionBuilder.setLibraryIdentifier(CcLinkingOutputs.libraryIdentifierOf(binary));
+
+ if (featureConfiguration.isEnabled(CppRuleClasses.TARGETS_WINDOWS)) {
+ ImmutableList.Builder<Artifact> objectFiles = ImmutableList.builder();
+ objectFiles.addAll(ccCompilationOutputs.getObjectFiles(false));
+ for (LibraryToLink library : linkParams.getLibraries()) {
+ if (library.containsObjectFiles()
+ && library.getArtifactCategory() != ArtifactCategory.DYNAMIC_LIBRARY
+ && library.getArtifactCategory() != ArtifactCategory.INTERFACE_LIBRARY) {
+ objectFiles.addAll(library.getObjectFiles());
+ }
+ }
+ defFile =
+ CppHelper.createDefFileActions(
+ ruleContext,
+ ccToolchain.getDefParserTool(),
+ objectFiles.build(),
+ binary.getFilename());
+
+ if (CppHelper.shouldUseDefFile(featureConfiguration)) {
+ linkActionBuilder.setDefFile(defFile);
+ }
+
+ // If we are using a toolchain supporting interface library and targeting Windows, we build
+ // the interface library with the link action and add it to `interface_output` output group.
+ if (cppConfiguration.useInterfaceSharedObjects()) {
+ interfaceLibrary = ruleContext.getRelatedArtifact(binary.getRootRelativePath(), ".ifso");
+ linkActionBuilder.setInterfaceOutput(interfaceLibrary);
+ linkActionBuilder.addActionOutput(interfaceLibrary);
+ }
+ }
}
// Store immutable context for use in other *_binary rules that are implemented by
@@ -451,6 +483,14 @@ public abstract class CcBinary implements RuleConfiguredTargetFactory {
ruleBuilder.addOutputGroup("pdb_file", pdbFile);
}
+ if (defFile != null) {
+ ruleBuilder.addOutputGroup("def_file", defFile);
+ }
+
+ if (interfaceLibrary != null) {
+ ruleBuilder.addOutputGroup("interface_library", interfaceLibrary);
+ }
+
return ruleBuilder
.addProvider(RunfilesProvider.class, RunfilesProvider.simple(runfiles))
.addProvider(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
index 5bc125633e..e5c871ef8a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.rules.cpp;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
@@ -24,6 +25,7 @@ import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.MiddlemanFactory;
+import com.google.devtools.build.lib.actions.ParameterFile;
import com.google.devtools.build.lib.analysis.AnalysisUtils;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.PlatformConfiguration;
@@ -33,6 +35,7 @@ import com.google.devtools.build.lib.analysis.StaticallyLinkedMarkerProvider;
import com.google.devtools.build.lib.analysis.ToolchainContext.ResolvedToolchainProviders;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
+import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
@@ -761,4 +764,64 @@ public class CppHelper {
return getArtifactNameForCategory(
ruleContext, toolchain, ArtifactCategory.INCLUDED_FILE_LIST, baseName);
}
+
+ /**
+ * Returns true when {@link CppRuleClasses#WINDOWS_EXPORT_ALL_SYMBOLS} feature is enabled and
+ * {@link CppRuleClasses#NO_WINDOWS_EXPORT_ALL_SYMBOLS} feature is not enabled.
+ */
+ public static boolean shouldUseDefFile(FeatureConfiguration featureConfiguration) {
+ return featureConfiguration.isEnabled(CppRuleClasses.WINDOWS_EXPORT_ALL_SYMBOLS)
+ && !featureConfiguration.isEnabled(CppRuleClasses.NO_WINDOWS_EXPORT_ALL_SYMBOLS);
+ }
+
+ /**
+ * Create actions for parsing object files to generate a DEF file, should only be used when
+ * targeting Windows.
+ *
+ * @param defParser The tool we use to parse object files for generating the DEF file.
+ * @param objectFiles A list of object files to parse
+ * @param dllName The DLL name to be written into the DEF file, it specifies which DLL is required
+ * at runtime
+ * @return The DEF file artifact.
+ */
+ public static Artifact createDefFileActions(
+ RuleContext ruleContext,
+ Artifact defParser,
+ ImmutableList<Artifact> objectFiles,
+ String dllName) {
+ Artifact defFile = ruleContext.getBinArtifact(ruleContext.getLabel().getName() + ".def");
+ CustomCommandLine.Builder argv = new CustomCommandLine.Builder();
+ for (Artifact objectFile : objectFiles) {
+ argv.addDynamicString(objectFile.getExecPathString());
+ }
+
+ Artifact paramFile =
+ ruleContext.getDerivedArtifact(
+ ParameterFile.derivePath(defFile.getRootRelativePath()), defFile.getRoot());
+
+ ruleContext.registerAction(
+ new ParameterFileWriteAction(
+ ruleContext.getActionOwner(),
+ paramFile,
+ argv.build(),
+ ParameterFile.ParameterFileType.SHELL_QUOTED,
+ UTF_8));
+
+ ruleContext.registerAction(
+ new SpawnAction.Builder()
+ .addInput(paramFile)
+ .addInputs(objectFiles)
+ .addOutput(defFile)
+ .setExecutable(defParser)
+ .useDefaultShellEnvironment()
+ .addCommandLine(
+ CustomCommandLine.builder()
+ .addExecPath(defFile)
+ .addDynamicString(dllName)
+ .addPrefixedExecPath("@", paramFile)
+ .build())
+ .setMnemonic("DefParser")
+ .build(ruleContext));
+ return defFile;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java
index 4978902723..2038daba89 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java
@@ -14,8 +14,6 @@
package com.google.devtools.build.lib.rules.cpp;
-import static java.nio.charset.StandardCharsets.UTF_8;
-
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
@@ -25,13 +23,9 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.FailAction;
-import com.google.devtools.build.lib.actions.ParameterFile;
import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
-import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
-import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
-import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.PerLabelOptions;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
@@ -60,7 +54,6 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.annotation.Nullable;
/**
* Representation of a C/C++ compilation. Its purpose is to share the code that creates compilation
@@ -686,60 +679,6 @@ public final class CppModel {
}
/**
- * Create actions for parsing object files to generate a DEF file, should on be used on Windows.
- *
- * <p>The method only creates the actions when WINDOWS_EXPORT_ALL_SYMBOLS feature is enabled and
- * NO_WINDOWS_EXPORT_ALL_SYMBOLS feature is not enabled.
- *
- * @param objectFiles A list of object files to parse
- * @param dllName The DLL name to be written into the DEF file, it specifies which DLL is required
- * at runtime
- * @return The DEF file artifact, null if actions are not created.
- */
- @Nullable
- public Artifact createDefFileActions(ImmutableList<Artifact> objectFiles, String dllName) {
- if (!featureConfiguration.isEnabled(CppRuleClasses.WINDOWS_EXPORT_ALL_SYMBOLS)
- || featureConfiguration.isEnabled(CppRuleClasses.NO_WINDOWS_EXPORT_ALL_SYMBOLS)) {
- return null;
- }
- Artifact defFile = ruleContext.getBinArtifact(ruleContext.getLabel().getName() + ".def");
- CustomCommandLine.Builder argv = new CustomCommandLine.Builder();
- for (Artifact objectFile : objectFiles) {
- argv.addDynamicString(objectFile.getExecPathString());
- }
-
- Artifact paramFile =
- ruleContext.getDerivedArtifact(
- ParameterFile.derivePath(defFile.getRootRelativePath()), defFile.getRoot());
-
- ruleContext.registerAction(
- new ParameterFileWriteAction(
- ruleContext.getActionOwner(),
- paramFile,
- argv.build(),
- ParameterFile.ParameterFileType.SHELL_QUOTED,
- UTF_8));
-
- Artifact defParser = ccToolchain.getDefParserTool();
- ruleContext.registerAction(
- new SpawnAction.Builder()
- .addInput(paramFile)
- .addInputs(objectFiles)
- .addOutput(defFile)
- .setExecutable(defParser)
- .useDefaultShellEnvironment()
- .addCommandLine(
- CustomCommandLine.builder()
- .addExecPath(defFile)
- .addDynamicString(dllName)
- .addPrefixedExecPath("@", paramFile)
- .build())
- .setMnemonic("DefParser")
- .build(ruleContext));
- return defFile;
- }
-
- /**
* Constructs the C++ compiler actions. It generally creates one action for every specified source
* file. It takes into account LIPO, fake-ness, coverage, and PIC, in addition to using the
* settings specified on the current object. This method should only be called once.
@@ -1504,11 +1443,13 @@ public final class CppModel {
ccToolchain.getDynamicRuntimeLinkInputs())
.addVariablesExtensions(variablesExtensions);
- Artifact defFile =
- createDefFileActions(
- ccOutputs.getObjectFiles(false),
- SolibSymlinkAction.getDynamicLibrarySoname(soImpl.getRootRelativePath(), true));
- if (defFile != null) {
+ if (CppHelper.shouldUseDefFile(featureConfiguration)) {
+ Artifact defFile =
+ CppHelper.createDefFileActions(
+ ruleContext,
+ ccToolchain.getDefParserTool(),
+ ccOutputs.getObjectFiles(false),
+ SolibSymlinkAction.getDynamicLibrarySoname(soImpl.getRootRelativePath(), true));
dynamicLinkActionBuilder.setDefFile(defFile);
}