aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar Peter Schmitt <schmitt@google.com>2015-04-20 20:18:49 +0000
committerGravatar Laszlo Csomor <laszlocsomor@google.com>2015-04-21 10:57:52 +0000
commitc1c147d0f8a45f7f47ea19e5bad697791ec5a00b (patch)
tree275bbb7d9df14c67d04d4f7e047b1a6ea101a9c0 /src/main/java/com/google
parentdedda49b582bd18e461448e40c04a6ff091ccff9 (diff)
Refactor link command line to live in CompilationSupport.
Also simplifies command line construction and removes redundant linker arguments. -- MOS_MIGRATED_REVID=91613561
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java159
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcActionsBuilder.java176
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java5
7 files changed, 160 insertions, 206 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
index d50bdd8bf8..979909ea78 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
@@ -19,6 +19,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
@@ -28,8 +29,7 @@ import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesSupport;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
-import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkArgs;
-import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkInputs;
+import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes;
import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary;
@@ -83,7 +83,7 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
.registerJ2ObjcCompileAndArchiveActions(optionsProvider, objcProvider)
.registerCompileAndArchiveActions(common, optionsProvider)
.addXcodeSettings(xcodeProviderBuilder, common, optionsProvider)
- .registerLinkActions(objcProvider, extraLinkArgs, new ExtraLinkInputs())
+ .registerLinkActions(objcProvider, extraLinkArgs, ImmutableList.<Artifact>of())
.validateAttributes();
Optional<XcTestAppProvider> xcTestAppProvider;
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 cc29288b0f..132cf86c4c 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
@@ -15,14 +15,27 @@
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.FORCE_LOAD_LIBRARY;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_DIR;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_FILE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_CPP;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.HEADER;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INCLUDE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWORK;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK;
+import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.CLANG;
+import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.CLANG_PLUSPLUS;
+import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.DSYMUTIL;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.NON_ARC_SRCS_TYPE;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.SRCS_TYPE;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -31,16 +44,18 @@ 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.actions.ActionConstructionContext;
+import com.google.devtools.build.lib.analysis.actions.CommandLine;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
-import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkArgs;
-import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkInputs;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
import com.google.devtools.build.lib.rules.objc.XcodeProvider.Builder;
import com.google.devtools.build.lib.shell.ShellUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Support for rules that compile sources. Provides ways to determine files that should be output,
* registering Xcode settings and generating the various actions that might be needed for
@@ -63,6 +78,15 @@ final class CompilationSupport {
ImmutableList.of("-fprofile-arcs", "-ftest-coverage", "-fprofile-dir=./coverage_output");
/**
+ * Iterable wrapper providing strong type safety for arguments to binary linking.
+ */
+ static final class ExtraLinkArgs extends IterableWrapper<String> {
+ ExtraLinkArgs(String... args) {
+ super(args);
+ }
+ }
+
+ /**
* Returns information about the given rule's compilation artifacts.
*/
// TODO(bazel-team): Remove this information from ObjcCommon and move it internal to this class.
@@ -176,7 +200,7 @@ final class CompilationSupport {
ruleContext.registerAction(ObjcActionsBuilder.spawnOnDarwinActionBuilder()
.setMnemonic("ObjcCompile")
- .setExecutable(ObjcRuleClasses.CLANG)
+ .setExecutable(CLANG)
.setCommandLine(commandLine.build())
.addInput(sourceFile)
.addOutput(objFile)
@@ -240,7 +264,7 @@ final class CompilationSupport {
* @return this compilation support
*/
CompilationSupport registerLinkActions(ObjcProvider objcProvider, ExtraLinkArgs extraLinkArgs,
- ExtraLinkInputs extraLinkInputs) {
+ Iterable<Artifact> extraLinkInputs) {
IntermediateArtifacts intermediateArtifacts =
ObjcRuleClasses.intermediateArtifacts(ruleContext);
Optional<Artifact> dsymBundle;
@@ -251,16 +275,129 @@ final class CompilationSupport {
dsymBundle = Optional.absent();
}
- ExtraLinkArgs coverageLinkArgs = new ExtraLinkArgs();
+ registerLinkAction(objcProvider, extraLinkArgs, extraLinkInputs, dsymBundle);
+ return this;
+ }
+
+ private void registerLinkAction(ObjcProvider objcProvider, ExtraLinkArgs extraLinkArgs,
+ Iterable<Artifact> extraLinkInputs, Optional<Artifact> dsymBundle) {
+ Artifact linkedBinary =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext).singleArchitectureBinary();
+
+ ruleContext.registerAction(
+ ObjcActionsBuilder.spawnOnDarwinActionBuilder()
+ .setMnemonic("ObjcLink")
+ .setShellCommand(ImmutableList.of("/bin/bash", "-c"))
+ .setCommandLine(linkCommandLine(extraLinkArgs, objcProvider, linkedBinary, dsymBundle))
+ .addOutput(linkedBinary)
+ .addOutputs(dsymBundle.asSet())
+ .addTransitiveInputs(objcProvider.get(LIBRARY))
+ .addTransitiveInputs(objcProvider.get(IMPORTED_LIBRARY))
+ .addTransitiveInputs(objcProvider.get(FRAMEWORK_FILE))
+ .addInputs(extraLinkInputs)
+ .build(ruleContext));
+ }
+
+ private static final String FRAMEWORK_SUFFIX = ".framework";
+
+ private CommandLine linkCommandLine(ExtraLinkArgs extraLinkArgs,
+ ObjcProvider objcProvider, Artifact linkedBinary, Optional<Artifact> dsymBundle) {
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+
+ final CustomCommandLine.Builder commandLine = CustomCommandLine.builder();
+
+ if (objcProvider.is(USES_CPP)) {
+ commandLine
+ .addPath(CLANG_PLUSPLUS)
+ .add("-stdlib=libc++");
+ } else {
+ commandLine.addPath(CLANG);
+ }
+ commandLine
+ .add(IosSdkCommands.commonLinkAndCompileFlagsForClang(objcProvider, objcConfiguration))
+ .add("-Xlinker").add("-objc_abi_version")
+ .add("-Xlinker").add("2")
+ .add("-fobjc-link-runtime")
+ .add(IosSdkCommands.DEFAULT_LINKER_FLAGS)
+ .addBeforeEach("-framework", frameworkNames(objcProvider))
+ .addBeforeEach("-weak_framework", SdkFramework.names(objcProvider.get(WEAK_SDK_FRAMEWORK)))
+ .addExecPath("-o", linkedBinary)
+ .addExecPaths(objcProvider.get(LIBRARY))
+ .addExecPaths(objcProvider.get(IMPORTED_LIBRARY))
+ .add(dylibPaths(objcProvider))
+ .addBeforeEach("-force_load", Artifact.toExecPaths(objcProvider.get(FORCE_LOAD_LIBRARY)))
+ .add(extraLinkArgs)
+ .build();
+
if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
- coverageLinkArgs = new ExtraLinkArgs(LINKER_COVERAGE_FLAGS);
+ commandLine.add(LINKER_COVERAGE_FLAGS);
}
- ObjcRuleClasses.actionsBuilder(ruleContext).registerLinkAction(
- intermediateArtifacts.singleArchitectureBinary(), objcProvider,
- extraLinkArgs.appendedWith(coverageLinkArgs), extraLinkInputs,
- dsymBundle);
- return this;
+ // Call to dsymutil for debug symbol generation must happen in the link action.
+ // All debug symbol information is encoded in object files inside archive files. To generate
+ // the debug symbol bundle, dsymutil will look inside the linked binary for the encoded
+ // absolute paths to archive files, which are only valid in the link action.
+ if (dsymBundle.isPresent()) {
+ commandLine
+ .add("&&")
+ .addPath(DSYMUTIL)
+ .add(linkedBinary.getExecPathString())
+ .addExecPath("-o", dsymBundle.get());
+ }
+
+ return new SingleArgCommandLine(commandLine.build());
+ }
+
+ /**
+ * Command line that converts its input's arg array to a single input.
+ *
+ * <p>Required as a hack to the link command line because that may contain two commands, which are
+ * then passed to {@code /bin/bash -c}, and accordingly need to be a single argument.
+ */
+ private static class SingleArgCommandLine extends CommandLine {
+
+ private final CommandLine original;
+
+ private SingleArgCommandLine(CommandLine original) {
+ this.original = original;
+ }
+
+ @Override
+ public Iterable<String> arguments() {
+ return ImmutableList.of(Joiner.on(' ').join(original.arguments()));
+ }
+ }
+
+ private Iterable<String> dylibPaths(ObjcProvider objcProvider) {
+ ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
+ ImmutableList.Builder<String> args = new ImmutableList.Builder<>();
+ for (String dylib : objcProvider.get(SDK_DYLIB)) {
+ args.add(String.format(
+ "%s/usr/lib/%s.dylib", IosSdkCommands.sdkDir(objcConfiguration), dylib));
+ }
+ return args.build();
+ }
+
+ /**
+ * All framework names to pass to the linker using {@code -framework} flags. For a framework in
+ * the directory foo/bar.framework, the name is "bar". Each framework is found without using the
+ * full path by means of the framework search paths. The search paths are added by
+ * {@link IosSdkCommands#commonLinkAndCompileFlagsForClang(ObjcProvider, ObjcConfiguration)}).
+ *
+ * <p>It's awful that we can't pass the full path to the framework and avoid framework search
+ * paths, but this is imposed on us by clang. clang does not support passing the full path to the
+ * framework, so Bazel cannot do it either.
+ */
+ private Iterable<String> frameworkNames(ObjcProvider provider) {
+ List<String> names = new ArrayList<>();
+ Iterables.addAll(names, SdkFramework.names(provider.get(SDK_FRAMEWORK)));
+ for (PathFragment frameworkDir : provider.get(FRAMEWORK_DIR)) {
+ String segment = frameworkDir.getBaseName();
+ Preconditions.checkState(segment.endsWith(FRAMEWORK_SUFFIX),
+ "expect %s to end with %s, but it does not", segment, FRAMEWORK_SUFFIX);
+ names.add(segment.substring(0, segment.length() - FRAMEWORK_SUFFIX.length()));
+ }
+ return names;
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java
index cecc3d9f2c..e85e4c44f5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java
@@ -14,7 +14,7 @@
package com.google.devtools.build.lib.rules.objc;
-import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkArgs;
+import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
/**
* Implementation for the "ios_extension_binary" rule.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
index 7171706dd8..17e8395789 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
@@ -29,8 +29,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
-import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkArgs;
-import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkInputs;
+import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary;
import java.util.ArrayList;
@@ -86,11 +85,11 @@ public abstract class IosTest implements RuleConfiguredTargetFactory {
XcodeProductType productType;
ExtraLinkArgs extraLinkArgs;
- ExtraLinkInputs extraLinkInputs;
+ Iterable<Artifact> extraLinkInputs;
if (!isXcTest(ruleContext)) {
productType = XcodeProductType.APPLICATION;
extraLinkArgs = new ExtraLinkArgs();
- extraLinkInputs = new ExtraLinkInputs();
+ extraLinkInputs = ImmutableList.of();
} else {
productType = XcodeProductType.UNIT_TEST;
XcodeProvider appIpaXcodeProvider =
@@ -111,18 +110,13 @@ public abstract class IosTest implements RuleConfiguredTargetFactory {
"-bundle",
"-bundle_loader", bundleLoader.getExecPathString());
- extraLinkInputs = new ExtraLinkInputs(bundleLoader);
+ extraLinkInputs = ImmutableList.of(bundleLoader);
filesToBuild.add(testApp.getIpa());
}
- if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
- extraLinkArgs = extraLinkArgs.appendedWith(CompilationSupport.LINKER_COVERAGE_FLAGS);
- }
-
new CompilationSupport(ruleContext)
- .registerLinkActions(
- common.getObjcProvider(), extraLinkArgs, extraLinkInputs)
+ .registerLinkActions(common.getObjcProvider(), extraLinkArgs, extraLinkInputs)
.registerJ2ObjcCompileAndArchiveActions(optionsProvider, common.getObjcProvider())
.registerCompileAndArchiveActions(common, optionsProvider)
.addXcodeSettings(xcodeProviderBuilder, common, optionsProvider)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcActionsBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcActionsBuilder.java
index 9a0684f1bd..cda2843f8c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcActionsBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcActionsBuilder.java
@@ -14,81 +14,45 @@
package com.google.devtools.build.lib.rules.objc;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FORCE_LOAD_LIBRARY;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_DIR;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_FILE;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_CPP;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWORK;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
import com.google.common.io.ByteSource;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.ActionRegistry;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
import com.google.devtools.build.lib.analysis.actions.BinaryFileWriteAction;
-import com.google.devtools.build.lib.analysis.actions.CommandLine;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos;
import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.annotation.CheckReturnValue;
/**
* Object that creates actions used by Objective-C rules.
*/
final class ObjcActionsBuilder {
- private static final Joiner COMMAND_JOINER = Joiner.on(' ');
-
private final ActionConstructionContext context;
private final IntermediateArtifacts intermediateArtifacts;
private final ObjcConfiguration objcConfiguration;
private final ActionRegistry actionRegistry;
- private final PathFragment clang;
- private final PathFragment clangPlusPlus;
- private final PathFragment dsymutil;
/**
* @param context {@link ActionConstructionContext} of the rule
* @param intermediateArtifacts provides intermediate output paths for this rule
* @param objcConfiguration configuration for this rule
* @param actionRegistry registry with which to register new actions
- * @param clang path to clang binary to use for compilation. This will soon be deprecated, and
- * replaced with an Artifact from an objc_toolchain.
- * @param clangPlusPlus path to clang++ binary to use for compilation. This will soon be
- * deprecated and replaced with an Artifact from an objc_toolchain.
- * @param dsymutil path to the dsymutil binary to use when generating debug symbols. This will
- * soon be deprecated and replaced with an Aritifact from an objc_toolchain.
*/
ObjcActionsBuilder(
ActionConstructionContext context,
IntermediateArtifacts intermediateArtifacts,
ObjcConfiguration objcConfiguration,
- ActionRegistry actionRegistry,
- PathFragment clang,
- PathFragment clangPlusPlus,
- PathFragment dsymutil) {
+ ActionRegistry actionRegistry) {
this.context = Preconditions.checkNotNull(context);
this.intermediateArtifacts = Preconditions.checkNotNull(intermediateArtifacts);
this.objcConfiguration = Preconditions.checkNotNull(objcConfiguration);
this.actionRegistry = Preconditions.checkNotNull(actionRegistry);
- this.clang = clang;
- this.clangPlusPlus = clangPlusPlus;
- this.dsymutil = dsymutil;
}
/**
@@ -165,142 +129,4 @@ final class ObjcActionsBuilder {
super(args);
}
}
-
-
- private static final String FRAMEWORK_SUFFIX = ".framework";
-
- /**
- * All framework names to pass to the linker using {@code -framework} flags. For a framework in
- * the directory foo/bar.framework, the name is "bar". Each framework is found without using the
- * full path by means of the framework search paths. The search paths are added by
- * {@link IosSdkCommands#commonLinkAndCompileFlagsForClang(ObjcProvider, ObjcConfiguration)}).
- *
- * <p>It's awful that we can't pass the full path to the framework and avoid framework search
- * paths, but this is imposed on us by clang. clang does not support passing the full path to the
- * framework, so Bazel cannot do it either.
- */
- private static Iterable<String> frameworkNames(ObjcProvider provider) {
- List<String> names = new ArrayList<>();
- Iterables.addAll(names, SdkFramework.names(provider.get(SDK_FRAMEWORK)));
- for (PathFragment frameworkDir : provider.get(FRAMEWORK_DIR)) {
- String segment = frameworkDir.getBaseName();
- Preconditions.checkState(segment.endsWith(FRAMEWORK_SUFFIX),
- "expect %s to end with %s, but it does not", segment, FRAMEWORK_SUFFIX);
- names.add(segment.substring(0, segment.length() - FRAMEWORK_SUFFIX.length()));
- }
- return names;
- }
-
- static final class ExtraLinkArgs extends IterableWrapper<String> {
- ExtraLinkArgs(Iterable<String> args) {
- super(args);
- }
-
- ExtraLinkArgs(String... args) {
- super(args);
- }
-
- /*
- * Returns an ExtraLinkArgs with the parameter appended to this instance's contents. This
- * function does not modify this instance.
- */
- @CheckReturnValue
- public ExtraLinkArgs appendedWith(Iterable<String> extraLinkArgs) {
- return new ExtraLinkArgs(Iterables.concat(this, extraLinkArgs));
- }
- }
-
- static final class ExtraLinkInputs extends IterableWrapper<Artifact> {
- ExtraLinkInputs(Artifact... inputs) {
- super(inputs);
- }
- }
-
- private final class LinkCommandLine extends CommandLine {
- private final ObjcProvider objcProvider;
- private final Artifact linkedBinary;
- private final Optional<Artifact> dsymBundle;
- private final ExtraLinkArgs extraLinkArgs;
-
- LinkCommandLine(ExtraLinkArgs extraLinkArgs,
- ObjcProvider objcProvider, Artifact linkedBinary, Optional<Artifact> dsymBundle) {
- this.extraLinkArgs = Preconditions.checkNotNull(extraLinkArgs);
- this.objcProvider = Preconditions.checkNotNull(objcProvider);
- this.linkedBinary = Preconditions.checkNotNull(linkedBinary);
- this.dsymBundle = Preconditions.checkNotNull(dsymBundle);
- }
-
- Iterable<String> dylibPaths() {
- ImmutableList.Builder<String> args = new ImmutableList.Builder<>();
- for (String dylib : objcProvider.get(SDK_DYLIB)) {
- args.add(String.format(
- "%s/usr/lib/%s.dylib", IosSdkCommands.sdkDir(objcConfiguration), dylib));
- }
- return args.build();
- }
-
- @Override
- public Iterable<String> arguments() {
- StringBuilder argumentStringBuilder = new StringBuilder();
-
- Iterable<String> archiveExecPaths = Artifact.toExecPaths(
- Iterables.concat(objcProvider.get(LIBRARY), objcProvider.get(IMPORTED_LIBRARY)));
- COMMAND_JOINER.appendTo(argumentStringBuilder, new ImmutableList.Builder<String>()
- .add(objcProvider.is(USES_CPP) ? clangPlusPlus.toString() : clang.toString())
- .addAll(objcProvider.is(USES_CPP)
- ? ImmutableList.of("-stdlib=libc++") : ImmutableList.<String>of())
- .addAll(IosSdkCommands.commonLinkAndCompileFlagsForClang(objcProvider, objcConfiguration))
- .add("-Xlinker", "-objc_abi_version")
- .add("-Xlinker", "2")
- .add("-fobjc-link-runtime")
- .addAll(IosSdkCommands.DEFAULT_LINKER_FLAGS)
- .addAll(Interspersing.beforeEach("-framework", frameworkNames(objcProvider)))
- .addAll(Interspersing.beforeEach(
- "-weak_framework", SdkFramework.names(objcProvider.get(WEAK_SDK_FRAMEWORK))))
- .add("-o", linkedBinary.getExecPathString())
- .addAll(archiveExecPaths)
- .addAll(dylibPaths())
- .addAll(extraLinkArgs)
- .build());
-
- // Call to dsymutil for debug symbol generation must happen in the link action.
- // All debug symbol information is encoded in object files inside archive files. To generate
- // the debug symbol bundle, dsymutil will look inside the linked binary for the encoded
- // absolute paths to archive files, which are only valid in the link action.
- for (Artifact justDsymBundle : dsymBundle.asSet()) {
- argumentStringBuilder.append(" ");
- COMMAND_JOINER.appendTo(argumentStringBuilder, new ImmutableList.Builder<String>()
- .add("&&")
- .add(dsymutil.toString())
- .add(linkedBinary.getExecPathString())
- .add("-o").add(justDsymBundle.getExecPathString())
- .build());
- }
-
- return ImmutableList.of(argumentStringBuilder.toString());
- }
- }
-
- /**
- * Generates an action to link a binary.
- */
- void registerLinkAction(Artifact linkedBinary, ObjcProvider objcProvider,
- ExtraLinkArgs extraLinkArgs, ExtraLinkInputs extraLinkInputs, Optional<Artifact> dsymBundle) {
- extraLinkArgs = new ExtraLinkArgs(Iterables.concat(
- Interspersing.beforeEach(
- "-force_load", Artifact.toExecPaths(objcProvider.get(FORCE_LOAD_LIBRARY))),
- extraLinkArgs));
- register(spawnOnDarwinActionBuilder()
- .setMnemonic("ObjcLink")
- .setShellCommand(ImmutableList.of("/bin/bash", "-c"))
- .setCommandLine(
- new LinkCommandLine(extraLinkArgs, objcProvider, linkedBinary, dsymBundle))
- .addOutput(linkedBinary)
- .addOutputs(dsymBundle.asSet())
- .addTransitiveInputs(objcProvider.get(LIBRARY))
- .addTransitiveInputs(objcProvider.get(IMPORTED_LIBRARY))
- .addTransitiveInputs(objcProvider.get(FRAMEWORK_FILE))
- .addInputs(extraLinkInputs)
- .build(context));
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java
index 37b772b99e..02bf67f88c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java
@@ -14,7 +14,7 @@
package com.google.devtools.build.lib.rules.objc;
-import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkArgs;
+import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
/**
* Implementation for the "objc_binary" rule.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
index beb0fdc4c9..107abfe392 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
@@ -183,10 +183,7 @@ public class ObjcRuleClasses {
ruleContext,
intermediateArtifacts(ruleContext),
ObjcRuleClasses.objcConfiguration(ruleContext),
- ruleContext,
- CLANG,
- CLANG_PLUSPLUS,
- DSYMUTIL);
+ ruleContext);
}
public static ObjcConfiguration objcConfiguration(RuleContext ruleContext) {