aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main
diff options
context:
space:
mode:
authorGravatar Marcel Hlopko <hlopko@google.com>2016-10-11 15:30:49 +0000
committerGravatar Yue Gan <yueg@google.com>2016-10-12 08:55:07 +0000
commit74b94328db5346e0f6c573731fcbaa85ca751304 (patch)
treecab3cab9a81aab6bea2016b2567039661f682324 /src/main
parent671045b8fd9cc53d208af6eb38dab5c1fb543545 (diff)
Move interface so building to action configs
This cl moves the conditional building of interface libraries from LinkCommandLine to action configs and features. It provides link_dynamic_library.sh to keep blaze backwards compatible. The script and related code can be deleted once all crosstools are updated. RELNOTES: No. -- MOS_MIGRATED_REVID=135799041
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java18
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java565
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java80
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionConfigs.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java85
8 files changed, 444 insertions, 373 deletions
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 ec766a7d72..5ff24aa753 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
@@ -56,6 +56,7 @@ import java.util.Map;
* Implementation for the cc_toolchain rule.
*/
public class CcToolchain implements RuleConfiguredTargetFactory {
+
/**
* This file (found under the sysroot) may be unconditionally included in every C/C++ compilation.
*/
@@ -198,6 +199,8 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
"FDO_DIR", cppConfiguration.getFdoInstrument().getPathString()));
}
+ Artifact linkDynamicLibraryTool = getLinkDynamicLibraryTool(ruleContext);
+
CcToolchainProvider provider =
new CcToolchainProvider(
cppConfiguration,
@@ -220,6 +223,7 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
getBuildVariables(ruleContext),
getBuiltinIncludes(ruleContext),
coverageEnvironment.build(),
+ linkDynamicLibraryTool,
getEnvironment(ruleContext));
RuleConfiguredTargetBuilder builder =
new RuleConfiguredTargetBuilder(ruleContext)
@@ -250,6 +254,10 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
return builder.build();
}
+ private Artifact getLinkDynamicLibraryTool(RuleContext ruleContext) {
+ return ruleContext.getPrerequisiteArtifact("$link_dynamic_library_tool", Mode.TARGET);
+ }
+
private ImmutableList<Artifact> getBuiltinIncludes(RuleContext ruleContext) {
ImmutableList.Builder<Artifact> result = ImmutableList.builder();
for (Artifact artifact : inputsForLibc(ruleContext)) {
@@ -285,6 +293,7 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
return NestedSetBuilder.<Artifact>stableOrder()
.addTransitive(link)
.addTransitive(AnalysisUtils.getMiddlemanFor(ruleContext, ":libc_top"))
+ .add(getLinkDynamicLibraryTool(ruleContext))
.add(
ruleContext
.getAnalysisEnvironment()
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
index 799be8b998..a5e37154a6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
@@ -1149,9 +1149,12 @@ public class CcToolchainFeatures implements Serializable {
return enabledFeatureNames.contains(feature);
}
- /**
- * @return whether an action config for the blaze action with the given name is enabled.
- */
+ /** @return true if tool_path in action_config points to a real tool, not a dummy placeholder */
+ public boolean hasConfiguredLinkerPathInActionConfig() {
+ return isEnabled("has_configured_linker_path");
+ }
+
+ /** @return whether an action config for the blaze action with the given name is enabled. */
boolean actionIsConfigured(String actionName) {
return enabledActionConfigActionNames.contains(actionName);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java
index 755da5311c..4145ebdede 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java
@@ -25,9 +25,7 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.PathFragment;
-
import java.util.Map;
-
import javax.annotation.Nullable;
/**
@@ -35,9 +33,7 @@ import javax.annotation.Nullable;
*/
@Immutable
public final class CcToolchainProvider implements TransitiveInfoProvider {
- /**
- * An empty toolchain to be returned in the error case (instead of null).
- */
+ /** An empty toolchain to be returned in the error case (instead of null). */
public static final CcToolchainProvider EMPTY_TOOLCHAIN_IS_ERROR =
new CcToolchainProvider(
null,
@@ -60,6 +56,7 @@ public final class CcToolchainProvider implements TransitiveInfoProvider {
ImmutableMap.<String, String>of(),
ImmutableList.<Artifact>of(),
NestedSetBuilder.<Pair<String, String>>emptySet(Order.COMPILE_ORDER),
+ null,
ImmutableMap.<String, String>of());
@Nullable private final CppConfiguration cppConfiguration;
@@ -82,6 +79,7 @@ public final class CcToolchainProvider implements TransitiveInfoProvider {
private final ImmutableMap<String, String> buildVariables;
private final ImmutableList<Artifact> builtinIncludeFiles;
private final NestedSet<Pair<String, String>> coverageEnvironment;
+ @Nullable private final Artifact linkDynamicLibraryTool;
private final ImmutableMap<String, String> environment;
public CcToolchainProvider(
@@ -105,6 +103,7 @@ public final class CcToolchainProvider implements TransitiveInfoProvider {
Map<String, String> buildVariables,
ImmutableList<Artifact> builtinIncludeFiles,
NestedSet<Pair<String, String>> coverageEnvironment,
+ Artifact linkDynamicLibraryTool,
ImmutableMap<String, String> environment) {
this.cppConfiguration = cppConfiguration;
this.crosstool = Preconditions.checkNotNull(crosstool);
@@ -126,6 +125,7 @@ public final class CcToolchainProvider implements TransitiveInfoProvider {
this.buildVariables = ImmutableMap.copyOf(buildVariables);
this.builtinIncludeFiles = builtinIncludeFiles;
this.coverageEnvironment = coverageEnvironment;
+ this.linkDynamicLibraryTool = linkDynamicLibraryTool;
this.environment = environment;
}
@@ -283,4 +283,12 @@ public final class CcToolchainProvider implements TransitiveInfoProvider {
public ImmutableMap<String, String> getEnvironment() {
return environment;
}
+
+ /**
+ * Returns the tool which should be used for linking dynamic libraries, or in case it's not
+ * specified by the crosstool this will be @tools_repository/tools/cpp:link_dynamic_library
+ */
+ public Artifact getLinkDynamicLibraryTool() {
+ return linkDynamicLibraryTool;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
index 9ee448165f..786add8315 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
@@ -75,12 +75,16 @@ public final class CcToolchainRule implements RuleDefinition {
.add(attr("module_map", LABEL).legacyAllowAnyFileType().cfg(HOST))
.add(attr("supports_param_files", BOOLEAN).value(true))
.add(attr("supports_header_parsing", BOOLEAN).value(false))
+ .add(
+ attr("$link_dynamic_library_tool", LABEL)
+ .value(env.getToolsLabel("//tools/cpp:link_dynamic_library")))
// TODO(bazel-team): Should be using the TARGET configuration.
.add(attr(":libc_top", LABEL).cfg(HOST).value(LIBC_TOP))
- .add(attr(":lipo_context_collector", LABEL)
- .cfg(LipoTransition.LIPO_COLLECTOR)
- .value(CppRuleClasses.LIPO_CONTEXT_COLLECTOR)
- .skipPrereqValidatorCheck())
+ .add(
+ attr(":lipo_context_collector", LABEL)
+ .cfg(LipoTransition.LIPO_COLLECTOR)
+ .value(CppRuleClasses.LIPO_CONTEXT_COLLECTOR)
+ .skipPrereqValidatorCheck())
.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 95f37e7d0c..7231f64869 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
@@ -51,6 +51,7 @@ import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CTool
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain.ArtifactNamePattern;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LinkingModeFlags;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LipoMode;
+import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath;
import com.google.devtools.common.options.OptionsParsingException;
import com.google.protobuf.TextFormat;
import com.google.protobuf.TextFormat.ParseException;
@@ -693,7 +694,6 @@ public class CppConfiguration extends BuildConfiguration.Fragment {
// feature configuration, and all crosstools have been converted.
private CToolchain addLegacyFeatures(CToolchain toolchain) {
CToolchain.Builder toolchainBuilder = CToolchain.newBuilder();
- toolchainBuilder.mergeFrom(toolchain);
Set<ArtifactCategory> definedCategories = new HashSet<>();
for (ArtifactNamePattern pattern : toolchainBuilder.getArtifactNamePatternList()) {
@@ -719,292 +719,302 @@ public class CppConfiguration extends BuildConfiguration.Fragment {
featuresBuilder.add(feature.getName());
}
Set<String> features = featuresBuilder.build();
- if (features.contains(CppRuleClasses.NO_LEGACY_FEATURES)) {
- // The toolchain requested to not get any legacy features enabled.
- return toolchainBuilder.build();
- }
+ if (!features.contains(CppRuleClasses.NO_LEGACY_FEATURES)) {
+ try {
+ if (!linkActionsAreConfigured(toolchain)) {
+ String linkerToolPath = "DUMMY_LINKER_TOOL";
+ for (ToolPath tool : toolchain.getToolPathList()) {
+ if (tool.getName().equals(Tool.GCC.getNamePart())) {
+ linkerToolPath =
+ crosstoolTopPathFragment
+ .getRelative(new PathFragment(tool.getPath()))
+ .getPathString();
+ }
+ }
+ if (getTargetLibc().equals("macosx")) {
+ TextFormat.merge(
+ CppLinkActionConfigs.getCppLinkActionConfigs(
+ CppLinkPlatform.MAC, features, linkerToolPath),
+ toolchainBuilder);
+ } else {
+ TextFormat.merge(
+ CppLinkActionConfigs.getCppLinkActionConfigs(
+ CppLinkPlatform.LINUX, features, linkerToolPath),
+ toolchainBuilder);
+ }
+ }
- try {
-
- if (!linkActionsAreConfigured(toolchain)) {
- if (getTargetLibc().equals("macosx")) {
- TextFormat.merge(
- CppLinkActionConfigs.getCppLinkActionConfigs(CppLinkPlatform.MAC), toolchainBuilder);
- } else {
+ if (!features.contains("dependency_file")) {
+ // Gcc options:
+ // -MD turns on .d file output as a side-effect (doesn't imply -E)
+ // -MM[D] enables user includes only, not system includes
+ // -MF <name> specifies the dotd file name
+ // Issues:
+ // -M[M] alone subverts actual .o output (implies -E)
+ // -M[M]D alone breaks some of the .d naming assumptions
+ // This combination gets user and system includes with specified name:
+ // -MD -MF <name>
TextFormat.merge(
- CppLinkActionConfigs.getCppLinkActionConfigs(CppLinkPlatform.LINUX),
+ ""
+ + "feature {"
+ + " name: 'dependency_file'"
+ + " flag_set {"
+ + " action: 'assemble'"
+ + " action: 'preprocess-assemble'"
+ + " action: 'c-compile'"
+ + " action: 'c++-compile'"
+ + " action: 'c++-module-compile'"
+ + " action: 'objc-compile'"
+ + " action: 'objc++-compile'"
+ + " action: 'c++-header-preprocessing'"
+ + " action: 'c++-header-parsing'"
+ + " expand_if_all_available: 'dependency_file'"
+ + " flag_group {"
+ + " flag: '-MD'"
+ + " flag: '-MF'"
+ + " flag: '%{dependency_file}'"
+ + " }"
+ + " }"
+ + "}",
toolchainBuilder);
}
- }
- if (!features.contains("dependency_file")) {
- // Gcc options:
- // -MD turns on .d file output as a side-effect (doesn't imply -E)
- // -MM[D] enables user includes only, not system includes
- // -MF <name> specifies the dotd file name
- // Issues:
- // -M[M] alone subverts actual .o output (implies -E)
- // -M[M]D alone breaks some of the .d naming assumptions
- // This combination gets user and system includes with specified name:
- // -MD -MF <name>
- TextFormat.merge(""
- + "feature {"
- + " name: 'dependency_file'"
- + " flag_set {"
- + " action: 'assemble'"
- + " action: 'preprocess-assemble'"
- + " action: 'c-compile'"
- + " action: 'c++-compile'"
- + " action: 'c++-module-compile'"
- + " action: 'objc-compile'"
- + " action: 'objc++-compile'"
- + " action: 'c++-header-preprocessing'"
- + " action: 'c++-header-parsing'"
- + " expand_if_all_available: 'dependency_file'"
- + " flag_group {"
- + " flag: '-MD'"
- + " flag: '-MF'"
- + " flag: '%{dependency_file}'"
- + " }"
- + " }"
- + "}",
- toolchainBuilder);
- }
- if (!features.contains("random_seed")) {
- // GCC and Clang give randomized names to symbols which are defined in
- // an anonymous namespace but have external linkage. To make
- // computation of these deterministic, we want to override the
- // default seed for the random number generator. It's safe to use
- // any value which differs for all translation units; we use the
- // path to the object file.
- TextFormat.merge(""
- + "feature {"
- + " name: 'random_seed'"
- + " flag_set {"
- + " action: 'c++-compile'"
- + " action: 'c++-module-compile'"
- + " flag_group {"
- + " flag: '-frandom-seed=%{output_file}'"
- + " }"
- + " }"
- + "}",
- toolchainBuilder);
- }
+ if (!features.contains("random_seed")) {
+ // GCC and Clang give randomized names to symbols which are defined in
+ // an anonymous namespace but have external linkage. To make
+ // computation of these deterministic, we want to override the
+ // default seed for the random number generator. It's safe to use
+ // any value which differs for all translation units; we use the
+ // path to the object file.
+ TextFormat.merge(
+ ""
+ + "feature {"
+ + " name: 'random_seed'"
+ + " flag_set {"
+ + " action: 'c++-compile'"
+ + " action: 'c++-module-compile'"
+ + " flag_group {"
+ + " flag: '-frandom-seed=%{output_file}'"
+ + " }"
+ + " }"
+ + "}",
+ toolchainBuilder);
+ }
- if (!features.contains("pic")) {
- TextFormat.merge(""
- + "feature {"
- + " name: 'pic'"
- + " flag_set {"
- + " action: 'c-compile'"
- + " action: 'c++-compile'"
- + " action: 'c++-module-compile'"
- + " action: 'preprocess-assemble'"
- + " expand_if_all_available: 'pic'"
- + " flag_group {"
- + " flag: '-fPIC'"
- + " }"
- + " }"
- + "}",
- toolchainBuilder);
- }
+ if (!features.contains("pic")) {
+ TextFormat.merge(
+ ""
+ + "feature {"
+ + " name: 'pic'"
+ + " flag_set {"
+ + " action: 'c-compile'"
+ + " action: 'c++-compile'"
+ + " action: 'c++-module-compile'"
+ + " action: 'preprocess-assemble'"
+ + " expand_if_all_available: 'pic'"
+ + " flag_group {"
+ + " flag: '-fPIC'"
+ + " }"
+ + " }"
+ + "}",
+ toolchainBuilder);
+ }
- if (!features.contains("per_object_debug_info")) {
- TextFormat.merge(""
- + "feature {"
- + " name: 'per_object_debug_info'"
- + " flag_set {"
- + " action: 'c-compile'"
- + " action: 'c++-compile'"
- + " action: 'assemble'"
- + " action: 'preprocess-assemble'"
- + " expand_if_all_available: 'per_object_debug_info_file'"
- + " flag_group {"
- + " flag: '-gsplit-dwarf'"
- + " }"
- + " }"
- + "}",
- toolchainBuilder);
- }
+ if (!features.contains("per_object_debug_info")) {
+ TextFormat.merge(
+ ""
+ + "feature {"
+ + " name: 'per_object_debug_info'"
+ + " flag_set {"
+ + " action: 'c-compile'"
+ + " action: 'c++-compile'"
+ + " action: 'assemble'"
+ + " action: 'preprocess-assemble'"
+ + " expand_if_all_available: 'per_object_debug_info_file'"
+ + " flag_group {"
+ + " flag: '-gsplit-dwarf'"
+ + " }"
+ + " }"
+ + "}",
+ toolchainBuilder);
+ }
- if (!features.contains("preprocessor_defines")) {
- TextFormat.merge(
- ""
- + "feature {"
- + " name: 'preprocessor_defines'"
- + " flag_set {"
- + " action: 'preprocess-assemble'"
- + " action: 'c-compile'"
- + " action: 'c++-compile'"
- + " action: 'c++-header-parsing'"
- + " action: 'c++-header-preprocessing'"
- + " action: 'c++-module-compile'"
- + " action: 'clif-match'"
- + " flag_group {"
- + " flag: '-D%{preprocessor_defines}'"
- + " }"
- + " }"
- + "}",
- toolchainBuilder);
- }
- if (!features.contains("include_paths")) {
- TextFormat.merge(
- ""
- + "feature {"
- + " name: 'include_paths'"
- + " flag_set {"
- + " action: 'preprocess-assemble'"
- + " action: 'c-compile'"
- + " action: 'c++-compile'"
- + " action: 'c++-header-parsing'"
- + " action: 'c++-header-preprocessing'"
- + " action: 'c++-module-compile'"
- + " action: 'clif-match'"
- + " action: 'objc-compile'"
- + " action: 'objc++-compile'"
- + " flag_group {"
- + " flag: '-iquote'"
- + " flag: '%{quote_include_paths}'"
- + " }"
- + " flag_group {"
- + " flag: '-I%{include_paths}'"
- + " }"
- + " flag_group {"
- + " flag: '-isystem'"
- + " flag: '%{system_include_paths}'"
- + " }"
- + " }"
- + "}",
- toolchainBuilder);
- }
- if (!features.contains("fdo_instrument")) {
- TextFormat.merge(
- ""
- + "feature {"
- + " name: 'fdo_instrument'"
- + " provides: 'profile'"
- + " flag_set {"
- + " action: 'c-compile'"
- + " action: 'c++-compile'"
- + " action: 'c++-link-interface-dynamic-library'"
- + " action: 'c++-link-dynamic-library'"
- + " action: 'c++-link-executable'"
- + " flag_group {"
- + " flag: '-fprofile-generate=%{fdo_instrument_path}'"
- + " flag: '-fno-data-sections'"
- + " }"
- + " }"
- + "}",
- toolchainBuilder);
- }
- if (!features.contains("fdo_optimize")) {
- TextFormat.merge(
- ""
- + "feature {"
- + " name: 'fdo_optimize'"
- + " provides: 'profile'"
- + " flag_set {"
- + " action: 'c-compile'"
- + " action: 'c++-compile'"
- + " expand_if_all_available: 'fdo_profile_path'"
- + " flag_group {"
- + " flag: '-fprofile-use=%{fdo_profile_path}'"
- + " flag: '-Xclang-only=-Wno-profile-instr-unprofiled'"
- + " flag: '-Xclang-only=-Wno-profile-instr-out-of-date'"
- + " flag: '-fprofile-correction'"
- + " }"
- + " }"
- + "}",
- toolchainBuilder);
- }
- if (!features.contains("autofdo")) {
- TextFormat.merge(
- ""
- + "feature {"
- + " name: 'autofdo'"
- + " provides: 'profile'"
- + " flag_set {"
- + " action: 'c-compile'"
- + " action: 'c++-compile'"
- + " expand_if_all_available: 'fdo_profile_path'"
- + " flag_group {"
- + " flag: '-fauto-profile=%{fdo_profile_path}'"
- + " flag: '-fprofile-correction'"
- + " }"
- + " }"
- + "}",
- toolchainBuilder);
- }
- if (!features.contains("lipo")) {
- TextFormat.merge(
- ""
- + "feature {"
- + " name: 'lipo'"
- + " requires { feature: 'autofdo' }"
- + " requires { feature: 'fdo_optimize' }"
- + " requires { feature: 'fdo_instrument' }"
- + " flag_set {"
- + " action: 'c-compile'"
- + " action: 'c++-compile'"
- + " flag_group {"
- + " flag: '-fripa'"
- + " }"
- + " }"
- + "}",
- toolchainBuilder);
- }
- if (!features.contains("coverage")) {
- String compileFlags;
- String linkerFlags;
- if (useLLVMCoverageMap) {
- compileFlags =
- "flag_group {"
- + " flag: '-fprofile-instr-generate'"
- + " flag: '-fcoverage-mapping'"
- + "}";
- linkerFlags =
- " flag_group {"
- + " flag: '-fprofile-instr-generate'"
- + "}";
- } else {
- compileFlags =
- " expand_if_all_available: 'gcov_gcno_file'"
- + "flag_group {"
- + " flag: '-fprofile-arcs'"
- + " flag: '-ftest-coverage'"
- + "}";
- linkerFlags =
- " flag_group {"
- + " flag: '-lgcov'"
- + "}";
+ if (!features.contains("preprocessor_defines")) {
+ TextFormat.merge(
+ ""
+ + "feature {"
+ + " name: 'preprocessor_defines'"
+ + " flag_set {"
+ + " action: 'preprocess-assemble'"
+ + " action: 'c-compile'"
+ + " action: 'c++-compile'"
+ + " action: 'c++-header-parsing'"
+ + " action: 'c++-header-preprocessing'"
+ + " action: 'c++-module-compile'"
+ + " action: 'clif-match'"
+ + " flag_group {"
+ + " flag: '-D%{preprocessor_defines}'"
+ + " }"
+ + " }"
+ + "}",
+ toolchainBuilder);
+ }
+ if (!features.contains("include_paths")) {
+ TextFormat.merge(
+ ""
+ + "feature {"
+ + " name: 'include_paths'"
+ + " flag_set {"
+ + " action: 'preprocess-assemble'"
+ + " action: 'c-compile'"
+ + " action: 'c++-compile'"
+ + " action: 'c++-header-parsing'"
+ + " action: 'c++-header-preprocessing'"
+ + " action: 'c++-module-compile'"
+ + " action: 'clif-match'"
+ + " action: 'objc-compile'"
+ + " action: 'objc++-compile'"
+ + " flag_group {"
+ + " flag: '-iquote'"
+ + " flag: '%{quote_include_paths}'"
+ + " }"
+ + " flag_group {"
+ + " flag: '-I%{include_paths}'"
+ + " }"
+ + " flag_group {"
+ + " flag: '-isystem'"
+ + " flag: '%{system_include_paths}'"
+ + " }"
+ + " }"
+ + "}",
+ toolchainBuilder);
+ }
+ if (!features.contains("fdo_instrument")) {
+ TextFormat.merge(
+ ""
+ + "feature {"
+ + " name: 'fdo_instrument'"
+ + " provides: 'profile'"
+ + " flag_set {"
+ + " action: 'c-compile'"
+ + " action: 'c++-compile'"
+ + " action: 'c++-link-interface-dynamic-library'"
+ + " action: 'c++-link-dynamic-library'"
+ + " action: 'c++-link-executable'"
+ + " flag_group {"
+ + " flag: '-fprofile-generate=%{fdo_instrument_path}'"
+ + " flag: '-fno-data-sections'"
+ + " }"
+ + " }"
+ + "}",
+ toolchainBuilder);
+ }
+ if (!features.contains("fdo_optimize")) {
+ TextFormat.merge(
+ ""
+ + "feature {"
+ + " name: 'fdo_optimize'"
+ + " provides: 'profile'"
+ + " flag_set {"
+ + " action: 'c-compile'"
+ + " action: 'c++-compile'"
+ + " expand_if_all_available: 'fdo_profile_path'"
+ + " flag_group {"
+ + " flag: '-fprofile-use=%{fdo_profile_path}'"
+ + " flag: '-Xclang-only=-Wno-profile-instr-unprofiled'"
+ + " flag: '-Xclang-only=-Wno-profile-instr-out-of-date'"
+ + " flag: '-fprofile-correction'"
+ + " }"
+ + " }"
+ + "}",
+ toolchainBuilder);
+ }
+ if (!features.contains("autofdo")) {
+ TextFormat.merge(
+ ""
+ + "feature {"
+ + " name: 'autofdo'"
+ + " provides: 'profile'"
+ + " flag_set {"
+ + " action: 'c-compile'"
+ + " action: 'c++-compile'"
+ + " expand_if_all_available: 'fdo_profile_path'"
+ + " flag_group {"
+ + " flag: '-fauto-profile=%{fdo_profile_path}'"
+ + " flag: '-fprofile-correction'"
+ + " }"
+ + " }"
+ + "}",
+ toolchainBuilder);
+ }
+ if (!features.contains("lipo")) {
+ TextFormat.merge(
+ ""
+ + "feature {"
+ + " name: 'lipo'"
+ + " requires { feature: 'autofdo' }"
+ + " requires { feature: 'fdo_optimize' }"
+ + " requires { feature: 'fdo_instrument' }"
+ + " flag_set {"
+ + " action: 'c-compile'"
+ + " action: 'c++-compile'"
+ + " flag_group {"
+ + " flag: '-fripa'"
+ + " }"
+ + " }"
+ + "}",
+ toolchainBuilder);
+ }
+ if (!features.contains("coverage")) {
+ String compileFlags;
+ String linkerFlags;
+ if (useLLVMCoverageMap) {
+ compileFlags =
+ "flag_group {"
+ + " flag: '-fprofile-instr-generate'"
+ + " flag: '-fcoverage-mapping'"
+ + "}";
+ linkerFlags = " flag_group {" + " flag: '-fprofile-instr-generate'" + "}";
+ } else {
+ compileFlags =
+ " expand_if_all_available: 'gcov_gcno_file'"
+ + "flag_group {"
+ + " flag: '-fprofile-arcs'"
+ + " flag: '-ftest-coverage'"
+ + "}";
+ linkerFlags = " flag_group {" + " flag: '-lgcov'" + "}";
+ }
+ TextFormat.merge(
+ ""
+ + "feature {"
+ + " name: 'coverage'"
+ + " provides: 'profile'"
+ + " flag_set {"
+ + " action: 'preprocess-assemble'"
+ + " action: 'c-compile'"
+ + " action: 'c++-compile'"
+ + " action: 'c++-header-parsing'"
+ + " action: 'c++-header-preprocessing'"
+ + " action: 'c++-module-compile'"
+ + compileFlags
+ + " }"
+ + " flag_set {"
+ + " action: 'c++-link-interface-dynamic-library'"
+ + " action: 'c++-link-dynamic-library'"
+ + " action: 'c++-link-executable'"
+ + linkerFlags
+ + " }"
+ + "}",
+ toolchainBuilder);
}
- TextFormat.merge(
- ""
- + "feature {"
- + " name: 'coverage'"
- + " provides: 'profile'"
- + " flag_set {"
- + " action: 'preprocess-assemble'"
- + " action: 'c-compile'"
- + " action: 'c++-compile'"
- + " action: 'c++-header-parsing'"
- + " action: 'c++-header-preprocessing'"
- + " action: 'c++-module-compile'"
- + compileFlags
- + " }"
- + " flag_set {"
- + " action: 'c++-link-interface-dynamic-library'"
- + " action: 'c++-link-dynamic-library'"
- + " action: 'c++-link-executable'"
- + linkerFlags
- + " }"
- + "}",
- toolchainBuilder);
+ } catch (ParseException e) {
+ // Can only happen if we change the proto definition without changing our
+ // configuration above.
+ throw new RuntimeException(e);
}
- } catch (ParseException e) {
- // Can only happen if we change the proto definition without changing our configuration above.
- throw new RuntimeException(e);
}
+
+ toolchainBuilder.mergeFrom(toolchain);
return toolchainBuilder.build();
}
@@ -1026,7 +1036,8 @@ public class CppConfiguration extends BuildConfiguration.Fragment {
private static final String SYSROOT_START = "%sysroot%/";
private static final String WORKSPACE_START = "%workspace%/";
private static final String CROSSTOOL_START = "%crosstool_top%/";
- private static final String PACKAGE_START = "%package(", PACKAGE_END = ")%";
+ private static final String PACKAGE_START = "%package(";
+ private static final String PACKAGE_END = ")%";
/**
* Resolve the given include directory.
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 178d0688fb..d6b2c62d94 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
@@ -100,6 +100,18 @@ public class CppLinkActionBuilder {
/** A build variable for the execpath of the output of the linker. */
public static final String OUTPUT_EXECPATH_VARIABLE = "output_execpath";
+ /** A build variable setting if interface library should be generated. */
+ public static final String GENERATE_INTERFACE_LIBRARY_VARIABLE = "generate_interface_library";
+
+ /** A build variable for the path to the interface library builder tool. */
+ public static final String INTERFACE_LIBRARY_BUILDER_VARIABLE = "interface_library_builder_path";
+
+ /** A build variable for the input for the interface library builder tool. */
+ public static final String INTERFACE_LIBRARY_INPUT_VARIABLE = "interface_library_input_path";
+
+ /** A build variable for the path where to generate interface library using the builder tool. */
+ public static final String INTERFACE_LIBRARY_OUTPUT_VARIABLE = "interface_library_output_path";
+
/**
* A build variable that is set to indicate a mostly static linking for which the linked binary
* should be piped to /dev/null.
@@ -320,6 +332,10 @@ public class CppLinkActionBuilder {
public List<String> getLinkstampOptions() {
return this.linkstampOptions;
}
+
+ protected Artifact getInterfaceSoBuilder() {
+ return analysisEnvironment.getEmbeddedToolArtifact(CppRuleClasses.BUILD_INTERFACE_SO);
+ }
/**
* Returns command line options for this link action.
@@ -552,7 +568,9 @@ public class CppLinkActionBuilder {
runtimeLinkerInputs,
null,
linkerParamsFile,
- ltoOutputRootPrefix)
+ ltoOutputRootPrefix,
+ null,
+ null)
: new CppLinkVariablesExtension(
configuration,
linkstampMap,
@@ -561,7 +579,9 @@ public class CppLinkActionBuilder {
runtimeLinkerInputs,
output,
linkerParamsFile,
- PathFragment.EMPTY_FRAGMENT);
+ PathFragment.EMPTY_FRAGMENT,
+ getInterfaceSoBuilder(),
+ interfaceOutput);
variablesExtension.addVariables(buildVariablesBuilder);
for (VariablesExtension extraVariablesExtension : variablesExtensions) {
extraVariablesExtension.addVariables(buildVariablesBuilder);
@@ -612,6 +632,7 @@ public class CppLinkActionBuilder {
.setParamFile(paramFile)
.setToolchain(toolchain)
.setBuildVariables(buildVariables)
+ .setToolPath(getToolPath())
.setFeatureConfiguration(featureConfiguration);
// TODO(b/30228443): Refactor noWholeArchiveInputs into action_configs, and remove this.
@@ -622,9 +643,7 @@ public class CppLinkActionBuilder {
if (!isLTOIndexing) {
linkCommandLineBuilder
.setOutput(output)
- .setInterfaceOutput(interfaceOutput)
.setBuildInfoHeaderArtifacts(buildInfoHeaderArtifacts)
- .setInterfaceSoBuilder(getInterfaceSoBuilder())
.setLinkstamps(linkstampMap)
.setLinkopts(ImmutableList.copyOf(linkopts))
.addLinkstampCompileOptions(linkstampOptions);
@@ -639,6 +658,7 @@ public class CppLinkActionBuilder {
// Compute the set of inputs - we only need stable order here.
NestedSetBuilder<Artifact> dependencyInputsBuilder = NestedSetBuilder.stableOrder();
dependencyInputsBuilder.addTransitive(crosstoolInputs);
+ dependencyInputsBuilder.add(toolchain.getLinkDynamicLibraryTool());
dependencyInputsBuilder.addAll(linkActionInputs);
if (runtimeMiddleman != null) {
dependencyInputsBuilder.add(runtimeMiddleman);
@@ -739,6 +759,26 @@ public class CppLinkActionBuilder {
executionRequirements.build());
}
+ /**
+ * Returns the tool path from feature configuration, if the tool in the configuration is sane, or
+ * builtin tool, if configuration has a dummy value.
+ */
+ private String getToolPath() {
+ if (!featureConfiguration.actionIsConfigured(linkType.getActionName())) {
+ return null;
+ }
+ String toolPath =
+ featureConfiguration
+ .getToolForAction(linkType.getActionName())
+ .getToolPath(cppConfiguration.getCrosstoolTopPathFragment())
+ .getPathString();
+ if (linkType.equals(LinkTargetType.DYNAMIC_LIBRARY)
+ && !featureConfiguration.hasConfiguredLinkerPathInActionConfig()) {
+ toolPath = toolchain.getLinkDynamicLibraryTool().getExecPathString();
+ }
+ return toolPath;
+ }
+
/** The default heuristic on whether we need to use whole-archive for the link. */
private static boolean needWholeArchive(
LinkStaticness staticness,
@@ -809,10 +849,6 @@ public class CppLinkActionBuilder {
return ruleContext.getActionOwner();
}
- protected Artifact getInterfaceSoBuilder() {
- return analysisEnvironment.getEmbeddedToolArtifact(CppRuleClasses.BUILD_INTERFACE_SO);
- }
-
/** Set the crosstool inputs required for the action. */
public CppLinkActionBuilder setCrosstoolInputs(NestedSet<Artifact> inputs) {
this.crosstoolInputs = inputs;
@@ -1196,6 +1232,8 @@ public class CppLinkActionBuilder {
private final Iterable<LinkerInput> linkerInputs;
private final ImmutableList<LinkerInput> runtimeLinkerInputs;
private final Artifact outputArtifact;
+ private final Artifact interfaceLibraryBuilder;
+ private final Artifact interfaceLibraryOutput;
private final Artifact linkerParamsFile;
private final PathFragment ltoOutputRootPrefix;
@@ -1209,13 +1247,17 @@ public class CppLinkActionBuilder {
ImmutableList<LinkerInput> runtimeLinkerInputs,
Artifact output,
Artifact linkerParamsFile,
- PathFragment ltoOutputRootPrefix) {
+ PathFragment ltoOutputRootPrefix,
+ Artifact interfaceLibraryBuilder,
+ Artifact interfaceLibraryOutput) {
this.configuration = configuration;
this.linkstampMap = linkstampMap;
this.needWholeArchive = needWholeArchive;
this.linkerInputs = linkerInputs;
this.runtimeLinkerInputs = runtimeLinkerInputs;
this.outputArtifact = output;
+ this.interfaceLibraryBuilder = interfaceLibraryBuilder;
+ this.interfaceLibraryOutput = interfaceLibraryOutput;
this.linkerParamsFile = linkerParamsFile;
this.ltoOutputRootPrefix = ltoOutputRootPrefix;
@@ -1285,9 +1327,8 @@ public class CppLinkActionBuilder {
}
// output exec path
- if (this.outputArtifact != null) {
- buildVariables.addVariable(
- OUTPUT_EXECPATH_VARIABLE, this.outputArtifact.getExecPathString());
+ if (outputArtifact != null) {
+ buildVariables.addVariable(OUTPUT_EXECPATH_VARIABLE, outputArtifact.getExecPathString());
}
if (!ltoOutputRootPrefix.equals(PathFragment.EMPTY_FRAGMENT)) {
@@ -1303,6 +1344,21 @@ public class CppLinkActionBuilder {
+ ";"
+ configuration.getBinDirectory().getExecPath().getRelative(ltoOutputRootPrefix));
}
+ boolean shouldGenerateInterfaceLibrary =
+ outputArtifact != null
+ && interfaceLibraryBuilder != null
+ && interfaceLibraryOutput != null;
+ buildVariables.addVariable(
+ GENERATE_INTERFACE_LIBRARY_VARIABLE, shouldGenerateInterfaceLibrary ? "yes" : "no");
+ buildVariables.addVariable(
+ INTERFACE_LIBRARY_BUILDER_VARIABLE,
+ shouldGenerateInterfaceLibrary ? interfaceLibraryBuilder.getExecPathString() : "ignored");
+ buildVariables.addVariable(
+ INTERFACE_LIBRARY_INPUT_VARIABLE,
+ shouldGenerateInterfaceLibrary ? outputArtifact.getExecPathString() : "ignored");
+ buildVariables.addVariable(
+ INTERFACE_LIBRARY_OUTPUT_VARIABLE,
+ shouldGenerateInterfaceLibrary ? interfaceLibraryOutput.getExecPathString() : "ignored");
// Variables arising from the toolchain
buildVariables
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionConfigs.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionConfigs.java
index a359350834..dc7b250c0a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionConfigs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionConfigs.java
@@ -15,6 +15,7 @@ package com.google.devtools.build.lib.rules.cpp;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
+import java.util.Set;
/**
* A helper class for creating action_configs for the c++ link action.
@@ -30,7 +31,25 @@ public class CppLinkActionConfigs {
MAC
}
- public static String getCppLinkActionConfigs(CppLinkPlatform platform) {
+ public static String getCppLinkActionConfigs(
+ CppLinkPlatform platform, Set<String> features, String cppLinkDynamicLibraryToolPath) {
+ String cppDynamicLibraryLinkerTool = "";
+ if (!features.contains("dynamic_library_linker_tool")) {
+ cppDynamicLibraryLinkerTool =
+ ""
+ + "feature {"
+ + " name: 'dynamic_library_linker_tool'"
+ + " flag_set {"
+ + " action: 'c++-link-dynamic-library'"
+ + " flag_group {"
+ + " flag: '"
+ + cppLinkDynamicLibraryToolPath
+ + "'"
+ + " }"
+ + " }"
+ + "}";
+ }
+
return Joiner.on("\n")
.join(
ImmutableList.of(
@@ -55,6 +74,8 @@ public class CppLinkActionConfigs {
" tool {",
" tool_path: 'DUMMY_TOOL'",
" }",
+ " implies: 'build_interface_libraries'",
+ " implies: 'dynamic_library_linker_tool'",
" implies: 'symbol_counts'",
" implies: 'shared_flag'",
" implies: 'linkstamps'",
@@ -109,6 +130,22 @@ public class CppLinkActionConfigs {
" implies: 'global_whole_archive_close'",
"}",
"feature {",
+ " name: 'build_interface_libraries'",
+ " flag_set {",
+ " expand_if_all_available: 'generate_interface_library'",
+ " action: 'c++-link-dynamic-library'",
+ " flag_group {",
+ " flag: '%{generate_interface_library}'",
+ " flag: '%{interface_library_builder_path}'",
+ " flag: '%{interface_library_input_path}'",
+ " flag: '%{interface_library_output_path}'",
+ " }",
+ " }",
+ "}",
+ // Order of feature declaration matters, cppDynamicLibraryLinkerTool has to follow
+ // right after build_interface_libraries.
+ cppDynamicLibraryLinkerTool,
+ "feature {",
" name: 'symbol_counts'",
" flag_set {",
" expand_if_all_available: 'symbol_counts_output'",
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 db3ab654fd..27e3e4db99 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
@@ -53,14 +53,13 @@ import javax.annotation.Nullable;
@Immutable
public final class LinkCommandLine extends CommandLine {
private final String actionName;
- private final BuildConfiguration configuration;
+ private final String toolPath;
private final CppConfiguration cppConfiguration;
private final ActionOwner owner;
private final CcToolchainFeatures.Variables variables;
// The feature config can be null for tests.
@Nullable private final FeatureConfiguration featureConfiguration;
@Nullable private final Artifact output;
- @Nullable private final Artifact interfaceOutput;
private final ImmutableList<Artifact> buildInfoHeaderArtifacts;
private final Iterable<? extends LinkerInput> linkerInputs;
private final Iterable<? extends LinkerInput> runtimeInputs;
@@ -77,14 +76,13 @@ public final class LinkCommandLine extends CommandLine {
private final List<String> noWholeArchiveFlags;
@Nullable private final Artifact paramFile;
- @Nullable private final Artifact interfaceSoBuilder;
private LinkCommandLine(
String actionName,
+ String toolPath,
BuildConfiguration configuration,
ActionOwner owner,
Artifact output,
- @Nullable Artifact interfaceOutput,
ImmutableList<Artifact> buildInfoHeaderArtifacts,
Iterable<? extends LinkerInput> linkerInputs,
Iterable<? extends LinkerInput> runtimeInputs,
@@ -100,23 +98,17 @@ public final class LinkCommandLine extends CommandLine {
boolean useTestOnlyFlags,
boolean needWholeArchive,
@Nullable Artifact paramFile,
- Artifact interfaceSoBuilder,
List<String> noWholeArchiveFlags,
CcToolchainFeatures.Variables variables,
@Nullable FeatureConfiguration featureConfiguration) {
this.actionName = actionName;
- this.configuration = Preconditions.checkNotNull(configuration);
+ this.toolPath = toolPath;
this.cppConfiguration = configuration.getFragment(CppConfiguration.class);
this.variables = variables;
this.featureConfiguration = featureConfiguration;
this.owner = Preconditions.checkNotNull(owner);
this.output = output;
- this.interfaceOutput = interfaceOutput;
- if (interfaceOutput != null) {
- Preconditions.checkNotNull(this.output);
- }
-
this.buildInfoHeaderArtifacts = Preconditions.checkNotNull(buildInfoHeaderArtifacts);
this.linkerInputs = Preconditions.checkNotNull(linkerInputs);
this.runtimeInputs = Preconditions.checkNotNull(runtimeInputs);
@@ -135,23 +127,6 @@ public final class LinkCommandLine extends CommandLine {
this.useTestOnlyFlags = useTestOnlyFlags;
this.paramFile = paramFile;
this.noWholeArchiveFlags = noWholeArchiveFlags;
-
- // For now, silently ignore interfaceSoBuilder if we don't build an interface dynamic library.
- this.interfaceSoBuilder =
- ((linkTargetType == LinkTargetType.DYNAMIC_LIBRARY) && (interfaceOutput != null))
- ? Preconditions.checkNotNull(
- interfaceSoBuilder, "cannot build interface dynamic library without builder")
- : null;
- }
-
- /**
- * Returns an interface shared object output artifact produced during linking. This only returns
- * non-null if {@link #getLinkTargetType} is {@code DYNAMIC_LIBRARY} and an interface shared
- * object was requested.
- */
- @Nullable
- public Artifact getInterfaceOutput() {
- return interfaceOutput;
}
@Nullable
@@ -410,17 +385,7 @@ public final class LinkCommandLine extends CommandLine {
break;
case DYNAMIC_LIBRARY:
- if (interfaceOutput != null) {
- argv.add(configuration.getShellExecutable().getPathString());
- argv.add("-c");
- argv.add(
- "build_iface_so=\"$0\"; impl=\"$1\"; iface=\"$2\"; cmd=\"$3\"; shift 3; "
- + "\"$cmd\" \"$@\" && \"$build_iface_so\" \"$impl\" \"$iface\"");
- argv.add(interfaceSoBuilder.getExecPathString());
- argv.add(output.getExecPathString());
- argv.add(interfaceOutput.getExecPathString());
- }
- argv.add(cppConfiguration.getCppExecutable().getPathString());
+ argv.add(toolPath);
argv.addAll(featureConfiguration.getCommandLine(actionName, variables));
argv.addAll(noWholeArchiveFlags);
addToolchainFlags(argv);
@@ -443,11 +408,7 @@ public final class LinkCommandLine extends CommandLine {
// 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)
- .getToolPath(cppConfiguration.getCrosstoolTopPathFragment())
- .getPathString());
+ argv.add(toolPath);
argv.addAll(featureConfiguration.getCommandLine(actionName, variables));
break;
@@ -664,8 +625,8 @@ public final class LinkCommandLine extends CommandLine {
private final ActionOwner owner;
@Nullable private final RuleContext ruleContext;
+ @Nullable private String toolPath;
@Nullable private Artifact output;
- @Nullable private Artifact interfaceOutput;
private ImmutableList<Artifact> buildInfoHeaderArtifacts = ImmutableList.of();
private Iterable<? extends LinkerInput> linkerInputs = ImmutableList.of();
private Iterable<? extends LinkerInput> runtimeInputs = ImmutableList.of();
@@ -680,7 +641,6 @@ public final class LinkCommandLine extends CommandLine {
private boolean useTestOnlyFlags;
private boolean needWholeArchive;
@Nullable private Artifact paramFile;
- @Nullable private Artifact interfaceSoBuilder;
@Nullable private CcToolchainProvider toolchain;
private Variables variables;
private FeatureConfiguration featureConfiguration;
@@ -740,10 +700,10 @@ public final class LinkCommandLine extends CommandLine {
return new LinkCommandLine(
actionName,
+ toolPath,
configuration,
owner,
output,
- interfaceOutput,
buildInfoHeaderArtifacts,
linkerInputs,
runtimeInputs,
@@ -759,7 +719,6 @@ public final class LinkCommandLine extends CommandLine {
useTestOnlyFlags,
needWholeArchive,
paramFile,
- interfaceSoBuilder,
noWholeArchiveFlags,
variables,
featureConfiguration);
@@ -774,9 +733,13 @@ public final class LinkCommandLine extends CommandLine {
return this;
}
- /**
- * Sets the feature configuration for this link action.
- */
+ /** Sets the tool path, with tool being the first thing on the command line */
+ public Builder setToolPath(String toolPath) {
+ this.toolPath = toolPath;
+ return this;
+ }
+
+ /** Sets the feature configuration for this link action. */
public Builder setFeatureConfiguration(FeatureConfiguration featureConfiguration) {
this.featureConfiguration = featureConfiguration;
return this;
@@ -818,16 +781,6 @@ public final class LinkCommandLine extends CommandLine {
}
/**
- * Sets the additional interface output artifact, which is only used for dynamic libraries. The
- * {@link #build} method throws an exception if the target type is not {@link
- * LinkTargetType#DYNAMIC_LIBRARY}.
- */
- public Builder setInterfaceOutput(Artifact interfaceOutput) {
- this.interfaceOutput = interfaceOutput;
- return this;
- }
-
- /**
* Sets the linker options. These are passed to the linker in addition to the other linker
* options like linker inputs, symbol count options, etc. The {@link #build} method throws an
* exception if the linker options are non-empty for a static link (see {@link
@@ -850,16 +803,6 @@ public final class LinkCommandLine extends CommandLine {
}
/**
- * Sets the binary that should be used to create the interface output for a dynamic library.
- * This is ignored unless the target type is {@link LinkTargetType#DYNAMIC_LIBRARY} and an
- * interface output artifact is specified.
- */
- public Builder setInterfaceSoBuilder(Artifact interfaceSoBuilder) {
- this.interfaceSoBuilder = interfaceSoBuilder;
- return this;
- }
-
- /**
* Sets the linkstamps. Linkstamps are additional C++ source files that are compiled as part of
* the link command. The {@link #build} method throws an exception if the linkstamps are
* non-empty for a static link (see {@link LinkTargetType#staticness()}}).