C++: Introduces Starlark API needed for shared library rule
Guarded by --experimental_cc_shared_library flag. This CL introduces incompatible changes to the Starlark API. It exposes LinkerInput which wraps libraries to link, user link flags and additional inputs. Once we are confident about the cc_shared_library rule design and implementation, for any incompatible change here we will introduce an incompatible flag
RELNOTES:none
PiperOrigin-RevId: 278568019
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
index 12e5055..4401db5 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
@@ -22,6 +22,7 @@
import com.google.devtools.build.lib.rules.cpp.CcCompilationContext;
import com.google.devtools.build.lib.rules.cpp.CcCompilationOutputs;
import com.google.devtools.build.lib.rules.cpp.CcLinkingContext;
+import com.google.devtools.build.lib.rules.cpp.CcLinkingContext.LinkerInput;
import com.google.devtools.build.lib.rules.cpp.CcLinkingOutputs;
import com.google.devtools.build.lib.rules.cpp.CcModule;
import com.google.devtools.build.lib.rules.cpp.CcToolchainConfigInfo;
@@ -52,6 +53,7 @@
CcCompilationContext,
CcCompilationOutputs,
CcLinkingOutputs,
+ LinkerInput,
LibraryToLink,
CcLinkingContext,
CcToolchainVariables,
diff --git a/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java
index ac37875..890c9c1 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java
@@ -169,6 +169,19 @@
public boolean experimentalStarlarkUnusedInputsList;
@Option(
+ name = "experimental_cc_shared_library",
+ defaultValue = "false",
+ documentationCategory = OptionDocumentationCategory.STARLARK_SEMANTICS,
+ effectTags = {OptionEffectTag.BUILD_FILE_SEMANTICS, OptionEffectTag.LOADING_AND_ANALYSIS},
+ metadataTags = {
+ OptionMetadataTag.EXPERIMENTAL,
+ },
+ help =
+ "If set to true, rule attributes and Starlark API methods needed for the rule "
+ + "cc_shared_library will be available")
+ public boolean experimentalCcSharedLibrary;
+
+ @Option(
name = "incompatible_bzl_disallow_load_after_statement",
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.STARLARK_SEMANTICS,
@@ -689,6 +702,7 @@
.experimentalPlatformsApi(experimentalPlatformsApi)
.experimentalStarlarkConfigTransitions(experimentalStarlarkConfigTransitions)
.experimentalStarlarkUnusedInputsList(experimentalStarlarkUnusedInputsList)
+ .experimentalCcSharedLibrary(experimentalCcSharedLibrary)
.incompatibleBzlDisallowLoadAfterStatement(incompatibleBzlDisallowLoadAfterStatement)
.incompatibleDepsetIsNotIterable(incompatibleDepsetIsNotIterable)
.incompatibleDepsetUnion(incompatibleDepsetUnion)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingContext.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingContext.java
index 40093f2..248a3f1 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingContext.java
@@ -26,8 +26,11 @@
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.SymbolGenerator;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcLinkingContextApi;
+import com.google.devtools.build.lib.skylarkbuildapi.cpp.LinkerInputApi;
+import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.StarlarkThread;
@@ -152,8 +155,9 @@
/**
* Wraps any input to the linker, be it libraries, linker scripts, linkstamps or linking options.
*/
- public static class LinkerInput {
- // Identifier which target created the LinkerInput. It doesn't have to be unique between
+ @Immutable
+ public static class LinkerInput implements LinkerInputApi<LibraryToLink, Artifact> {
+ // Identifies which target created the LinkerInput. It doesn't have to be unique between
// LinkerInputs.
private final Label owner;
private final ImmutableList<LibraryToLink> libraries;
@@ -174,10 +178,56 @@
this.linkstamps = linkstamps;
}
+ @Override
+ public Label getSkylarkOwner(Location location) throws EvalException {
+ if (owner == null) {
+ throw new EvalException(
+ location,
+ "Owner is null. This means that some target upstream is of a rule type that uses the"
+ + " old API of create_linking_context");
+ }
+ return owner;
+ }
+
public Label getOwner() {
return owner;
}
+ public List<LibraryToLink> getLibraries() {
+ return libraries;
+ }
+
+ @Override
+ public SkylarkList<LibraryToLink> getSkylarkLibrariesToLink(StarlarkThread thread) {
+ return SkylarkList.createImmutable(getLibraries());
+ }
+
+ public List<LinkOptions> getUserLinkFlags() {
+ return userLinkFlags;
+ }
+
+ @Override
+ public SkylarkList<String> getSkylarkUserLinkFlags() {
+ return SkylarkList.createImmutable(
+ getUserLinkFlags().stream()
+ .map(LinkOptions::get)
+ .flatMap(Collection::stream)
+ .collect(ImmutableList.toImmutableList()));
+ }
+
+ public List<Artifact> getNonCodeInputs() {
+ return nonCodeInputs;
+ }
+
+ @Override
+ public SkylarkList<Artifact> getSkylarkNonCodeInputs() {
+ return SkylarkList.createImmutable(getNonCodeInputs());
+ }
+
+ public List<Linkstamp> getLinkstamps() {
+ return linkstamps;
+ }
+
public static Builder builder() {
return new Builder();
}
@@ -337,6 +387,11 @@
}
@Override
+ public SkylarkNestedSet getSkylarkLinkerInputs() {
+ return SkylarkNestedSet.of(LinkerInput.class, linkerInputs);
+ }
+
+ @Override
public SkylarkList<String> getSkylarkUserLinkFlags() {
return SkylarkList.createImmutable(getFlattenedUserLinkFlags());
}
@@ -359,7 +414,7 @@
public NestedSet<LinkOptions> getUserLinkFlags() {
NestedSetBuilder<LinkOptions> userLinkFlags = NestedSetBuilder.linkOrder();
for (LinkerInput linkerInput : linkerInputs) {
- userLinkFlags.addAll(linkerInput.userLinkFlags);
+ userLinkFlags.addAll(linkerInput.getUserLinkFlags());
}
return userLinkFlags.build();
}
@@ -374,7 +429,7 @@
public NestedSet<Linkstamp> getLinkstamps() {
NestedSetBuilder<Linkstamp> linkstamps = NestedSetBuilder.linkOrder();
for (LinkerInput linkerInput : linkerInputs) {
- linkstamps.addAll(linkerInput.linkstamps);
+ linkstamps.addAll(linkerInput.getLinkstamps());
}
return linkstamps.build();
}
@@ -382,7 +437,7 @@
public NestedSet<Artifact> getNonCodeInputs() {
NestedSetBuilder<Artifact> nonCodeInputs = NestedSetBuilder.linkOrder();
for (LinkerInput linkerInput : linkerInputs) {
- nonCodeInputs.addAll(linkerInput.nonCodeInputs);
+ nonCodeInputs.addAll(linkerInput.getNonCodeInputs());
}
return nonCodeInputs.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
index cb7ca03..b77054d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
@@ -39,6 +39,7 @@
import com.google.devtools.build.lib.packages.SkylarkInfo;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.rules.cpp.CcCompilationHelper.CompilationInfo;
+import com.google.devtools.build.lib.rules.cpp.CcLinkingContext.LinkOptions;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ActionConfig;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ArtifactNamePattern;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.EnvEntry;
@@ -87,6 +88,7 @@
CcToolchainProvider,
FeatureConfigurationForStarlark,
CcCompilationContext,
+ CcLinkingContext.LinkerInput,
CcLinkingContext,
LibraryToLink,
CcToolchainVariables,
@@ -564,37 +566,99 @@
}
@Override
- public CcLinkingContext createCcLinkingInfo(
+ public CcLinkingContext.LinkerInput createLinkerInput(
+ Label owner,
Object librariesToLinkObject,
Object userLinkFlagsObject,
- SkylarkList<?> nonCodeInputs,
+ Object nonCodeInputs, // <FileT> expected
+ Location location,
+ StarlarkThread thread)
+ throws EvalException, InterruptedException {
+
+ LinkOptions options =
+ LinkOptions.of(
+ SkylarkNestedSet.getSetFromNoneableParam(
+ userLinkFlagsObject, String.class, "user_link_flags")
+ .toList(),
+ BazelStarlarkContext.from(thread).getSymbolGenerator());
+
+ return CcLinkingContext.LinkerInput.builder()
+ .setOwner(owner)
+ .addLibraries(
+ SkylarkNestedSet.getSetFromNoneableParam(
+ librariesToLinkObject, LibraryToLink.class, "libraries")
+ .toList())
+ .addUserLinkFlags(ImmutableList.of(options))
+ .addNonCodeInputs(
+ SkylarkNestedSet.getSetFromNoneableParam(
+ nonCodeInputs, Artifact.class, "additional_inputs")
+ .toList())
+ .build();
+ }
+
+ @Override
+ public CcLinkingContext createCcLinkingInfo(
+ Object linkerInputs,
+ Object librariesToLinkObject,
+ Object userLinkFlagsObject,
+ Object nonCodeInputsObject,
Location location,
StarlarkThread thread)
throws EvalException {
- @SuppressWarnings("unchecked")
- SkylarkList<LibraryToLink> librariesToLink =
- nullIfNone(librariesToLinkObject, SkylarkList.class);
- @SuppressWarnings("unchecked")
- SkylarkList<String> userLinkFlags = nullIfNone(userLinkFlagsObject, SkylarkList.class);
+ if (EvalUtils.isNullOrNone(linkerInputs)) {
+ @SuppressWarnings("unchecked")
+ SkylarkList<LibraryToLink> librariesToLink =
+ nullIfNone(librariesToLinkObject, SkylarkList.class);
+ @SuppressWarnings("unchecked")
+ SkylarkList<String> userLinkFlags = nullIfNone(userLinkFlagsObject, SkylarkList.class);
- if (librariesToLink != null || userLinkFlags != null) {
+ if (librariesToLink != null || userLinkFlags != null) {
+ CcLinkingContext.Builder ccLinkingContextBuilder = CcLinkingContext.builder();
+ // TODO(b/135146460): Old API, no support for shared library, linker input won't have
+ // labels.
+ if (librariesToLink != null) {
+ ccLinkingContextBuilder.addLibraries(librariesToLink.getImmutableList());
+ }
+ if (userLinkFlags != null) {
+ ccLinkingContextBuilder.addUserLinkFlags(
+ ImmutableList.of(
+ CcLinkingContext.LinkOptions.of(
+ userLinkFlags.getImmutableList(),
+ BazelStarlarkContext.from(thread).getSymbolGenerator())));
+ }
+ @SuppressWarnings("unchecked")
+ SkylarkList<String> nonCodeInputs = nullIfNone(nonCodeInputsObject, SkylarkList.class);
+ if (nonCodeInputs != null) {
+ ccLinkingContextBuilder.addNonCodeInputs(
+ nonCodeInputs.getContents(Artifact.class, "additional_inputs"));
+ }
+ return ccLinkingContextBuilder.build();
+ }
+
+ throw new EvalException(location, "Must pass libraries_to_link, user_link_flags or both.");
+ } else {
CcLinkingContext.Builder ccLinkingContextBuilder = CcLinkingContext.builder();
- if (librariesToLink != null) {
- ccLinkingContextBuilder.addLibraries(librariesToLink.getImmutableList());
+ ccLinkingContextBuilder.addTransitiveLinkerInputs(
+ SkylarkNestedSet.getSetFromNoneableParam(
+ linkerInputs, CcLinkingContext.LinkerInput.class, "linker_inputs"));
+
+ @SuppressWarnings("unchecked")
+ SkylarkList<LibraryToLink> librariesToLink =
+ nullIfNone(librariesToLinkObject, SkylarkList.class);
+ @SuppressWarnings("unchecked")
+ SkylarkList<String> userLinkFlags = nullIfNone(userLinkFlagsObject, SkylarkList.class);
+ @SuppressWarnings("unchecked")
+ SkylarkList<String> nonCodeInputs = nullIfNone(nonCodeInputsObject, SkylarkList.class);
+
+ if (librariesToLink != null || userLinkFlags != null || nonCodeInputs != null) {
+ throw new EvalException(
+ location,
+ "If you pass linker_inputs you are using the new API. "
+ + "Just pass linker_inputs. Do not mix old and new API parameters.");
}
- if (userLinkFlags != null) {
- ccLinkingContextBuilder.addUserLinkFlags(
- ImmutableList.of(
- CcLinkingContext.LinkOptions.of(
- userLinkFlags.getImmutableList(),
- BazelStarlarkContext.from(thread).getSymbolGenerator())));
- }
- ccLinkingContextBuilder.addNonCodeInputs(
- nonCodeInputs.getContents(Artifact.class, "additional_inputs"));
+
return ccLinkingContextBuilder.build();
}
-
- throw new EvalException(location, "Must pass libraries_to_link, user_link_flags or both.");
}
// TODO(b/65151735): Remove when cc_flags is entirely from features.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/LibraryToLink.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/LibraryToLink.java
index 44e4322..e440932 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/LibraryToLink.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/LibraryToLink.java
@@ -14,11 +14,13 @@
// limitations under the License.
import com.google.auto.value.AutoValue;
+import com.google.auto.value.AutoValue.CopyAnnotations;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.LibraryToLinkApi;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
@@ -34,6 +36,8 @@
* dynamic params for executable and dynamic params for dynamic library.
*/
@AutoValue
+@Immutable
+@CopyAnnotations
public abstract class LibraryToLink implements LibraryToLinkApi<Artifact> {
public Artifact getDynamicLibraryForRuntimeOrNull(boolean linkingStatically) {
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BUILD b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BUILD
index 6ef3972..9e98133 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BUILD
@@ -24,6 +24,7 @@
"//src/main/java/com/google/devtools/build/lib:events",
"//src/main/java/com/google/devtools/build/lib:skylarkinterface",
"//src/main/java/com/google/devtools/build/lib:syntax",
+ "//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
"//src/main/java/com/google/devtools/build/lib/skylarkbuildapi",
"//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/go",
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
index 41bdb0f..57f57ef 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
@@ -42,6 +42,7 @@
CompilationContextT extends CcCompilationContextApi,
CompilationOutputsT extends CcCompilationOutputsApi<FileT>,
LinkingOutputsT extends CcLinkingOutputsApi<FileT>,
+ LinkerInputT extends LinkerInputApi<LibraryToLinkT, FileT>,
LibraryToLinkT extends LibraryToLinkApi<FileT>,
LinkingContextT extends CcLinkingContextApi<FileT>,
CcToolchainVariablesT extends CcToolchainVariablesApi,
@@ -52,6 +53,7 @@
CcToolchainProviderT,
FeatureConfigurationT,
CompilationContextT,
+ LinkerInputT,
LinkingContextT,
LibraryToLinkT,
CcToolchainVariablesT,
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcBootstrap.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcBootstrap.java
index 5d1cb65..6950dac 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcBootstrap.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcBootstrap.java
@@ -32,6 +32,8 @@
? extends CcToolchainProviderApi<? extends FeatureConfigurationApi>,
? extends FeatureConfigurationApi,
? extends CcCompilationContextApi,
+ ? extends
+ LinkerInputApi<? extends LibraryToLinkApi<? extends FileApi>, ? extends FileApi>,
? extends CcLinkingContextApi<? extends FileApi>,
? extends LibraryToLinkApi<? extends FileApi>,
? extends CcToolchainVariablesApi,
@@ -54,6 +56,8 @@
? extends CcToolchainProviderApi<? extends FeatureConfigurationApi>,
? extends FeatureConfigurationApi,
? extends CcCompilationContextApi,
+ ? extends
+ LinkerInputApi<? extends LibraryToLinkApi<? extends FileApi>, ? extends FileApi>,
? extends CcLinkingContextApi<? extends FileApi>,
? extends LibraryToLinkApi<? extends FileApi>,
? extends CcToolchainVariablesApi,
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingContextApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingContextApi.java
index 0973a49..bdba1bc 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingContextApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcLinkingContextApi.java
@@ -20,6 +20,7 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
import com.google.devtools.build.lib.syntax.StarlarkThread;
/** Wrapper for every C++ linking provider. */
@@ -50,4 +51,11 @@
doc = "Returns the depset of additional inputs, e.g.: linker scripts.",
structField = true)
SkylarkNestedSet getSkylarkNonCodeInputs();
+
+ @SkylarkCallable(
+ name = "linker_inputs",
+ doc = "Returns the depset of linker inputs.",
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_CC_SHARED_LIBRARY,
+ structField = true)
+ SkylarkNestedSet getSkylarkLinkerInputs();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
index 2240e74..b3c2a8d 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.skylarkbuildapi.cpp;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkbuildapi.FileApi;
import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi;
@@ -29,6 +30,7 @@
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
import com.google.devtools.build.lib.syntax.StarlarkThread;
/** Utilites related to C++ support. */
@@ -41,8 +43,9 @@
CcToolchainProviderT extends CcToolchainProviderApi,
FeatureConfigurationT extends FeatureConfigurationApi,
CompilationContextT extends CcCompilationContextApi,
+ LinkerInputT extends LinkerInputApi<LibraryToLinkT, FileT>,
LinkingContextT extends CcLinkingContextApi,
- LibraryToLinkT extends LibraryToLinkApi,
+ LibraryToLinkT extends LibraryToLinkApi<FileT>,
CcToolchainVariablesT extends CcToolchainVariablesApi,
SkylarkRuleContextT extends SkylarkRuleContextApi,
CcToolchainConfigInfoT extends CcToolchainConfigInfoApi,
@@ -600,19 +603,29 @@
throws EvalException, InterruptedException;
@SkylarkCallable(
- name = "create_linking_context",
+ name = "create_linker_input",
doc = "Creates a <code>LinkingContext</code>.",
useLocation = true,
useStarlarkThread = true,
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_CC_SHARED_LIBRARY,
parameters = {
@Param(
- name = "libraries_to_link",
+ name = "owner",
+ doc = "List of <code>LibraryToLink</code>.",
+ positional = false,
+ named = true,
+ type = Label.class),
+ @Param(
+ name = "libraries",
doc = "List of <code>LibraryToLink</code>.",
positional = false,
named = true,
noneable = true,
defaultValue = "None",
- type = SkylarkList.class),
+ allowedTypes = {
+ @ParamType(type = NoneType.class),
+ @ParamType(type = SkylarkNestedSet.class)
+ }),
@Param(
name = "user_link_flags",
doc = "List of user link flags passed as strings.",
@@ -620,19 +633,87 @@
named = true,
noneable = true,
defaultValue = "None",
- type = SkylarkList.class),
+ allowedTypes = {
+ @ParamType(type = NoneType.class),
+ @ParamType(type = SkylarkNestedSet.class)
+ }),
@Param(
name = "additional_inputs",
doc = "For additional inputs to the linking action, e.g.: linking scripts.",
positional = false,
named = true,
- defaultValue = "[]",
- type = SkylarkList.class),
+ noneable = true,
+ defaultValue = "None",
+ allowedTypes = {
+ @ParamType(type = NoneType.class),
+ @ParamType(type = SkylarkNestedSet.class)
+ }),
})
- LinkingContextT createCcLinkingInfo(
+ LinkerInputT createLinkerInput(
+ Label owner,
Object librariesToLinkObject,
Object userLinkFlagsObject,
- SkylarkList<?> nonCodeInputs, // <FileT> expected
+ Object nonCodeInputs,
+ Location location,
+ StarlarkThread thread)
+ throws EvalException, InterruptedException;
+
+ @SkylarkCallable(
+ name = "create_linking_context",
+ doc = "Creates a <code>LinkingContext</code>.",
+ useLocation = true,
+ useStarlarkThread = true,
+ parameters = {
+ @Param(
+ name = "linker_inputs",
+ doc = "Depset of <code>LinkerInput</code>.",
+ positional = false,
+ named = true,
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_CC_SHARED_LIBRARY,
+ valueWhenDisabled = "None",
+ allowedTypes = {
+ @ParamType(type = NoneType.class),
+ @ParamType(type = SkylarkNestedSet.class)
+ }),
+ @Param(
+ name = "libraries_to_link",
+ doc = "List of <code>LibraryToLink</code>.",
+ positional = false,
+ named = true,
+ noneable = true,
+ defaultValue = "None",
+ allowedTypes = {
+ @ParamType(type = NoneType.class),
+ @ParamType(type = SkylarkList.class)
+ }),
+ @Param(
+ name = "user_link_flags",
+ doc = "List of user link flags passed as strings.",
+ positional = false,
+ named = true,
+ noneable = true,
+ defaultValue = "None",
+ allowedTypes = {
+ @ParamType(type = NoneType.class),
+ @ParamType(type = SkylarkList.class)
+ }),
+ @Param(
+ name = "additional_inputs",
+ doc = "For additional inputs to the linking action, e.g.: linking scripts.",
+ positional = false,
+ named = true,
+ noneable = true,
+ defaultValue = "None",
+ allowedTypes = {
+ @ParamType(type = NoneType.class),
+ @ParamType(type = SkylarkList.class)
+ }),
+ })
+ LinkingContextT createCcLinkingInfo(
+ Object linkerInputs,
+ Object librariesToLinkObject,
+ Object userLinkFlagsObject,
+ Object nonCodeInputs, // <FileT> expected
Location location,
StarlarkThread thread)
throws EvalException, InterruptedException;
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkerInputApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkerInputApi.java
new file mode 100644
index 0000000..10371d6
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkerInputApi.java
@@ -0,0 +1,66 @@
+// Copyright 2018 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.skylarkbuildapi.cpp;
+
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkbuildapi.FileApi;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
+import com.google.devtools.build.lib.syntax.StarlarkThread;
+
+/** Either libraries, flags or other files that may be passed to the linker as inputs. */
+@SkylarkModule(
+ name = "LinkerInput",
+ category = SkylarkModuleCategory.BUILTIN,
+ doc = "Either libraries, flags or other files that may be passed to the linker as inputs.")
+public interface LinkerInputApi<
+ LibraryToLinkT extends LibraryToLinkApi<FileT>, FileT extends FileApi> {
+ @SkylarkCallable(
+ name = "owner",
+ doc = "Returns the owner of this LinkerInput.",
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_CC_SHARED_LIBRARY,
+ useLocation = true,
+ structField = true)
+ Label getSkylarkOwner(Location location) throws EvalException;
+
+ @SkylarkCallable(
+ name = "user_link_flags",
+ doc = "Returns the list of user link flags passed as strings.",
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_CC_SHARED_LIBRARY,
+ structField = true)
+ SkylarkList<String> getSkylarkUserLinkFlags();
+
+ @SkylarkCallable(
+ name = "libraries",
+ doc =
+ "Returns the depset of <code>LibraryToLink</code>. May return a list but this is "
+ + "deprecated. See #8118.",
+ structField = true,
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_CC_SHARED_LIBRARY,
+ useStarlarkThread = true)
+ SkylarkList<LibraryToLinkT> getSkylarkLibrariesToLink(StarlarkThread thread);
+
+ @SkylarkCallable(
+ name = "additional_inputs",
+ doc = "Returns the depset of additional inputs, e.g.: linker scripts.",
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_CC_SHARED_LIBRARY,
+ structField = true)
+ SkylarkList<FileT> getSkylarkNonCodeInputs();
+}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java b/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java
index 2bfbf2f..ef5e224 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java
@@ -59,6 +59,7 @@
StarlarkSemantics::experimentalStarlarkConfigTransitions),
EXPERIMENTAL_STARLARK_UNUSED_INPUTS_LIST(
StarlarkSemantics::experimentalStarlarkUnusedInputsList),
+ EXPERIMENTAL_CC_SHARED_LIBRARY(StarlarkSemantics::experimentalCcSharedLibrary),
INCOMPATIBLE_DISABLE_DEPSET_INPUTS(StarlarkSemantics::incompatibleDisableDepsetItems),
INCOMPATIBLE_NO_OUTPUT_ATTR_DEFAULT(StarlarkSemantics::incompatibleNoOutputAttrDefault),
INCOMPATIBLE_NO_RULE_OUTPUTS_PARAM(StarlarkSemantics::incompatibleNoRuleOutputsParam),
@@ -149,6 +150,8 @@
public abstract boolean experimentalStarlarkUnusedInputsList();
+ public abstract boolean experimentalCcSharedLibrary();
+
public abstract boolean incompatibleBzlDisallowLoadAfterStatement();
public abstract boolean incompatibleDepsetIsNotIterable();
@@ -263,6 +266,7 @@
.experimentalPlatformsApi(false)
.experimentalStarlarkConfigTransitions(true)
.experimentalStarlarkUnusedInputsList(true)
+ .experimentalCcSharedLibrary(false)
.incompatibleBzlDisallowLoadAfterStatement(true)
.incompatibleDepsetIsNotIterable(true)
.incompatibleDepsetUnion(true)
@@ -326,6 +330,8 @@
public abstract Builder experimentalStarlarkUnusedInputsList(boolean value);
+ public abstract Builder experimentalCcSharedLibrary(boolean value);
+
public abstract Builder incompatibleBzlDisallowLoadAfterStatement(boolean value);
public abstract Builder incompatibleDepsetIsNotIterable(boolean value);
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/BUILD b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/BUILD
index dab772e..f02e942 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/BUILD
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/BUILD
@@ -18,6 +18,7 @@
"//src/main/java/com/google/devtools/build/lib:events",
"//src/main/java/com/google/devtools/build/lib:skylarkinterface",
"//src/main/java/com/google/devtools/build/lib:syntax",
+ "//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
"//src/main/java/com/google/devtools/build/lib/skylarkbuildapi",
"//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp",
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
index f049b20..fdede8c 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.skydoc.fakebuildapi.cpp;
import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkbuildapi.FileApi;
import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi;
@@ -32,6 +33,7 @@
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcToolchainVariablesApi;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.FeatureConfigurationApi;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.LibraryToLinkApi;
+import com.google.devtools.build.lib.skylarkbuildapi.cpp.LinkerInputApi;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
@@ -50,6 +52,7 @@
CcCompilationContextApi,
CcCompilationOutputsApi<FileApi>,
CcLinkingOutputsApi<FileApi>,
+ LinkerInputApi<LibraryToLinkApi<FileApi>, FileApi>,
LibraryToLinkApi<FileApi>,
CcLinkingContextApi<FileApi>,
CcToolchainVariablesApi,
@@ -153,10 +156,22 @@
}
@Override
- public CcLinkingContextApi createCcLinkingInfo(
+ public LinkerInputApi<LibraryToLinkApi<FileApi>, FileApi> createLinkerInput(
+ Label owner,
Object librariesToLinkObject,
Object userLinkFlagsObject,
- SkylarkList<?> nonCodeInputs,
+ Object nonCodeInputs,
+ Location location,
+ StarlarkThread thread) {
+ return null;
+ }
+
+ @Override
+ public CcLinkingContextApi createCcLinkingInfo(
+ Object linkerInputs,
+ Object librariesToLinkObject,
+ Object userLinkFlagsObject,
+ Object nonCodeInputs,
Location location,
StarlarkThread thread) {
return null;
diff --git a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
index b3b1af5..98359fa 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
@@ -132,6 +132,7 @@
"--experimental_starlark_config_transitions=" + rand.nextBoolean(),
"--experimental_starlark_unused_inputs_list=" + rand.nextBoolean(),
"--incompatible_allow_tags_propagation=" + rand.nextBoolean(),
+ "--experimental_cc_shared_library=" + rand.nextBoolean(),
"--incompatible_bzl_disallow_load_after_statement=" + rand.nextBoolean(),
"--incompatible_depset_for_libraries_to_link_getter=" + rand.nextBoolean(),
"--incompatible_depset_is_not_iterable=" + rand.nextBoolean(),
@@ -187,6 +188,7 @@
.experimentalStarlarkConfigTransitions(rand.nextBoolean())
.experimentalStarlarkUnusedInputsList(rand.nextBoolean())
.experimentalAllowTagsPropagation(rand.nextBoolean())
+ .experimentalCcSharedLibrary(rand.nextBoolean())
.incompatibleBzlDisallowLoadAfterStatement(rand.nextBoolean())
.incompatibleDepsetForLibrariesToLinkGetter(rand.nextBoolean())
.incompatibleDepsetIsNotIterable(rand.nextBoolean())
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
index 6ac4506..30fc1ee 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
@@ -1249,6 +1249,7 @@
CppRuleClasses.TARGETS_WINDOWS,
CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
doTestCcLinkingContext(
+ /* experimentalCcSharedLibrary= */ false,
ImmutableList.of("a.a", "libdep2.a", "b.a", "c.a", "d.a", "libdep1.a"),
ImmutableList.of("a.pic.a", "b.pic.a", "c.pic.a", "e.pic.a"),
ImmutableList.of("a.so", "libdep2.so", "b.so", "e.so", "libdep1.so"));
@@ -1266,6 +1267,25 @@
CppRuleClasses.SUPPORTS_PIC,
CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
doTestCcLinkingContext(
+ /* experimentalCcSharedLibrary= */ false,
+ ImmutableList.of("a.a", "b.a", "c.a", "d.a"),
+ ImmutableList.of("a.pic.a", "libdep2.a", "b.pic.a", "c.pic.a", "e.pic.a", "libdep1.a"),
+ ImmutableList.of("a.so", "liba_Slibdep2.so", "b.so", "e.so", "liba_Slibdep1.so"));
+ }
+
+ @Test
+ public void testCcLinkingContextForExperimentalCcSharedLibrary() throws Exception {
+ AnalysisMock.get()
+ .ccSupport()
+ .setupCcToolchainConfig(
+ mockToolsConfig,
+ CcToolchainConfig.builder()
+ .withFeatures(
+ CppRuleClasses.PIC,
+ CppRuleClasses.SUPPORTS_PIC,
+ CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
+ doTestCcLinkingContext(
+ /* experimentalCcSharedLibrary= */ true,
ImmutableList.of("a.a", "b.a", "c.a", "d.a"),
ImmutableList.of("a.pic.a", "libdep2.a", "b.pic.a", "c.pic.a", "e.pic.a", "libdep1.a"),
ImmutableList.of("a.so", "liba_Slibdep2.so", "b.so", "e.so", "liba_Slibdep1.so"));
@@ -1310,15 +1330,19 @@
.containsExactly("a.so", "liba_Slibdep2.so", "b.so", "e.so", "liba_Slibdep1.so");
}
- @Deprecated
private void doTestCcLinkingContext(
+ boolean experimentalCcSharedLibrary,
List<String> staticLibraryList,
List<String> picStaticLibraryList,
List<String> dynamicLibraryList)
throws Exception {
useConfiguration("--features=-supports_interface_shared_libraries");
setSkylarkSemanticsOptions("--incompatible_depset_for_libraries_to_link_getter");
- setUpCcLinkingContextTest();
+ if (experimentalCcSharedLibrary) {
+ setUpCcLinkingContextTestForExperimentalCcSharedLibrary();
+ } else {
+ setUpCcLinkingContextTest();
+ }
ConfiguredTarget a = getConfiguredTarget("//a:a");
StructImpl info = ((StructImpl) getMyInfoFromTarget(a).getValue("info"));
@@ -1493,6 +1517,134 @@
");");
}
+ // This test should replace the old linking context test when the old API is deprecated.
+ private void setUpCcLinkingContextTestForExperimentalCcSharedLibrary() throws Exception {
+ setSkylarkSemanticsOptions("--experimental_cc_shared_library");
+ scratch.file(
+ "a/BUILD",
+ "load('//tools/build_defs/cc:rule.bzl', 'crule')",
+ "cc_binary(name='bin',",
+ " deps = [':a'],",
+ ")",
+ "crule(name='a',",
+ " static_library = 'a.a',",
+ " pic_static_library = 'a.pic.a',",
+ " dynamic_library = 'a.so',",
+ " interface_library = 'a.ifso',",
+ " user_link_flags = ['-la', '-lc2'],",
+ " alwayslink = True,",
+ " deps = [':c', ':dep2', ':b'],",
+ ")",
+ "crule(name='b',",
+ " static_library = 'b.a',",
+ " pic_static_library = 'b.pic.a',",
+ " dynamic_library = 'b.so',",
+ " deps = [':c', ':d'],",
+ " additional_inputs = ['b.lds'],",
+ ")",
+ "crule(name='c',",
+ " static_library = 'c.a',",
+ " pic_static_library = 'c.pic.a',",
+ " user_link_flags = ['-lc1', '-lc2'],",
+ ")",
+ "crule(name='d',",
+ " static_library = 'd.a',",
+ " alwayslink = True,",
+ " deps = [':e'],",
+ " additional_inputs = ['d.lds'],",
+ ")",
+ "crule(name='e',",
+ " pic_static_library = 'e.pic.a',",
+ " dynamic_library = 'e.so',",
+ " deps = [':dep1'],",
+ ")",
+ "cc_toolchain_alias(name='alias')",
+ "cc_library(",
+ " name = 'dep1',",
+ " srcs = ['dep1.cc'],",
+ " hdrs = ['dep1.h'],",
+ " linkopts = ['-DEP1_LINKOPT'],",
+ ")",
+ "cc_library(",
+ " name = 'dep2',",
+ " srcs = ['dep2.cc'],",
+ " hdrs = ['dep2.h'],",
+ " linkopts = ['-DEP2_LINKOPT'],",
+ ")");
+ scratch.file("a/lib.a", "");
+ scratch.file("a/lib.so", "");
+ scratch.overwriteFile("tools/build_defs/cc/BUILD", "");
+ scratch.file(
+ "tools/build_defs/cc/rule.bzl",
+ "load('//myinfo:myinfo.bzl', 'MyInfo')",
+ "top_linking_context_smoke = cc_common.create_linking_context(linker_inputs=depset([]))",
+ "def _create(ctx, feature_configuration, static_library, pic_static_library,",
+ " dynamic_library, interface_library, alwayslink):",
+ " return cc_common.create_library_to_link(",
+ " actions=ctx.actions, feature_configuration=feature_configuration, ",
+ " cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo], ",
+ " static_library=static_library, pic_static_library=pic_static_library,",
+ " dynamic_library=dynamic_library, interface_library=interface_library,",
+ " alwayslink=alwayslink)",
+ "def _impl(ctx):",
+ " toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
+ " feature_configuration = cc_common.configure_features(",
+ " ctx = ctx,",
+ " cc_toolchain = toolchain,",
+ " )",
+ " library_to_link = _create(ctx, feature_configuration, ctx.file.static_library, ",
+ " ctx.file.pic_static_library, ctx.file.dynamic_library, ctx.file.interface_library,",
+ " ctx.attr.alwayslink)",
+ " linker_input = cc_common.create_linker_input(",
+ " owner=ctx.label,",
+ " libraries=depset([library_to_link]),",
+ " user_link_flags=depset(ctx.attr.user_link_flags),",
+ " additional_inputs=depset(ctx.files.additional_inputs))",
+ " linking_context = cc_common.create_linking_context(",
+ " linker_inputs=depset([linker_input]))",
+ " cc_infos = [CcInfo(linking_context=linking_context)]",
+ " for dep in ctx.attr.deps:",
+ " cc_infos.append(dep[CcInfo])",
+ " merged_cc_info = cc_common.merge_cc_infos(cc_infos=cc_infos)",
+ " result_linker_input = merged_cc_info.linking_context.linker_inputs.to_list()[0]",
+ " user_link_flags= []",
+ " additional_inputs = []",
+ " libraries = []",
+ " for linker_input in merged_cc_info.linking_context.linker_inputs.to_list():",
+ " user_link_flags.extend(linker_input.user_link_flags)",
+ " additional_inputs.extend(linker_input.additional_inputs)",
+ " libraries.extend(linker_input.libraries)",
+ " return [",
+ " MyInfo(",
+ " info = struct(",
+ " cc_info = merged_cc_info,",
+ " user_link_flags = user_link_flags,",
+ " additional_inputs = depset(direct=additional_inputs),",
+ " libraries_to_link = depset(direct=libraries),",
+ " static_library = library_to_link.static_library,",
+ " pic_static_library = library_to_link.pic_static_library,",
+ " dynamic_library = library_to_link.dynamic_library,",
+ " interface_library = library_to_link.interface_library,",
+ " alwayslink = library_to_link.alwayslink),",
+ " ),",
+ " merged_cc_info]",
+ "crule = rule(",
+ " _impl,",
+ " attrs = { ",
+ " 'user_link_flags' : attr.string_list(),",
+ " 'additional_inputs': attr.label_list(allow_files=True),",
+ " 'static_library': attr.label(allow_single_file=True),",
+ " 'pic_static_library': attr.label(allow_single_file=True),",
+ " 'dynamic_library': attr.label(allow_single_file=True),",
+ " 'interface_library': attr.label(allow_single_file=True),",
+ " 'alwayslink': attr.bool(),",
+ " '_cc_toolchain': attr.label(default=Label('//a:alias')),",
+ " 'deps': attr.label_list(),",
+ " },",
+ " fragments = ['cpp'],",
+ ");");
+ }
+
private void loadCcToolchainConfigLib() throws IOException {
scratch.appendFile("tools/cpp/BUILD", "");
scratch.overwriteFile(