aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcVariablesExtension.java
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/objc/ObjcVariablesExtension.java
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/objc/ObjcVariablesExtension.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcVariablesExtension.java189
1 files changed, 184 insertions, 5 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcVariablesExtension.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcVariablesExtension.java
index e14be86eba..851af8d32e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcVariablesExtension.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcVariablesExtension.java
@@ -15,17 +15,22 @@
package com.google.devtools.build.lib.rules.objc;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LINKOPT;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.Platform;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.StringSequence;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.VariablesExtension;
+import java.util.Set;
/** Build variable extensions for templating a toolchain for objc builds. */
class ObjcVariablesExtension implements VariablesExtension {
@@ -43,22 +48,41 @@ class ObjcVariablesExtension implements VariablesExtension {
static final String CC_LIBRARY_EXEC_PATHS_VARIABLE_NAME = "cc_library_exec_paths";
static final String IMPORTED_LIBRARY_EXEC_PATHS_VARIABLE_NAME = "imported_library_exec_paths";
+ // executable linking variables
+ static final String FRAMEWORK_NAMES_VARIABLE_NAME = "framework_names";
+ static final String WEAK_FRAMEWORK_NAMES_VARIABLE_NAME = "weak_framework_names";
+ static final String LIBRARY_NAMES_VARIABLE_NAME = "library_names";
+ static final String FILELIST_VARIABLE_NAME = "filelist";
+ static final String LINKED_BINARY_VARIABLE_NAME = "linked_binary";
+ static final String FORCE_LOAD_EXEC_PATHS_VARIABLE_NAME = "force_load_exec_paths";
+ static final String DEP_LINKOPTS_VARIABLE_NAME = "dep_linkopts";
+ static final String ATTR_LINKOPTS_VARIABLE_NAME = "attr_linkopts";
+
private final RuleContext ruleContext;
private final ObjcProvider objcProvider;
private final CompilationArtifacts compilationArtifacts;
private final Artifact fullyLinkArchive;
private final IntermediateArtifacts intermediateArtifacts;
-
private final BuildConfiguration buildConfiguration;
private final AppleConfiguration appleConfiguration;
+ private final Set<String> frameworkNames;
+ private final ImmutableList<String> libraryNames;
+ private final ImmutableSet<Artifact> forceLoadArtifacts;
+ private final NestedSet<String> attributeLinkopts;
+ private final ImmutableSet<VariableCategory> activeVariableCategories;
- public ObjcVariablesExtension(
+ private ObjcVariablesExtension(
RuleContext ruleContext,
ObjcProvider objcProvider,
CompilationArtifacts compilationArtifacts,
Artifact fullyLinkArchive,
IntermediateArtifacts intermediateArtifacts,
- BuildConfiguration buildConfiguration) {
+ BuildConfiguration buildConfiguration,
+ Set<String> frameworkNames,
+ ImmutableList<String> libraryNames,
+ ImmutableSet<Artifact> forceLoadArtifacts,
+ NestedSet<String> attributeLinkopts,
+ ImmutableSet<VariableCategory> activeVariableCategories) {
this.ruleContext = ruleContext;
this.objcProvider = objcProvider;
this.compilationArtifacts = compilationArtifacts;
@@ -66,6 +90,16 @@ class ObjcVariablesExtension implements VariablesExtension {
this.intermediateArtifacts = intermediateArtifacts;
this.buildConfiguration = buildConfiguration;
this.appleConfiguration = buildConfiguration.getFragment(AppleConfiguration.class);
+ this.frameworkNames = frameworkNames;
+ this.libraryNames = libraryNames;
+ this.forceLoadArtifacts = forceLoadArtifacts;
+ this.attributeLinkopts = attributeLinkopts;
+ this.activeVariableCategories = activeVariableCategories;
+ }
+
+ /** Type of build variable that can optionally exported by this extension. */
+ public enum VariableCategory {
+ ARCHIVE_VARIABLES, FULLY_LINK_VARIABLES, EXECUTABLE_LINKING_VARIABLES;
}
@Override
@@ -74,10 +108,15 @@ class ObjcVariablesExtension implements VariablesExtension {
addFrameworkVariables(builder);
addArchVariables(builder);
addModuleMapVariables(builder);
- if (compilationArtifacts.getArchive().isPresent()) {
+ if (activeVariableCategories.contains(VariableCategory.ARCHIVE_VARIABLES)) {
addArchiveVariables(builder);
}
- addFullyLinkArchiveVariables(builder);
+ if (activeVariableCategories.contains(VariableCategory.FULLY_LINK_VARIABLES)) {
+ addFullyLinkArchiveVariables(builder);
+ }
+ if (activeVariableCategories.contains(VariableCategory.EXECUTABLE_LINKING_VARIABLES)) {
+ addExecutableLinkVariables(builder);
+ }
}
private void addPchVariables(CcToolchainFeatures.Variables.Builder builder) {
@@ -138,4 +177,144 @@ class ObjcVariablesExtension implements VariablesExtension {
IMPORTED_LIBRARY_EXEC_PATHS_VARIABLE_NAME,
ImmutableList.copyOf(Artifact.toExecPaths(objcProvider.get(IMPORTED_LIBRARY))));
}
+
+ private void addExecutableLinkVariables(CcToolchainFeatures.Variables.Builder builder) {
+ builder.addSequenceVariable(FRAMEWORK_NAMES_VARIABLE_NAME, frameworkNames);
+ builder.addSequenceVariable(
+ WEAK_FRAMEWORK_NAMES_VARIABLE_NAME,
+ SdkFramework.names(objcProvider.get(ObjcProvider.WEAK_SDK_FRAMEWORK)));
+ builder.addSequenceVariable(LIBRARY_NAMES_VARIABLE_NAME, libraryNames);
+ builder.addVariable(
+ FILELIST_VARIABLE_NAME, intermediateArtifacts.linkerObjList().getExecPathString());
+ builder.addVariable(
+ LINKED_BINARY_VARIABLE_NAME,
+ ruleContext.getFragment(ObjcConfiguration.class).shouldStripBinary()
+ ? intermediateArtifacts.unstrippedSingleArchitectureBinary().getExecPathString()
+ : intermediateArtifacts.strippedSingleArchitectureBinary().getExecPathString());
+
+ builder.addSequenceVariable(
+ FORCE_LOAD_EXEC_PATHS_VARIABLE_NAME,
+ Artifact.toExecPaths(forceLoadArtifacts));
+ builder.addSequenceVariable(DEP_LINKOPTS_VARIABLE_NAME, objcProvider.get(LINKOPT));
+ builder.addSequenceVariable(ATTR_LINKOPTS_VARIABLE_NAME, attributeLinkopts);
+ }
+
+ /** A Builder for {@link ObjcVariablesExtension}. */
+ static class Builder {
+ private RuleContext ruleContext;
+ private ObjcProvider objcProvider;
+ private CompilationArtifacts compilationArtifacts;
+ private Artifact fullyLinkArchive;
+ private IntermediateArtifacts intermediateArtifacts;
+ private BuildConfiguration buildConfiguration;
+ private Set<String> frameworkNames;
+ private ImmutableSet<Artifact> forceLoadArtifacts;
+ private ImmutableList<String> libraryNames;
+ private NestedSet<String> attributeLinkopts;
+
+ private final ImmutableSet.Builder<VariableCategory> activeVariableCategoriesBuilder =
+ ImmutableSet.builder();
+
+ /** Sets the {@link RuleContext} for this extension. */
+ public Builder setRuleContext(RuleContext ruleContext) {
+ this.ruleContext = Preconditions.checkNotNull(ruleContext);
+ return this;
+ }
+
+ /** Sets the {@link ObjcProvider} for this extension. */
+ public Builder setObjcProvider(ObjcProvider objcProvider) {
+ this.objcProvider = Preconditions.checkNotNull(objcProvider);
+ return this;
+ }
+
+ /** Sets the {@link CompilationArtifacts} for this extension. */
+ public Builder setCompilationArtifacts(CompilationArtifacts compilationArtifacts) {
+ this.compilationArtifacts = Preconditions.checkNotNull(compilationArtifacts);
+ return this;
+ }
+
+ /** Sets the output of the fully link action. */
+ public Builder setFullyLinkArchive(Artifact fullyLinkArchive) {
+ this.fullyLinkArchive = Preconditions.checkNotNull(fullyLinkArchive);
+ return this;
+ }
+
+ /** Sets the {@link IntermediateArtifacts} for this extension. */
+ public Builder setIntermediateArtifacts(IntermediateArtifacts intermediateArtifacts) {
+ this.intermediateArtifacts = Preconditions.checkNotNull(intermediateArtifacts);
+ return this;
+ }
+
+ /** Sets the configuration for this extension. */
+ public Builder setConfiguration(BuildConfiguration buildConfiguration) {
+ this.buildConfiguration = Preconditions.checkNotNull(buildConfiguration);
+ return this;
+ }
+
+ /** Sets the framework names to be passed to the linker using {@code -framework}. */
+ public Builder setFrameworkNames(Set<String> frameworkNames) {
+ this.frameworkNames = Preconditions.checkNotNull(frameworkNames);
+ return this;
+ }
+
+ /** Sets binary input files to be passed to the linker with "-l" flags. */
+ public Builder setLibraryNames(ImmutableList<String> libraryNames) {
+ this.libraryNames = Preconditions.checkNotNull(libraryNames);
+ return this;
+ }
+
+ /** Sets artifacts to be passed to the linker with {@code -force_load}. */
+ public Builder setForceLoadArtifacts(ImmutableSet<Artifact> forceLoadArtifacts) {
+ this.forceLoadArtifacts = Preconditions.checkNotNull(forceLoadArtifacts);
+ return this;
+ }
+
+ /** Sets linkopts arising from rule attributes. */
+ public Builder setAttributeLinkopts(NestedSet<String> attributeLinkopts) {
+ this.attributeLinkopts = Preconditions.checkNotNull(attributeLinkopts);
+ return this;
+ }
+
+ /** Sets the given {@link VariableCategory} as active for this extension. */
+ public Builder addVariableCategory(VariableCategory variableCategory) {
+ this.activeVariableCategoriesBuilder.add(Preconditions.checkNotNull(variableCategory));
+ return this;
+ }
+
+ public ObjcVariablesExtension build() {
+
+ ImmutableSet<VariableCategory> activeVariableCategories =
+ activeVariableCategoriesBuilder.build();
+
+ Preconditions.checkNotNull(ruleContext, "missing RuleContext");
+ Preconditions.checkNotNull(objcProvider, "missing ObjcProvider");
+ Preconditions.checkNotNull(buildConfiguration, "missing BuildConfiguration");
+ Preconditions.checkNotNull(intermediateArtifacts, "missing IntermediateArtifacts");
+ if (activeVariableCategories.contains(VariableCategory.ARCHIVE_VARIABLES)) {
+ Preconditions.checkNotNull(compilationArtifacts, "missing CompilationArtifacts");
+ }
+ if (activeVariableCategories.contains(VariableCategory.FULLY_LINK_VARIABLES)) {
+ Preconditions.checkNotNull(fullyLinkArchive, "missing fully-link archive");
+ }
+ if (activeVariableCategories.contains(VariableCategory.EXECUTABLE_LINKING_VARIABLES)) {
+ Preconditions.checkNotNull(frameworkNames, "missing framework names");
+ Preconditions.checkNotNull(libraryNames, "missing library names");
+ Preconditions.checkNotNull(forceLoadArtifacts, "missing force-load artifacts");
+ Preconditions.checkNotNull(attributeLinkopts, "missing attribute linkopts");
+ }
+
+ return new ObjcVariablesExtension(
+ ruleContext,
+ objcProvider,
+ compilationArtifacts,
+ fullyLinkArchive,
+ intermediateArtifacts,
+ buildConfiguration,
+ frameworkNames,
+ libraryNames,
+ forceLoadArtifacts,
+ attributeLinkopts,
+ activeVariableCategories);
+ }
+ }
}