Add new global attribute: applicable_licenses
- Package level default with default_applicable_licenses
- guarded by --incompatible_applicable_licenses (default true for Blaze, false for Bazel)
Import features:
- applicable_licenses is not configurable. Software does not get a different
license in different environments. The license it is provided under dictates
what type of environments you may use it in.
- applicable_licenses is exempt from compatible_with checks. For the same
reason.
Since there is currently no actual behavior within Bazel, the test cases
are located with @rules_license. In the future, we will add provider
checking to applicable_licenses. (b/148601291), at which point there
must be positive and negative tests alongside the Bazel code.
RELNOTES:
Add new global attribute: applicable_licenses
- Package level default with default_applicable_licenses
- guarded by --incompatible_applicable_licenses (default true for Blaze, false for Bazel)
- In support of https://docs.google.com/document/d/1uwBuhAoBNrw8tmFs-NxlssI6VRolidGYdYqagLqHWt8/edit#
PiperOrigin-RevId: 296042678
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
index 18daf4d..53ce39a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
@@ -331,7 +331,14 @@
"special logic for constraints and select: see ConstraintSemantics"))
.add(
attr(RuleClass.CONFIG_SETTING_DEPS_ATTRIBUTE, LABEL_LIST)
- .nonconfigurable("stores configurability keys"));
+ .nonconfigurable("stores configurability keys"))
+ .add(
+ attr(RuleClass.APPLICABLE_LICENSES_ATTR, LABEL_LIST)
+ .cfg(HostTransition.createFactory())
+ .allowedFileTypes(FileTypeSet.NO_FILE)
+ // TODO(b/148601291): Require provider to be "LicenseInfo".
+ .dontCheckConstraints()
+ .nonconfigurable("applicable_licenses is not configurable"));
}
public static RuleClass.Builder nameAttribute(RuleClass.Builder builder) {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
index 61daebd..9433b26 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
@@ -482,6 +482,14 @@
if (toolchainContext != null) {
outgoingLabels.putAll(TOOLCHAIN_DEPENDENCY, toolchainContext.resolvedToolchainLabels());
}
+
+ if (!rule.isAttributeValueExplicitlySpecified(RuleClass.APPLICABLE_LICENSES_ATTR)) {
+ addExplicitDeps(
+ outgoingLabels,
+ rule,
+ RuleClass.APPLICABLE_LICENSES_ATTR,
+ rule.getPackage().getDefaultApplicableLicenses());
+ }
}
private void resolveAttributes(
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Package.java b/src/main/java/com/google/devtools/build/lib/packages/Package.java
index 45db928..5ae743e 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Package.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Package.java
@@ -167,6 +167,9 @@
*/
private ImmutableList<Label> skylarkFileDependencies;
+ /** The package's default "applicable_licenses" attribute. */
+ private Set<Label> defaultApplicableLicenses = ImmutableSet.of();
+
/**
* The package's default "licenses" and "distribs" attributes, as specified
* in calls to licenses() and distribs() in the BUILD file.
@@ -296,6 +299,14 @@
}
/**
+ * Sets the default 'applicable_licenses" value for this package attribute when not explicitly
+ * specified by the rule.
+ */
+ private void setDefaultApplicableLicenses(Set<Label> licenses) {
+ defaultApplicableLicenses = licenses;
+ }
+
+ /**
* Sets the default value to use for a rule's {@link RuleClass#COMPATIBLE_ENVIRONMENT_ATTR}
* attribute when not explicitly specified by the rule.
*/
@@ -659,6 +670,11 @@
return defaultVisibilitySet;
}
+ /** Gets the licenses list for the default applicable_licenses declared by this package. */
+ public Set<Label> getDefaultApplicableLicenses() {
+ return defaultApplicableLicenses;
+ }
+
/**
* Gets the parsed license object for the default license
* declared by this package.
@@ -830,6 +846,7 @@
@Nullable private IOException ioException = null;
private boolean containsErrors = false;
+ private ImmutableList<Label> defaultApplicableLicenses = ImmutableList.of();
private License defaultLicense = License.NO_LICENSE;
private Set<License.DistributionType> defaultDistributionSet = License.DEFAULT_DISTRIB;
@@ -1149,6 +1166,23 @@
}
/**
+ * Sets the default value to use for a rule's {@link RuleClass#APPLICABLE_LICENSES_ATTR}
+ * attribute when not explicitly specified by the rule. Records a package error if any labels
+ * are duplicated.
+ */
+ void setDefaultApplicableLicenses(List<Label> licenses, String attrName, Location location) {
+ if (!checkForDuplicateLabels(
+ licenses, "package " + pkg.getName(), attrName, location, builderEventHandler)) {
+ setContainsErrors();
+ }
+ pkg.setDefaultApplicableLicenses(ImmutableSet.copyOf(licenses));
+ }
+
+ ImmutableList<Label> getDefaultApplicableLicenses() {
+ return defaultApplicableLicenses;
+ }
+
+ /**
* Sets the default license for this package.
*/
void setDefaultLicense(License license) {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 237f0fa..acda081 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -199,6 +199,26 @@
}
}
+ /**
+ * Declares the package() attribute specifying the default value for {@link
+ * com.google.devtools.build.lib.packages.RuleClass#APPLICABLE_LICENSES_ATTR} when not explicitly
+ * specified.
+ */
+ private static class DefaultApplicableLicenses extends PackageArgument<List<Label>> {
+ private static final String DEFAULT_APPLICABLE_LICENSES_ATTRIBUTE =
+ "default_applicable_licenses";
+
+ private DefaultApplicableLicenses() {
+ super(DEFAULT_APPLICABLE_LICENSES_ATTRIBUTE, BuildType.LABEL_LIST);
+ }
+
+ @Override
+ protected void process(Package.Builder pkgBuilder, Location location, List<Label> value) {
+ pkgBuilder.setDefaultApplicableLicenses(
+ value, DEFAULT_APPLICABLE_LICENSES_ATTRIBUTE, location);
+ }
+ }
+
private static class DefaultLicenses extends PackageArgument<License> {
private DefaultLicenses() {
super("licenses", BuildType.LICENSE);
@@ -448,6 +468,7 @@
ImmutableList.<PackageArgument<?>>builder()
.add(new DefaultDeprecation())
.add(new DefaultDistribs())
+ .add(new DefaultApplicableLicenses())
.add(new DefaultLicenses())
.add(new DefaultTestOnly())
.add(new DefaultVisibility())
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index 301cc77..4e78bea 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -135,6 +135,10 @@
public static final PathFragment EXPERIMENTAL_PREFIX = PathFragment.create("experimental");
public static final String EXEC_COMPATIBLE_WITH_ATTR = "exec_compatible_with";
public static final String EXEC_PROPERTIES = "exec_properties";
+ /*
+ * The attribute that declares the set of license labels which apply to this target.
+ */
+ public static final String APPLICABLE_LICENSES_ATTR = "applicable_licenses";
/**
* A constraint for the package name of the Rule instances.
@@ -2183,6 +2187,11 @@
*/
private static Object getAttributeNoncomputedDefaultValue(Attribute attr,
Package.Builder pkgBuilder) {
+ // TODO(b/149505729): Determine the right semantics for someone trying to define their own
+ // attribute named applicable_licenses.
+ if (attr.getName().equals("applicable_licenses")) {
+ return pkgBuilder.getDefaultApplicableLicenses();
+ }
// Starlark rules may define their own "licenses" attributes with different types -
// we shouldn't trigger the special "licenses" on those cases.
if (attr.getName().equals("licenses") && attr.getType() == BuildType.LICENSE) {