aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcBinaryRule.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java25
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java24
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/cpp/LinkBuildVariablesTest.java20
5 files changed, 84 insertions, 1 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcBinaryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcBinaryRule.java
index df577ad7d9..74d15d78f7 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcBinaryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcBinaryRule.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.bazel.rules.cpp;
import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
@@ -25,6 +26,7 @@ import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppRuleClasses;
+import com.google.devtools.build.lib.util.FileType;
/** Rule definition for cc_binary rules. */
public final class BazelCcBinaryRule implements RuleDefinition {
@@ -73,6 +75,11 @@ public final class BazelCcBinaryRule implements RuleDefinition {
attr("linkshared", BOOLEAN)
.value(false)
.nonconfigurable("used to *determine* the rule's configuration"))
+ /*<!-- #BLAZE_RULE(cc_binary).ATTRIBUTE(linkopts_file) -->
+ A file with additional options to pass to the linker. The file can be generated during
+ execution.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(attr("linkopts_file", LABEL).allowedFileTypes(FileType.of("linkopts_file")))
.cfg(CppRuleClasses.LIPO_ON_DEMAND)
.build();
}
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 61f6c2a18c..727db97d60 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
@@ -13,6 +13,8 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.cpp;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
@@ -165,6 +167,7 @@ public abstract class CcBinary implements RuleConfiguredTargetFactory {
return CcBinary.init(semantics, context, /*fake =*/ false);
}
+ // TODO(plf): Split up this method.
public static ConfiguredTarget init(CppSemantics semantics, RuleContext ruleContext, boolean fake)
throws InterruptedException, RuleErrorException {
ruleContext.checkSrcsSamePackage(true);
@@ -286,6 +289,12 @@ public abstract class CcBinary implements RuleConfiguredTargetFactory {
linkCompileOutputSeparately,
semantics);
linkActionBuilder.setUseTestOnlyFlags(ruleContext.isTestTarget());
+ if (ruleContext.isAttrDefined("linkopts_file", LABEL)) {
+ Artifact linkoptsFile = ruleContext.getPrerequisiteArtifact("linkopts_file", Mode.DONT_CHECK);
+ if (linkoptsFile != null) {
+ linkActionBuilder.setLinkoptsParamFile(linkoptsFile);
+ }
+ }
if (linkStaticness == LinkStaticness.DYNAMIC) {
linkActionBuilder.setRuntimeInputs(
ArtifactCategory.DYNAMIC_LIBRARY,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
index a12e21ddad..29e78c3d9d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
@@ -439,6 +439,7 @@ public class CppActionConfigs {
" implies: 'libraries_to_link'",
" implies: 'force_pic_flags'",
" implies: 'legacy_link_flags'",
+ " implies: 'linkopts_file'",
" implies: 'linker_param_file'",
" implies: 'fission_support'",
" implies: 'sysroot'",
@@ -462,6 +463,7 @@ public class CppActionConfigs {
" implies: 'library_search_directories'",
" implies: 'libraries_to_link'",
" implies: 'legacy_link_flags'",
+ " implies: 'linkopts_file'",
" implies: 'linker_param_file'",
" implies: 'fission_support'",
" implies: 'sysroot'",
@@ -1057,6 +1059,29 @@ public class CppActionConfigs {
" }",
"}"),
ifTrue(
+ !existingFeatureNames.contains("linkopts_file"),
+ "feature {",
+ " name: 'linkopts_file'",
+ " flag_set {",
+ " expand_if_all_available: 'linkopts_file'",
+ " action: 'c++-link-executable'",
+ " action: 'c++-link-dynamic-library'",
+ " flag_group {",
+ " flag: '-Wl,@%{linkopts_file}'",
+ " }",
+ " }",
+ " flag_set {",
+ " expand_if_all_available: 'linkopts_file'",
+ " action: 'c++-link-static-library'",
+ " action: 'c++-link-alwayslink-static-library'",
+ " action: 'c++-link-pic-static-library'",
+ " action: 'c++-link-alwayslink-pic-static-library'",
+ " flag_group {",
+ " flag: '@%{linkopts_file}'",
+ " }",
+ " }",
+ "}"),
+ ifTrue(
!existingFeatureNames.contains("linker_param_file"),
"feature {",
" name: 'linker_param_file'",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java
index 200bd3a7ae..e0cd9a44d9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java
@@ -111,6 +111,9 @@ public class CppLinkActionBuilder {
*/
public static final String LINKER_PARAM_FILE_VARIABLE = "linker_param_file";
+ /** A build variable for linker flags read from a file provided by the user. */
+ public static final String LINK_OPTS_FILE_VARIABLE = "linkopts_file";
+
/** A build variable for the execpath of the output of the linker. */
public static final String OUTPUT_EXECPATH_VARIABLE = "output_execpath";
@@ -195,6 +198,7 @@ public class CppLinkActionBuilder {
private final ImmutableSet.Builder<Linkstamp> linkstampsBuilder = ImmutableSet.builder();
private ImmutableList<String> additionalLinkstampDefines = ImmutableList.of();
private final List<String> linkopts = new ArrayList<>();
+ private Artifact linkoptsFile;
private LinkTargetType linkType = LinkTargetType.STATIC_LIBRARY;
private LinkStaticness linkStaticness = LinkStaticness.FULLY_STATIC;
private String libraryIdentifier = null;
@@ -918,6 +922,7 @@ public class CppLinkActionBuilder {
runtimeLinkerInputs,
/* output= */ null,
paramFile,
+ linkoptsFile,
thinltoParamFile,
thinltoMergedObjectFile,
ltoOutputRootPrefix,
@@ -932,6 +937,7 @@ public class CppLinkActionBuilder {
runtimeLinkerInputs,
output,
paramFile,
+ linkoptsFile,
thinltoParamFile,
thinltoMergedObjectFile,
/* ltoOutputRootPrefix= */ PathFragment.EMPTY_FRAGMENT,
@@ -1273,7 +1279,7 @@ public class CppLinkActionBuilder {
for (VariablesExtension variablesExtension : variablesExtensions) {
addVariablesExtension(variablesExtension);
}
- return this;
+ return this;
}
/**
@@ -1474,6 +1480,15 @@ public class CppLinkActionBuilder {
return this;
}
+ /** Will pass a file with additional options to the linker. */
+ public CppLinkActionBuilder setLinkoptsParamFile(Artifact linkoptsFile) {
+ Preconditions.checkState(this.linkoptsFile == null);
+ Preconditions.checkNotNull(linkoptsFile);
+ this.linkoptsFile = linkoptsFile;
+ addActionInput(linkoptsFile);
+ return this;
+ }
+
/** Sets whether this link action will be used for a cc_fake_binary; false by default. */
public CppLinkActionBuilder setFake(boolean fake) {
this.fake = fake;
@@ -1593,6 +1608,7 @@ public class CppLinkActionBuilder {
private final Artifact interfaceLibraryBuilder;
private final Artifact interfaceLibraryOutput;
private final Artifact paramFile;
+ private final Artifact linkoptsFile;
private final Artifact thinltoParamFile;
private final Artifact thinltoMergedObjectFile;
private final PathFragment ltoOutputRootPrefix;
@@ -1607,6 +1623,7 @@ public class CppLinkActionBuilder {
ImmutableList<LinkerInput> runtimeLinkerInputs,
Artifact output,
Artifact paramFile,
+ Artifact linkoptsFile,
Artifact thinltoParamFile,
Artifact thinltoMergedObjectFile,
PathFragment ltoOutputRootPrefix,
@@ -1621,6 +1638,7 @@ public class CppLinkActionBuilder {
this.interfaceLibraryBuilder = interfaceLibraryBuilder;
this.interfaceLibraryOutput = interfaceLibraryOutput;
this.paramFile = paramFile;
+ this.linkoptsFile = linkoptsFile;
this.thinltoParamFile = thinltoParamFile;
this.thinltoMergedObjectFile = thinltoMergedObjectFile;
this.ltoOutputRootPrefix = ltoOutputRootPrefix;
@@ -1679,6 +1697,10 @@ public class CppLinkActionBuilder {
buildVariables.addStringVariable(LINKER_PARAM_FILE_VARIABLE, paramFile.getExecPathString());
}
+ if (linkoptsFile != null) {
+ buildVariables.addStringVariable(LINK_OPTS_FILE_VARIABLE, linkoptsFile.getExecPathString());
+ }
+
// output exec path
if (outputArtifact != null) {
buildVariables.addStringVariable(
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/LinkBuildVariablesTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/LinkBuildVariablesTest.java
index aa21798b4c..1f039cf095 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/LinkBuildVariablesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/LinkBuildVariablesTest.java
@@ -105,6 +105,26 @@ public class LinkBuildVariablesTest extends LinkBuildVariablesTestCase {
}
@Test
+ public void testLinkoptsFileIsExported() throws Exception {
+ AnalysisMock.get().ccSupport().setupCrosstool(mockToolsConfig);
+ useConfiguration();
+
+ scratch.file(
+ "x/BUILD",
+ "cc_binary(",
+ " name = 'bin',",
+ " srcs = ['bin.cc'],",
+ " linkopts_file= 'bin.linkopts_file'",
+ ")");
+
+ ConfiguredTarget target = getConfiguredTarget("//x:bin");
+ Variables variables = getLinkBuildVariables(target, Link.LinkTargetType.EXECUTABLE);
+ String variableValue =
+ getVariableValue(variables, CppLinkActionBuilder.LINK_OPTS_FILE_VARIABLE);
+ assertThat(variableValue).matches("x/bin.linkopts_file");
+ }
+
+ @Test
public void testInterfaceLibraryBuildingVariablesWhenGenerationPossible() throws Exception {
// Make sure the interface shared object generation is enabled in the configuration
// (which it is not by default for some windows toolchains)