diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
9 files changed, 149 insertions, 35 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/AppleCcToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/AppleCcToolchain.java index 656c8dfc84..3982e688f5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/AppleCcToolchain.java +++ b/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/AppleCcToolchain.java @@ -14,13 +14,16 @@ package com.google.devtools.build.lib.rules.apple.cpp; import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.AnalysisUtils; import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.collect.nestedset.NestedSet; +import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; import com.google.devtools.build.lib.rules.apple.AppleToolchain; import com.google.devtools.build.lib.rules.apple.DottedVersion; import com.google.devtools.build.lib.rules.apple.Platform; import com.google.devtools.build.lib.rules.cpp.CcToolchain; - import java.util.Map; /** @@ -68,4 +71,13 @@ public class AppleCcToolchain extends CcToolchain { AppleToolchain.platformDeveloperFrameworkDir(appleConfiguration)) .build(); } + + @Override + protected NestedSet<Artifact> fullInputsForLink( + RuleContext ruleContext, NestedSet<Artifact> link) { + return NestedSetBuilder.<Artifact>stableOrder() + .addTransitive(link) + .addTransitive(AnalysisUtils.getMiddlemanFor(ruleContext, ":libc_top")) + .build(); + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/BUILD b/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/BUILD index cbfb7f3906..a0177e65b5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/BUILD +++ b/src/main/java/com/google/devtools/build/lib/rules/apple/cpp/BUILD @@ -10,7 +10,9 @@ java_library( srcs = glob(["*.java"]), deps = [ "//src/main/java/com/google/devtools/build/lib:build-base", + "//src/main/java/com/google/devtools/build/lib:collect", "//src/main/java/com/google/devtools/build/lib:packages-internal", + "//src/main/java/com/google/devtools/build/lib/actions", "//src/main/java/com/google/devtools/build/lib/rules/apple", "//src/main/java/com/google/devtools/build/lib/rules/cpp", "//src/main/protobuf:xcodegen_java_proto", diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java index 1204bf04c7..f56ffdd2a4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java @@ -273,12 +273,19 @@ public class CcToolchain implements RuleConfiguredTargetFactory { .build(); } - private NestedSet<Artifact> fullInputsForLink(RuleContext ruleContext, NestedSet<Artifact> link) { + /** + * Returns the crosstool-derived link action inputs for a given rule. Adds the given set of + * artifacts as extra inputs. + */ + protected NestedSet<Artifact> fullInputsForLink( + RuleContext ruleContext, NestedSet<Artifact> link) { return NestedSetBuilder.<Artifact>stableOrder() .addTransitive(link) .addTransitive(AnalysisUtils.getMiddlemanFor(ruleContext, ":libc_top")) - .add(ruleContext.getAnalysisEnvironment().getEmbeddedToolArtifact( - CppRuleClasses.BUILD_INTERFACE_SO)) + .add( + ruleContext + .getAnalysisEnvironment() + .getEmbeddedToolArtifact(CppRuleClasses.BUILD_INTERFACE_SO)) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java index eb077e95ab..ae9218d134 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java @@ -677,7 +677,8 @@ public class CppConfiguration extends BuildConfiguration.Fragment { } private boolean linkActionsAreConfigured(CToolchain toolchain) { - for (LinkTargetType type : LinkTargetType.values()) { + + for (LinkTargetType type : Link.MANDATORY_LINK_TARGET_TYPES) { boolean typeIsConfigured = false; for (ActionConfig actionConfig : toolchain.getActionConfigList()) { if (actionConfig.getActionName().equals(type.getActionName())) { 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 1a2de41530..af2e1eebb4 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 @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.CommandAction; import com.google.devtools.build.lib.actions.ExecException; import com.google.devtools.build.lib.actions.Executor; import com.google.devtools.build.lib.actions.ResourceSet; @@ -56,11 +57,12 @@ import java.util.List; import java.util.Map; import javax.annotation.Nullable; -/** - * Action that represents a linking step. +/** + * Action that represents a linking step. */ @ThreadCompatible -public final class CppLinkAction extends AbstractAction implements ExecutionInfoSpecifier { +public final class CppLinkAction extends AbstractAction + implements ExecutionInfoSpecifier, CommandAction { /** * An abstraction for creating intermediate and output artifacts for C++ linking. * @@ -255,6 +257,11 @@ public final class CppLinkAction extends AbstractAction implements ExecutionInfo public List<String> getArgv() { return linkCommandLine.arguments(); } + + @Override + public List<String> getArguments() { + return getArgv(); + } /** * Returns the command line specification for this link, included any required linkstamp 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 7b5f693dc5..32e2b7b1a1 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 @@ -35,6 +35,19 @@ import java.util.Iterator; */ public abstract class Link { + /** + * Categories of link action that must be defined with action_configs in any toolchain. + */ + static final Iterable<LinkTargetType> MANDATORY_LINK_TARGET_TYPES = + ImmutableList.of( + LinkTargetType.STATIC_LIBRARY, + LinkTargetType.PIC_STATIC_LIBRARY, + LinkTargetType.ALWAYS_LINK_STATIC_LIBRARY, + LinkTargetType.ALWAYS_LINK_PIC_STATIC_LIBRARY, + LinkTargetType.DYNAMIC_LIBRARY, + LinkTargetType.EXECUTABLE, + LinkTargetType.INTERFACE_DYNAMIC_LIBRARY); + private Link() {} // uninstantiable /** @@ -107,6 +120,14 @@ public abstract class Link { "c++-link-static-library", Picness.NOPIC, ArtifactCategory.STATIC_LIBRARY), + + /** An objc static archive. */ + OBJC_ARCHIVE( + ".a", + Staticness.STATIC, + "objc-archive", + Picness.NOPIC, + ArtifactCategory.STATIC_LIBRARY), /** A static archive with .pic.o object files (compiled with -fPIC). */ PIC_STATIC_LIBRARY( 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 c0f365c92f..a3a01aefb0 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 @@ -399,6 +399,8 @@ public final class LinkCommandLine extends CommandLine { public List<String> getRawLinkArgv() { List<String> argv = new ArrayList<>(); + // TODO(b/30109612): Extract this switch into individual crosstools once action configs are no + // longer hardcoded in CppLinkActionConfigs switch (linkTargetType) { case EXECUTABLE: argv.add(cppConfiguration.getCppExecutable().getPathString()); @@ -438,6 +440,17 @@ public final class LinkCommandLine extends CommandLine { argv.addAll(noWholeArchiveFlags); break; + // Since the objc case is not hardcoded in CppConfiguration, we can use the actual tool. + // TODO(b/30109612): make this pattern the case for all link variants. + case OBJC_ARCHIVE: + argv.add( + featureConfiguration + .getToolForAction(actionName) + .getToolPath(cppConfiguration.getCrosstoolTopPathFragment()) + .getPathString()); + argv.addAll(featureConfiguration.getCommandLine(actionName, variables)); + break; + default: throw new IllegalArgumentException(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java index 97a4b01d6e..3aa555bc48 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java @@ -96,7 +96,6 @@ import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.PathFragment; - import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -980,7 +979,11 @@ public final class CompilationSupport { .build(ruleContext)); } - private void registerObjFilelistAction(Iterable<Artifact> objFiles, Artifact objList) { + /** + * Registers an action that writes given set of object files to the given objList. This objList is + * suitable to signal symbols to archive in a libtool archiving invocation. + */ + CompilationSupport registerObjFilelistAction(Iterable<Artifact> objFiles, Artifact objList) { ImmutableSet<Artifact> dedupedObjFiles = ImmutableSet.copyOf(objFiles); CustomCommandLine.Builder objFilesToLinkParam = new CustomCommandLine.Builder(); ImmutableList.Builder<Artifact> treeObjFiles = new ImmutableList.Builder<>(); @@ -1003,6 +1006,7 @@ public final class CompilationSupport { objFilesToLinkParam.build(), ParameterFile.ParameterFileType.UNQUOTED, ISO_8859_1)); + return this; } /** diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java index 0e2d47649f..de4f34d7aa 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java @@ -26,19 +26,17 @@ import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; 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.CcLibraryHelper; +import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; -import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.Builder; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.ValueSequence; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.VariablesExtension; import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; import com.google.devtools.build.lib.rules.cpp.CppRuleClasses; +import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; import com.google.devtools.build.lib.rules.cpp.PrecompiledFiles; - import java.util.Collection; -/** - * Implementation for experimental_objc_library. - */ +/** Implementation for experimental_objc_library. */ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { private static final String PCH_FILE_VARIABLE_NAME = "pch_file"; @@ -48,57 +46,64 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { private static final String OBJC_MODULE_CACHE_DIR_NAME = "_objc_module_cache"; private static final String OBJC_MODULE_CACHE_KEY = "modules_cache_path"; private static final String OBJC_MODULE_FEATURE_NAME = "use_objc_modules"; + private static final String OBJ_LIST_PATH_VARIABLE_NAME = "obj_list_path"; + private static final String ARCHIVE_PATH_VARIABLE_NAME = "archive_path"; private static final Iterable<String> ACTIVATED_ACTIONS = - ImmutableList.of("objc-compile", "objc++-compile"); + ImmutableList.of("objc-compile", "objc++-compile", "objc-archive"); - /** - * Build variable extensions for templating a toolchain for objc builds. - */ - private static class ObjcVariablesExtension implements VariablesExtension { + /** Build variable extensions for templating a toolchain for objc builds. */ + static class ObjcVariablesExtension implements VariablesExtension { private final RuleContext ruleContext; private final ObjcProvider objcProvider; - + private final CompilationArtifacts compilationArtifacts; + private final AppleConfiguration appleConfiguration; private final ObjcConfiguration objcConfiguration; - public ObjcVariablesExtension(RuleContext ruleContext, ObjcProvider objcProvider) { + public ObjcVariablesExtension( + RuleContext ruleContext, + ObjcProvider objcProvider, + CompilationArtifacts compilationArtifacts) { this.ruleContext = ruleContext; this.objcProvider = objcProvider; - + this.compilationArtifacts = compilationArtifacts; + this.appleConfiguration = ruleContext.getFragment(AppleConfiguration.class); this.objcConfiguration = ruleContext.getFragment(ObjcConfiguration.class); } - + @Override - public void addVariables(Builder builder) { + public void addVariables(CcToolchainFeatures.Variables.Builder builder) { addPchVariables(builder); addFrameworkVariables(builder); addArchVariables(builder); if (ObjcCommon.shouldUseObjcModules(ruleContext)) { addModuleMapVariables(builder); } + if (isStaticArchive(compilationArtifacts)) { + addArchiveVariables(builder); + } } - private void addPchVariables(Builder builder) { - if (ruleContext.getPrerequisiteArtifact("pch", Mode.TARGET) != null) { + private void addPchVariables(CcToolchainFeatures.Variables.Builder builder) { + if (ruleContext.getPrerequisiteArtifact("pch", Mode.TARGET) != null) { builder.addVariable( PCH_FILE_VARIABLE_NAME, ruleContext.getPrerequisiteArtifact("pch", Mode.TARGET).getExecPathString()); } } - - private void addFrameworkVariables(Builder builder) { + + private void addFrameworkVariables(CcToolchainFeatures.Variables.Builder builder) { ValueSequence.Builder frameworkSequence = new ValueSequence.Builder(); AppleConfiguration appleConfig = ruleContext.getFragment(AppleConfiguration.class); - for (String framework : - CompilationSupport.commonFrameworkNames(objcProvider, appleConfig)) { + for (String framework : CompilationSupport.commonFrameworkNames(objcProvider, appleConfig)) { frameworkSequence.addValue(framework); } builder.addSequence(FRAMEWORKS_VARIABLE_NAME, frameworkSequence.build()); } - - private void addModuleMapVariables(Builder builder) { + + private void addModuleMapVariables(CcToolchainFeatures.Variables.Builder builder) { builder.addVariable( MODULES_MAPS_DIR_NAME, ObjcRuleClasses.intermediateArtifacts(ruleContext) @@ -112,7 +117,7 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { ruleContext.getConfiguration().getGenfilesFragment() + "/" + OBJC_MODULE_CACHE_DIR_NAME); } - private void addArchVariables(Builder builder) { + private void addArchVariables(CcToolchainFeatures.Variables.Builder builder) { Platform platform = appleConfiguration.getSingleArchPlatform(); switch (platform.getType()) { case IOS: @@ -128,6 +133,14 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { throw new IllegalArgumentException("Unhandled platform: " + platform); } } + + private void addArchiveVariables(CcToolchainFeatures.Variables.Builder builder) { + builder.addVariable( + OBJ_LIST_PATH_VARIABLE_NAME, + ObjcRuleClasses.intermediateArtifacts(ruleContext).archiveObjList().getExecPathString()); + builder.addVariable( + ARCHIVE_PATH_VARIABLE_NAME, compilationArtifacts.getArchive().get().getExecPathString()); + } } @Override @@ -140,6 +153,9 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { CompilationAttributes compilationAttributes = CompilationAttributes.Builder.fromRuleContext(ruleContext).build(); PrecompiledFiles precompiledFiles = new PrecompiledFiles(ruleContext); + CompilationSupport compilationSupport = new CompilationSupport(ruleContext); + IntermediateArtifacts intermediateArtifacts = + ObjcRuleClasses.intermediateArtifacts(ruleContext); ObjcCommon common = common(ruleContext, compilationAttributes, compilationArtifacts); @@ -162,7 +178,20 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { .addPrecompiledFiles(precompiledFiles) .addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET)) .addVariableExtension( - new ObjcVariablesExtension(ruleContext, common.getObjcProvider())); + new ObjcVariablesExtension( + ruleContext, common.getObjcProvider(), compilationArtifacts)); + + if (isStaticArchive(compilationArtifacts)) { + Artifact objList = intermediateArtifacts.archiveObjList(); + + // TODO(b/30783125): Signal the need for this action in the CROSSTOOL. + compilationSupport.registerObjFilelistAction( + getObjFiles(compilationArtifacts, intermediateArtifacts), objList); + + helper + .setLinkType(LinkTargetType.OBJC_ARCHIVE) + .addLinkActionInput(objList); + } if (ObjcCommon.shouldUseObjcModules(ruleContext)) { helper.setCppModuleMap(ObjcRuleClasses.intermediateArtifacts(ruleContext).moduleMap()); @@ -227,4 +256,22 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { .addDepObjcProviders(ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class)) .build(); } + + private static boolean isStaticArchive(CompilationArtifacts compilationArtifacts) { + return compilationArtifacts.getArchive().isPresent(); + } + + private ImmutableList<Artifact> getObjFiles( + CompilationArtifacts compilationArtifacts, IntermediateArtifacts intermediateArtifacts) { + ImmutableList.Builder<Artifact> result = new ImmutableList.Builder<>(); + for (Artifact sourceFile : compilationArtifacts.getSrcs()) { + Artifact objFile = intermediateArtifacts.objFile(sourceFile); + result.add(objFile); + } + for (Artifact nonArcSourceFile : compilationArtifacts.getNonArcSrcs()) { + Artifact objFile = intermediateArtifacts.objFile(nonArcSourceFile); + result.add(objFile); + } + return result.build(); + } } |