aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/cpp
diff options
context:
space:
mode:
authorGravatar Cal Peyser <cpeyser@google.com>2016-11-15 20:21:38 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2016-11-16 15:56:43 +0000
commit5bb4ff6886450217f00765c7ed19055ff08e9568 (patch)
tree0e6c8a00d58e6f26283a9fb116b450c6f3a7f7f1 /src/main/java/com/google/devtools/build/lib/rules/cpp
parent60751d02cf9e2d78ab5d4bf9fee0006b8adcf453 (diff)
Implement basic objc executable linking in the CROSSTOOL.
The following link features are *not* implemented yet: 1) Objc++ linking semantics 2) Dead stripping 3) --should_prioritize_static_libs 4) DSYM generation 5) Coverage support 6) Swift interop 7) Linkmap -- MOS_MIGRATED_REVID=139232434
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/cpp')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java41
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/Link.java58
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java1
5 files changed, 92 insertions, 19 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
index ca464d2a1b..bf9e7c5367 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
@@ -1150,7 +1150,7 @@ public class CcToolchainFeatures implements Serializable {
* Add a variable that expands a flag group containing a reference to {@code name} for each
* entry in {@code values}.
*/
- public Builder addSequenceVariable(String name, Collection<String> values) {
+ public Builder addSequenceVariable(String name, Iterable<String> values) {
StringSequence.Builder sequenceBuilder = new StringSequence.Builder();
for (String value : values) {
sequenceBuilder.addValue(value);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java
index 44004745a0..04dc86895e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java
@@ -95,6 +95,7 @@ public final class CppLinkAction extends AbstractAction
private static final String LINK_GUID = "58ec78bd-1176-4e36-8143-439f656b181d";
private static final String FAKE_LINK_GUID = "da36f819-5a15-43a9-8a45-e01b60e10c8b";
+ @Nullable private final String mnemonic;
private final CppConfiguration cppConfiguration;
private final LibraryToLink outputLibrary;
private final Artifact linkOutput;
@@ -138,6 +139,7 @@ public final class CppLinkAction extends AbstractAction
*/
CppLinkAction(
ActionOwner owner,
+ String mnemonic,
Iterable<Artifact> inputs,
ImmutableList<Artifact> outputs,
CppConfiguration cppConfiguration,
@@ -151,6 +153,11 @@ public final class CppLinkAction extends AbstractAction
Map<String, String> toolchainEnv,
ImmutableSet<String> executionRequirements) {
super(owner, inputs, outputs);
+ if (mnemonic == null) {
+ this.mnemonic = (isLTOIndexing) ? "CppLTOIndexing" : "CppLink";
+ } else {
+ this.mnemonic = mnemonic;
+ }
this.mandatoryInputs = inputs;
this.cppConfiguration = cppConfiguration;
this.outputLibrary = outputLibrary;
@@ -457,7 +464,7 @@ public final class CppLinkAction extends AbstractAction
@Override
public String getMnemonic() {
- return (isLTOIndexing) ? "CppLTOIndexing" : "CppLink";
+ return mnemonic;
}
@Override
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 f2690c6062..9fe8673389 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
@@ -124,6 +124,7 @@ public class CppLinkActionBuilder {
@Nullable private final RuleContext ruleContext;
private final AnalysisEnvironment analysisEnvironment;
private final Artifact output;
+ @Nullable private String mnemonic;
// can be null for CppLinkAction.createTestBuilder()
@Nullable private final CcToolchainProvider toolchain;
@@ -162,7 +163,7 @@ public class CppLinkActionBuilder {
private Iterable<LTOBackendArtifacts> allLTOArtifacts = null;
private final List<VariablesExtension> variablesExtensions = new ArrayList<>();
- private final List<Artifact> linkActionInputs = new ArrayList<>();
+ private final NestedSetBuilder<Artifact> linkActionInputs = NestedSetBuilder.stableOrder();
/**
* Creates a builder that builds {@link CppLinkAction} instances.
@@ -442,8 +443,11 @@ public class CppLinkActionBuilder {
/** Builds the Action as configured and returns it. */
public CppLinkAction build() throws InterruptedException {
- Preconditions.checkState(
- (libraryIdentifier == null) == (linkType == LinkTargetType.EXECUTABLE));
+ // Executable links do not have library identifiers.
+ boolean hasIdentifier = (libraryIdentifier != null);
+ boolean isExecutable = linkType.isExecutable();
+ Preconditions.checkState(hasIdentifier != isExecutable);
+
if (interfaceOutput != null && (fake || linkType != LinkTargetType.DYNAMIC_LIBRARY)) {
throw new RuntimeException(
"Interface output can only be used " + "with non-fake DYNAMIC_LIBRARY targets");
@@ -485,7 +489,7 @@ public class CppLinkActionBuilder {
}
}
- final LibraryToLink outputLibrary = linkType == LinkTargetType.EXECUTABLE
+ final LibraryToLink outputLibrary = linkType.isExecutable()
? null
: LinkerInputs.newInputLibrary(output,
linkType.getLinkerOutput(),
@@ -651,7 +655,7 @@ public class CppLinkActionBuilder {
NestedSetBuilder<Artifact> dependencyInputsBuilder = NestedSetBuilder.stableOrder();
dependencyInputsBuilder.addTransitive(crosstoolInputs);
dependencyInputsBuilder.add(toolchain.getLinkDynamicLibraryTool());
- dependencyInputsBuilder.addAll(linkActionInputs);
+ dependencyInputsBuilder.addTransitive(linkActionInputs.build());
if (runtimeMiddleman != null) {
dependencyInputsBuilder.add(runtimeMiddleman);
}
@@ -737,6 +741,7 @@ public class CppLinkActionBuilder {
return new CppLinkAction(
getOwner(),
+ mnemonic,
inputsBuilder.deduplicate().build(),
actionOutputs,
cppConfiguration,
@@ -840,6 +845,12 @@ public class CppLinkActionBuilder {
protected ActionOwner getOwner() {
return ruleContext.getActionOwner();
}
+
+ /** Sets the mnemonic for the link action. */
+ public CppLinkActionBuilder setMnemonic(String mnemonic) {
+ this.mnemonic = mnemonic;
+ return this;
+ }
/** Set the crosstool inputs required for the action. */
public CppLinkActionBuilder setCrosstoolInputs(NestedSet<Artifact> inputs) {
@@ -1143,12 +1154,28 @@ public class CppLinkActionBuilder {
}
/**
- * Sets extra input artifacts to the link action.
+ * Adds an extra input artifact to the link action.
+ */
+ public CppLinkActionBuilder addActionInput(Artifact input) {
+ this.linkActionInputs.add(input);
+ return this;
+ }
+
+ /**
+ * Adds extra input artifacts to the link action.
*/
- public CppLinkActionBuilder addActionInputs(Collection<Artifact> inputs) {
+ public CppLinkActionBuilder addActionInputs(Iterable<Artifact> inputs) {
this.linkActionInputs.addAll(inputs);
return this;
}
+
+ /**
+ * Adds extra input artifacts to the link actions.
+ */
+ public CppLinkActionBuilder addTransitiveActionInputs(NestedSet<Artifact> inputs) {
+ this.linkActionInputs.addTransitive(inputs);
+ return this;
+ }
private static class LinkArgCollector {
String rpathRoot;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/Link.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/Link.java
index ec51c8413f..74f33ab913 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/Link.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/Link.java
@@ -103,6 +103,14 @@ public abstract class Link {
STATIC,
DYNAMIC
}
+
+ /**
+ * Whether a particular link target is executable.
+ */
+ public enum Executable {
+ EXECUTABLE,
+ NOT_EXECUTABLE
+ }
/**
* Types of ELF files that can be created by the linker (.a, .so, .lo,
@@ -115,7 +123,8 @@ public abstract class Link {
Staticness.STATIC,
"c++-link-static-library",
Picness.NOPIC,
- ArtifactCategory.STATIC_LIBRARY),
+ ArtifactCategory.STATIC_LIBRARY,
+ Executable.NOT_EXECUTABLE),
/** An objc static archive. */
OBJC_ARCHIVE(
@@ -123,19 +132,35 @@ public abstract class Link {
Staticness.STATIC,
"objc-archive",
Picness.NOPIC,
- ArtifactCategory.STATIC_LIBRARY),
+ ArtifactCategory.STATIC_LIBRARY,
+ Executable.NOT_EXECUTABLE),
/** An objc fully linked static archive. */
OBJC_FULLY_LINKED_ARCHIVE(
- ".a", Staticness.STATIC, "objc-fully-link", Picness.NOPIC, ArtifactCategory.STATIC_LIBRARY),
+ ".a",
+ Staticness.STATIC,
+ "objc-fully-link",
+ Picness.NOPIC,
+ ArtifactCategory.STATIC_LIBRARY,
+ Executable.NOT_EXECUTABLE),
+ /** An objc executable. */
+ OBJC_EXECUTABLE(
+ "",
+ Staticness.STATIC,
+ "objc-executable",
+ Picness.NOPIC,
+ ArtifactCategory.EXECUTABLE,
+ Executable.EXECUTABLE),
+
/** A static archive with .pic.o object files (compiled with -fPIC). */
PIC_STATIC_LIBRARY(
".pic.a",
Staticness.STATIC,
"c++-link-pic-static-library",
Picness.PIC,
- ArtifactCategory.STATIC_LIBRARY),
+ ArtifactCategory.STATIC_LIBRARY,
+ Executable.NOT_EXECUTABLE),
/** An interface dynamic library. */
INTERFACE_DYNAMIC_LIBRARY(
@@ -143,7 +168,8 @@ public abstract class Link {
Staticness.DYNAMIC,
"c++-link-interface-dynamic-library",
Picness.NOPIC, // Actually PIC but it's not indicated in the file name
- ArtifactCategory.INTERFACE_LIBRARY),
+ ArtifactCategory.INTERFACE_LIBRARY,
+ Executable.NOT_EXECUTABLE),
/** A dynamic library. */
DYNAMIC_LIBRARY(
@@ -151,7 +177,8 @@ public abstract class Link {
Staticness.DYNAMIC,
"c++-link-dynamic-library",
Picness.NOPIC, // Actually PIC but it's not indicated in the file name
- ArtifactCategory.DYNAMIC_LIBRARY),
+ ArtifactCategory.DYNAMIC_LIBRARY,
+ Executable.NOT_EXECUTABLE),
/** A static archive without removal of unused object files. */
ALWAYS_LINK_STATIC_LIBRARY(
@@ -159,7 +186,8 @@ public abstract class Link {
Staticness.STATIC,
"c++-link-alwayslink-static-library",
Picness.NOPIC,
- ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY),
+ ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY,
+ Executable.NOT_EXECUTABLE),
/** A PIC static archive without removal of unused object files. */
ALWAYS_LINK_PIC_STATIC_LIBRARY(
@@ -167,7 +195,8 @@ public abstract class Link {
Staticness.STATIC,
"c++-link-alwayslink-pic-static-library",
Picness.PIC,
- ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY),
+ ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY,
+ Executable.NOT_EXECUTABLE),
/** An executable binary. */
EXECUTABLE(
@@ -175,25 +204,29 @@ public abstract class Link {
Staticness.DYNAMIC,
"c++-link-executable",
Picness.NOPIC, // Picness is not indicate in the file name
- ArtifactCategory.EXECUTABLE);
+ ArtifactCategory.EXECUTABLE,
+ Executable.EXECUTABLE);
private final String extension;
private final Staticness staticness;
private final String actionName;
private final ArtifactCategory linkerOutput;
private final Picness picness;
+ private final Executable executable;
LinkTargetType(
String extension,
Staticness staticness,
String actionName,
Picness picness,
- ArtifactCategory linkerOutput) {
+ ArtifactCategory linkerOutput,
+ Executable executable) {
this.extension = extension;
this.staticness = staticness;
this.actionName = actionName;
this.linkerOutput = linkerOutput;
this.picness = picness;
+ this.executable = executable;
}
/**
@@ -223,6 +256,11 @@ public abstract class Link {
public String getActionName() {
return actionName;
}
+
+ /** Returns true iff this link type is executable */
+ public boolean isExecutable() {
+ return (executable == Executable.EXECUTABLE);
+ }
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java
index 27e3e4db99..6a95202423 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java
@@ -408,6 +408,7 @@ public final class LinkCommandLine extends CommandLine {
// TODO(b/30109612): make this pattern the case for all link variants.
case OBJC_ARCHIVE:
case OBJC_FULLY_LINKED_ARCHIVE:
+ case OBJC_EXECUTABLE:
argv.add(toolPath);
argv.addAll(featureConfiguration.getCommandLine(actionName, variables));
break;