diff options
author | 2016-08-17 19:11:59 +0000 | |
---|---|---|
committer | 2016-08-18 08:31:02 +0000 | |
commit | 6f3e05cb3acaa9a2f15ae3a8e9ab626263d2aff6 (patch) | |
tree | 5592dc3a208d8ce27e0b5775b36ad0d965180aaf /src/main/java/com/google/devtools/build | |
parent | 4e9be54b134165e8df51b749f78a66bd592944a6 (diff) |
Implement the fully link action in the OSX crosstool.
--
MOS_MIGRATED_REVID=130547971
Diffstat (limited to 'src/main/java/com/google/devtools/build')
9 files changed, 270 insertions, 160 deletions
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 15bde7883e..4fcc90c23d 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 @@ -822,11 +822,17 @@ public class CppLinkActionBuilder { return this; } - /** - * Adds variables extensions to template the toolchain for this link action. - */ - public CppLinkActionBuilder addVariablesExtension(List<VariablesExtension> variablesExtensions) { - this.variablesExtensions.addAll(variablesExtensions); + /** Adds a variables extension to template the toolchain for this link action. */ + public CppLinkActionBuilder addVariablesExtension(VariablesExtension variablesExtension) { + this.variablesExtensions.add(variablesExtension); + return this; + } + + /** Adds variables extensions to template the toolchain for this link action. */ + public CppLinkActionBuilder addVariablesExtensions(List<VariablesExtension> variablesExtensions) { + for (VariablesExtension variablesExtension : variablesExtensions) { + addVariablesExtension(variablesExtension); + } return this; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java index 8e0120efe0..a1c9644ef7 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java @@ -872,7 +872,7 @@ public final class CppModel { .setLinkStaticness(LinkStaticness.FULLY_STATIC) .addActionInputs(linkActionInputs) .setLibraryIdentifier(libraryIdentifier) - .addVariablesExtension(variablesExtensions) + .addVariablesExtensions(variablesExtensions) .setFeatureConfiguration(featureConfiguration) .build(); env.registerAction(maybePicAction); @@ -901,7 +901,7 @@ public final class CppModel { .setLinkStaticness(LinkStaticness.FULLY_STATIC) .addActionInputs(linkActionInputs) .setLibraryIdentifier(libraryIdentifier) - .addVariablesExtension(variablesExtensions) + .addVariablesExtensions(variablesExtensions) .setFeatureConfiguration(featureConfiguration) .build(); env.registerAction(picAction); @@ -961,7 +961,7 @@ public final class CppModel { CppHelper.getToolchain(ruleContext).getDynamicRuntimeLinkMiddleman(), CppHelper.getToolchain(ruleContext).getDynamicRuntimeLinkInputs()) .setFeatureConfiguration(featureConfiguration) - .addVariablesExtension(variablesExtensions); + .addVariablesExtensions(variablesExtensions); if (!ccOutputs.getLtoBitcodeFiles().isEmpty() && featureConfiguration.isEnabled(CppRuleClasses.THIN_LTO)) { 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 a6288e5eed..f03f128199 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 @@ -128,6 +128,10 @@ public abstract class Link { "objc-archive", Picness.NOPIC, ArtifactCategory.STATIC_LIBRARY), + + /** An objc fully linked static archive. */ + OBJC_FULLY_LINKED_ARCHIVE( + ".a", Staticness.STATIC, "objc-fully-link", 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 a3a01aefb0..b3a0cc7d09 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 @@ -443,6 +443,7 @@ public final class LinkCommandLine extends CommandLine { // 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: + case OBJC_FULLY_LINKED_ARCHIVE: argv.add( featureConfiguration .getToolForAction(actionName) 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 102b018802..4da2ff3eab 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 @@ -85,7 +85,6 @@ import com.google.devtools.build.lib.rules.apple.Platform; import com.google.devtools.build.lib.rules.apple.Platform.PlatformType; import com.google.devtools.build.lib.rules.cpp.CppModuleMap; import com.google.devtools.build.lib.rules.cpp.CppModuleMapAction; -import com.google.devtools.build.lib.rules.cpp.LinkerInputs; import com.google.devtools.build.lib.rules.objc.XcodeProvider.Builder; import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector; import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec; @@ -1019,8 +1018,8 @@ public final class CompilationSupport { throws InterruptedException { Artifact outputArchive = ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB); - ImmutableList<Artifact> objcLibraries = objcLibraries(objcProvider); - ImmutableList<Artifact> ccLibraries = ccLibraries(objcProvider); + ImmutableList<Artifact> objcLibraries = objcProvider.getObjcLibraries(); + ImmutableList<Artifact> ccLibraries = objcProvider.getCcLibraries(); ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder( appleConfiguration, appleConfiguration.getSingleArchPlatform()) .setMnemonic("ObjcLink") @@ -1214,8 +1213,8 @@ public final class CompilationSupport { ? intermediateArtifacts.unstrippedSingleArchitectureBinary() : intermediateArtifacts.strippedSingleArchitectureBinary(); - ImmutableList<Artifact> objcLibraries = objcLibraries(objcProvider); - ImmutableList<Artifact> ccLibraries = ccLibraries(objcProvider); + ImmutableList<Artifact> objcLibraries = objcProvider.getObjcLibraries(); + ImmutableList<Artifact> ccLibraries = objcProvider.getCcLibraries(); ImmutableList<Artifact> bazelBuiltLibraries = Iterables.isEmpty(prunedJ2ObjcArchives) ? objcLibraries : substituteJ2ObjcPrunedLibraries(objcProvider); CommandLine commandLine = @@ -1274,24 +1273,6 @@ public final class CompilationSupport { } } - private ImmutableList<Artifact> objcLibraries(ObjcProvider objcProvider) { - ImmutableList.Builder<Artifact> objcLibraryBuilder = ImmutableList.builder(); - // JRE libraries must be ordered after all regular objc libraries. - NestedSet<Artifact> jreLibs = objcProvider.get(ObjcProvider.JRE_LIBRARY); - objcLibraryBuilder.addAll(Iterables.filter( - objcProvider.get(LIBRARY), Predicates.not(Predicates.in(jreLibs.toSet())))); - objcLibraryBuilder.addAll(jreLibs); - return objcLibraryBuilder.build(); - } - - private ImmutableList<Artifact> ccLibraries(ObjcProvider objcProvider) { - ImmutableList.Builder<Artifact> ccLibraryBuilder = ImmutableList.builder(); - for (LinkerInputs.LibraryToLink libraryToLink : objcProvider.get(ObjcProvider.CC_LIBRARY)) { - ccLibraryBuilder.add(libraryToLink.getArtifact()); - } - return ccLibraryBuilder.build(); - } - private ImmutableList<Artifact> j2objcPrunedLibraries(ObjcProvider objcProvider) { ImmutableList.Builder<Artifact> j2objcPrunedLibraryBuilder = ImmutableList.builder(); for (Artifact j2objcLibrary : objcProvider.get(ObjcProvider.J2OBJC_LIBRARY)) { @@ -1318,7 +1299,7 @@ public final class CompilationSupport { ImmutableList.Builder<Artifact> libraries = new ImmutableList.Builder<>(); Set<Artifact> unprunedJ2ObjcLibs = objcProvider.get(ObjcProvider.J2OBJC_LIBRARY).toSet(); - for (Artifact library : objcLibraries(objcProvider)) { + for (Artifact library : objcProvider.getObjcLibraries()) { // If we match an unpruned J2ObjC library, add the pruned version of the J2ObjC static library // instead. if (unprunedJ2ObjcLibs.contains(library)) { 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 f02a63e988..5de560630b 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 @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.rules.objc; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DEFINE; +import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY; import static com.google.devtools.build.lib.rules.objc.XcodeProductType.LIBRARY_STATIC; import com.google.common.collect.ImmutableList; @@ -27,125 +28,26 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; 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.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.CppLinkAction; +import com.google.devtools.build.lib.rules.cpp.CppLinkActionBuilder; import com.google.devtools.build.lib.rules.cpp.CppRuleClasses; +import com.google.devtools.build.lib.rules.cpp.Link.LinkStaticness; import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; import com.google.devtools.build.lib.rules.cpp.PrecompiledFiles; import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes; +import com.google.devtools.build.lib.vfs.PathFragment; import java.util.Collection; /** Implementation for experimental_objc_library. */ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { - private static final String PCH_FILE_VARIABLE_NAME = "pch_file"; - private static final String FRAMEWORKS_VARIABLE_NAME = "framework_paths"; - private static final String VERSION_MIN_VARIABLE_NAME = "version_min"; - private static final String MODULES_MAPS_DIR_NAME = "module_maps_dir"; - 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", "objc-archive"); - - /** 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, - 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(CcToolchainFeatures.Variables.Builder builder) { - addPchVariables(builder); - addFrameworkVariables(builder); - addArchVariables(builder); - if (ObjcCommon.shouldUseObjcModules(ruleContext)) { - addModuleMapVariables(builder); - } - if (isStaticArchive(compilationArtifacts)) { - addArchiveVariables(builder); - } - } - - 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(CcToolchainFeatures.Variables.Builder builder) { - ValueSequence.Builder frameworkSequence = new ValueSequence.Builder(); - AppleConfiguration appleConfig = ruleContext.getFragment(AppleConfiguration.class); - for (String framework : CompilationSupport.commonFrameworkNames(objcProvider, appleConfig)) { - frameworkSequence.addValue(framework); - } - builder.addSequence(FRAMEWORKS_VARIABLE_NAME, frameworkSequence.build()); - } - - private void addModuleMapVariables(CcToolchainFeatures.Variables.Builder builder) { - builder.addVariable( - MODULES_MAPS_DIR_NAME, - ObjcRuleClasses.intermediateArtifacts(ruleContext) - .moduleMap() - .getArtifact() - .getExecPath() - .getParentDirectory() - .toString()); - builder.addVariable( - OBJC_MODULE_CACHE_KEY, - ruleContext.getConfiguration().getGenfilesFragment() + "/" + OBJC_MODULE_CACHE_DIR_NAME); - } - - private void addArchVariables(CcToolchainFeatures.Variables.Builder builder) { - Platform platform = appleConfiguration.getSingleArchPlatform(); - switch (platform.getType()) { - case IOS: - builder.addVariable( - VERSION_MIN_VARIABLE_NAME, objcConfiguration.getMinimumOs().toString()); - break; - case WATCHOS: - builder.addVariable( - VERSION_MIN_VARIABLE_NAME, - appleConfiguration.getSdkVersionForPlatform(platform).toString()); - break; - default: // don't handle MACOS and TVOS - 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()); - } - } + ImmutableList.of("objc-compile", "objc++-compile", "objc-archive", "objc-fully-link"); @Override public ConfiguredTarget create(RuleContext ruleContext) @@ -162,6 +64,16 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { ObjcRuleClasses.intermediateArtifacts(ruleContext); ObjcCommon common = common(ruleContext, compilationAttributes, compilationArtifacts); + ObjcVariablesExtension variablesExtension = + new ObjcVariablesExtension( + ruleContext, + common.getObjcProvider(), + compilationArtifacts, + ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB), + intermediateArtifacts, + ruleContext.getConfiguration()); + + FeatureConfiguration featureConfiguration = getFeatureConfiguration(ruleContext); Collection<Artifact> arcSources = Sets.newHashSet(compilationArtifacts.getSrcs()); Collection<Artifact> nonArcSources = Sets.newHashSet(compilationArtifacts.getNonArcSrcs()); @@ -172,7 +84,7 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { new CcLibraryHelper( ruleContext, new ObjcCppSemantics(common.getObjcProvider()), - getFeatureConfiguration(ruleContext), + featureConfiguration, CcLibraryHelper.SourceCategory.CC_AND_OBJC) .addSources(arcSources, ImmutableMap.of("objc_arc", "")) .addSources(nonArcSources, ImmutableMap.of("no_objc_arc", "")) @@ -183,21 +95,13 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { .addPrecompiledFiles(precompiledFiles) .addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET)) .addCopts(compilationSupport.getCompileRuleCopts()) - .addVariableExtension( - new ObjcVariablesExtension( - ruleContext, common.getObjcProvider(), compilationArtifacts)); - - if (isStaticArchive(compilationArtifacts)) { - Artifact objList = intermediateArtifacts.archiveObjList(); + .addVariableExtension(variablesExtension); - // 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 (compilationArtifacts.getArchive().isPresent()) { + registerArchiveAction( + intermediateArtifacts, compilationSupport, compilationArtifacts, helper); } + registerFullyLinkAction(ruleContext, common, variablesExtension, featureConfiguration); if (ObjcCommon.shouldUseObjcModules(ruleContext)) { helper.setCppModuleMap(ObjcRuleClasses.intermediateArtifacts(ruleContext).moduleMap()); @@ -222,6 +126,7 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build()) .addProvider(ObjcProvider.class, common.getObjcProvider()) .addProviders(info.getProviders()) + .addProvider(ObjcProvider.class, common.getObjcProvider()) .addProvider(XcodeProvider.class, xcodeProviderBuilder.build()) .build(); } @@ -254,9 +159,49 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { return toolchain.getFeatures().getFeatureConfiguration(activatedCrosstoolSelectables.build()); } - /** - * Throws errors or warnings for bad attribute state. - */ + private void registerArchiveAction( + IntermediateArtifacts intermediateArtifacts, + CompilationSupport compilationSupport, + CompilationArtifacts compilationArtifacts, + CcLibraryHelper helper) { + 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); + } + + private void registerFullyLinkAction( + RuleContext ruleContext, + ObjcCommon common, + VariablesExtension variablesExtension, + FeatureConfiguration featureConfiguration) + throws InterruptedException { + Artifact fullyLinkedArchive = + ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB); + PathFragment labelName = new PathFragment(ruleContext.getLabel().getName()); + String libraryIdentifier = + ruleContext + .getPackageDirectory() + .getRelative(labelName.replaceName("lib" + labelName.getBaseName())) + .getPathString(); + CppLinkAction fullyLinkAction = + new CppLinkActionBuilder(ruleContext, fullyLinkedArchive) + .addActionInputs(common.getObjcProvider().getObjcLibraries()) + .addActionInputs(common.getObjcProvider().getCcLibraries()) + .addActionInputs(common.getObjcProvider().get(IMPORTED_LIBRARY).toSet()) + .setLinkType(LinkTargetType.OBJC_FULLY_LINKED_ARCHIVE) + .setLinkStaticness(LinkStaticness.FULLY_STATIC) + .setLibraryIdentifier(libraryIdentifier) + .addVariablesExtension(variablesExtension) + .setFeatureConfiguration(featureConfiguration) + .build(); + ruleContext.registerAction(fullyLinkAction); + } + + /** Throws errors or warnings for bad attribute state. */ private void validateAttributes(RuleContext ruleContext) { for (String copt : ObjcCommon.getNonCrosstoolCopts(ruleContext)) { if (copt.contains("-fmodules-cache-path")) { @@ -282,11 +227,7 @@ public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory { .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext)) .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<>(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibraryRule.java index 42959fc43e..85014c37e8 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibraryRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibraryRule.java @@ -32,7 +32,9 @@ public class ExperimentalObjcLibraryRule implements RuleDefinition { return builder .requiresConfigurationFragments( ObjcConfiguration.class, AppleConfiguration.class, CppConfiguration.class) - .setImplicitOutputsFunction(ImplicitOutputsFunction.fromFunctions(XcodeSupport.PBXPROJ)) + .setImplicitOutputsFunction( + ImplicitOutputsFunction.fromFunctions( + CompilationSupport.FULLY_LINKED_LIB, XcodeSupport.PBXPROJ)) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java index 4051f81ff5..40ed2b1c73 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java @@ -17,6 +17,7 @@ package com.google.devtools.build.lib.rules.objc; import static com.google.devtools.build.lib.collect.nestedset.Order.LINK_ORDER; import static com.google.devtools.build.lib.collect.nestedset.Order.STABLE_ORDER; +import com.google.common.base.Predicates; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; @@ -32,7 +33,6 @@ import com.google.devtools.build.lib.rules.cpp.CppModuleMap; import com.google.devtools.build.lib.rules.cpp.LinkerInputs; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; -import com.google.devtools.build.lib.syntax.Concatable.Concatter; import com.google.devtools.build.lib.syntax.EvalUtils; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.PathFragment; @@ -470,6 +470,26 @@ public final class ObjcProvider extends SkylarkClassObject implements Transitive return !get(XCASSETS_DIR).isEmpty(); } + /** Returns the list of .a files required for linking that arise from objc libraries. */ + ImmutableList<Artifact> getObjcLibraries() { + // JRE libraries must be ordered after all regular objc libraries. + NestedSet<Artifact> jreLibs = get(JRE_LIBRARY); + return ImmutableList.<Artifact>builder() + .addAll(Iterables.filter( + get(LIBRARY), Predicates.not(Predicates.in(jreLibs.toSet())))) + .addAll(jreLibs) + .build(); + } + + /** Returns the list of .a files required for linking that arise from cc libraries. */ + ImmutableList<Artifact> getCcLibraries() { + ImmutableList.Builder<Artifact> ccLibraryBuilder = ImmutableList.builder(); + for (LinkerInputs.LibraryToLink libraryToLink : get(CC_LIBRARY)) { + ccLibraryBuilder.add(libraryToLink.getArtifact()); + } + return ccLibraryBuilder.build(); + } + /** * A builder for this context with an API that is optimized for collecting information from * several transitive dependencies. 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 new file mode 100644 index 0000000000..70fc868af9 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcVariablesExtension.java @@ -0,0 +1,155 @@ +// Copyright 2016 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.rules.objc; + +import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY; + +import com.google.common.collect.ImmutableList; +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.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.ValueSequence; +import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.VariablesExtension; + +/** Build variable extensions for templating a toolchain for objc builds. */ +class ObjcVariablesExtension implements VariablesExtension { + + static final String PCH_FILE_VARIABLE_NAME = "pch_file"; + static final String FRAMEWORKS_VARIABLE_NAME = "framework_paths"; + static final String VERSION_MIN_VARIABLE_NAME = "version_min"; + static final String MODULES_MAPS_DIR_NAME = "module_maps_dir"; + static final String OBJC_MODULE_CACHE_DIR_NAME = "_objc_module_cache"; + static final String OBJC_MODULE_CACHE_KEY = "modules_cache_path"; + static final String OBJ_LIST_PATH_VARIABLE_NAME = "obj_list_path"; + static final String ARCHIVE_PATH_VARIABLE_NAME = "archive_path"; + static final String FULLY_LINKED_ARCHIVE_PATH_VARIABLE_NAME = "fully_linked_archive_path"; + static final String OBJC_LIBRARY_EXEC_PATHS_VARIABLE_NAME = "objc_library_exec_paths"; + 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"; + + 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 ObjcConfiguration objcConfiguration; + + public ObjcVariablesExtension( + RuleContext ruleContext, + ObjcProvider objcProvider, + CompilationArtifacts compilationArtifacts, + Artifact fullyLinkArchive, + IntermediateArtifacts intermediateArtifacts, + BuildConfiguration buildConfiguration) { + this.ruleContext = ruleContext; + this.objcProvider = objcProvider; + this.compilationArtifacts = compilationArtifacts; + this.fullyLinkArchive = fullyLinkArchive; + this.intermediateArtifacts = intermediateArtifacts; + this.buildConfiguration = buildConfiguration; + this.objcConfiguration = buildConfiguration.getFragment(ObjcConfiguration.class); + this.appleConfiguration = buildConfiguration.getFragment(AppleConfiguration.class); + } + + @Override + public void addVariables(CcToolchainFeatures.Variables.Builder builder) { + addPchVariables(builder); + addFrameworkVariables(builder); + addArchVariables(builder); + if (ObjcCommon.shouldUseObjcModules(ruleContext)) { + addModuleMapVariables(builder); + } + if (compilationArtifacts.getArchive().isPresent()) { + addArchiveVariables(builder); + } + addFullyLinkArchiveVariables(builder); + } + + 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(CcToolchainFeatures.Variables.Builder builder) { + ValueSequence.Builder frameworkSequence = new ValueSequence.Builder(); + for (String framework : + CompilationSupport.commonFrameworkNames(objcProvider, appleConfiguration)) { + frameworkSequence.addValue(framework); + } + builder.addSequence(FRAMEWORKS_VARIABLE_NAME, frameworkSequence.build()); + } + + private void addModuleMapVariables(CcToolchainFeatures.Variables.Builder builder) { + builder.addVariable( + MODULES_MAPS_DIR_NAME, + intermediateArtifacts + .moduleMap() + .getArtifact() + .getExecPath() + .getParentDirectory() + .toString()); + builder.addVariable( + OBJC_MODULE_CACHE_KEY, + buildConfiguration.getGenfilesFragment() + "/" + OBJC_MODULE_CACHE_DIR_NAME); + } + + private void addArchVariables(CcToolchainFeatures.Variables.Builder builder) { + Platform platform = appleConfiguration.getSingleArchPlatform(); + switch (platform.getType()) { + case IOS: + builder.addVariable(VERSION_MIN_VARIABLE_NAME, objcConfiguration.getMinimumOs().toString()); + break; + case WATCHOS: + builder.addVariable( + VERSION_MIN_VARIABLE_NAME, + appleConfiguration.getSdkVersionForPlatform(platform).toString()); + break; + default: + 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()); + } + + private void addFullyLinkArchiveVariables(CcToolchainFeatures.Variables.Builder builder) { + builder.addVariable( + FULLY_LINKED_ARCHIVE_PATH_VARIABLE_NAME, fullyLinkArchive.getExecPathString()); + builder.addSequenceVariable( + OBJC_LIBRARY_EXEC_PATHS_VARIABLE_NAME, + ImmutableList.copyOf(Artifact.toExecPaths(objcProvider.getObjcLibraries()))); + builder.addSequenceVariable( + CC_LIBRARY_EXEC_PATHS_VARIABLE_NAME, + ImmutableList.copyOf(Artifact.toExecPaths(objcProvider.getCcLibraries()))); + builder.addSequenceVariable( + IMPORTED_LIBRARY_EXEC_PATHS_VARIABLE_NAME, + ImmutableList.copyOf(Artifact.toExecPaths(objcProvider.get(IMPORTED_LIBRARY)))); + } +} |