diff options
author | 2016-11-15 20:21:38 +0000 | |
---|---|---|
committer | 2016-11-16 15:56:43 +0000 | |
commit | 5bb4ff6886450217f00765c7ed19055ff08e9568 (patch) | |
tree | 0e6c8a00d58e6f26283a9fb116b450c6f3a7f7f1 /src/main/java/com/google/devtools/build/lib/rules/objc/ObjcVariablesExtension.java | |
parent | 60751d02cf9e2d78ab5d4bf9fee0006b8adcf453 (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.java | 189 |
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); + } + } } |