Skip to content

Commit 1e9b233

Browse files
tetrominocopybara-github
authored andcommitted
Introduce --experimental_lazy_macro_expansion_packages and allow PackageFunction to assemble packages from package pieces
At present, lazy symbolic macro expansion is incompatible with any package that calls native.existing_rule() or native.existing_rules() outside of a finalizer symbolic macro, and so cannot be enabled globally. Working towards #23852 PiperOrigin-RevId: 792253787 Change-Id: Ifb1fc9f0259b188e2bf33f58cd0a2ec610362db2
1 parent f12e843 commit 1e9b233

28 files changed

+904
-174
lines changed

src/main/java/com/google/devtools/build/lib/packages/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ java_library(
9393
"//src/main/java/com/google/devtools/build/lib/events",
9494
"//src/main/java/com/google/devtools/build/lib/io:file_symlink_exception",
9595
"//src/main/java/com/google/devtools/build/lib/packages/semantics",
96+
"//src/main/java/com/google/devtools/build/lib/pkgcache:package_options",
9697
"//src/main/java/com/google/devtools/build/lib/profiler",
9798
"//src/main/java/com/google/devtools/build/lib/skyframe:bzl_load_value",
9899
"//src/main/java/com/google/devtools/build/lib/skyframe:detailed_exceptions",

src/main/java/com/google/devtools/build/lib/packages/OutputFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static OutputFile createExplicit(Label label, Rule generatingRule, String attrNa
4848
private final String outputKey;
4949

5050
private OutputFile(Label label, Rule generatingRule, String outputKey) {
51-
super(generatingRule.getPackage(), label);
51+
super(generatingRule.getPackageoid(), label);
5252
this.generatingRule = generatingRule;
5353
this.outputKey = outputKey;
5454
}

src/main/java/com/google/devtools/build/lib/packages/Package.java

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ public enum ConfigSettingVisibilityPolicy {
191191
*/
192192
// TODO(#19922): Better separate fields that must be known a priori from those determined through
193193
// BUILD evaluation.
194-
private Package(Metadata metadata) {
195-
super(metadata, new Declarations.Builder());
194+
private Package(Metadata metadata, Declarations declarations) {
195+
super(metadata, declarations);
196196
}
197197

198198
// ==== General package metadata accessors ====
@@ -597,6 +597,7 @@ public static Builder newPackageBuilder(
597597
.configSettingVisibilityPolicy(configSettingVisibilityPolicy)
598598
.succinctTargetNotFoundErrors(packageSettings.succinctTargetNotFoundErrors())
599599
.build(),
600+
new Declarations.Builder(),
600601
SymbolGenerator.create(id),
601602
packageSettings.precomputeTransitiveLoads(),
602603
noImplicitFileExport,
@@ -611,6 +612,45 @@ public static Builder newPackageBuilder(
611612
packageLimits);
612613
}
613614

615+
/** Returns a new {@link Builder} suitable for constructing a package from package pieces. */
616+
public static Builder newPackageFromPackagePiecesBuilder(
617+
PackageSettings packageSettings,
618+
Metadata metadata,
619+
Declarations declarations,
620+
boolean noImplicitFileExport,
621+
boolean simplifyUnconditionalSelectsInRuleAttrs,
622+
RepositoryMapping mainRepositoryMapping,
623+
@Nullable Semaphore cpuBoundSemaphore,
624+
PackageOverheadEstimator packageOverheadEstimator,
625+
@Nullable ImmutableMap<Location, String> generatorMap,
626+
@Nullable Globber globber,
627+
boolean enableNameConflictChecking,
628+
boolean trackFullMacroInformation,
629+
PackageLimits packageLimits,
630+
InputFile buildFile) {
631+
Builder builder =
632+
new Builder(
633+
metadata,
634+
declarations.checkImmutable(),
635+
SymbolGenerator.create(metadata.packageIdentifier()),
636+
packageSettings.precomputeTransitiveLoads(),
637+
noImplicitFileExport,
638+
simplifyUnconditionalSelectsInRuleAttrs,
639+
mainRepositoryMapping,
640+
cpuBoundSemaphore,
641+
packageOverheadEstimator,
642+
generatorMap,
643+
globber,
644+
enableNameConflictChecking,
645+
trackFullMacroInformation,
646+
packageLimits);
647+
checkArgument(
648+
buildFile.getPackageMetadata().packageIdentifier().equals(metadata.packageIdentifier()));
649+
builder.recorder.replaceInputFileUnchecked(buildFile);
650+
builder.setBuildFile(buildFile);
651+
return builder;
652+
}
653+
614654
// ==== Non-trivial nested classes ====
615655

616656
/**
@@ -962,7 +1002,9 @@ protected void packageoidInitializationHook() {
9621002
mergePackageArgsFrom(PackageArgs.builder().setDefaultTestOnly(true));
9631003
}
9641004
// Add target for the BUILD file itself.
965-
// (This may be overridden by an exports_file declaration.)
1005+
// (This may be overridden by an exports_file declaration; or, for a package from package
1006+
// pieces, by the PackagePiece.ForBuildFile's BUILD file target set in
1007+
// newPackageFromPackagePiecesBuilder().)
9661008
recorder.addInputFileUnchecked(
9671009
new InputFile(pkg, metadata.buildFileLabel(), metadata.getBuildFileLocation()));
9681010
}
@@ -975,8 +1017,8 @@ protected void packageoidInitializationHook() {
9751017
public static class Builder extends AbstractBuilder {
9761018

9771019
/**
978-
* A bundle of options affecting package construction, that is not specific to any particular
979-
* package.
1020+
* A bundle of statically-defined options affecting package construction, that is not specific
1021+
* to any particular package and does not change for the lifetime of the server.
9801022
*/
9811023
public interface PackageSettings {
9821024
/**
@@ -1063,6 +1105,7 @@ default long maxStarlarkComputationStepsPerPackage() {
10631105

10641106
private Builder(
10651107
Metadata metadata,
1108+
Declarations declarations,
10661109
SymbolGenerator<?> symbolGenerator,
10671110
boolean precomputeTransitiveLoads,
10681111
boolean noImplicitFileExport,
@@ -1077,7 +1120,7 @@ private Builder(
10771120
PackageLimits packageLimits) {
10781121
super(
10791122
metadata,
1080-
new Package(metadata),
1123+
new Package(metadata, declarations),
10811124
symbolGenerator,
10821125
precomputeTransitiveLoads,
10831126
noImplicitFileExport,
@@ -1134,6 +1177,15 @@ public void addRuleUnchecked(Rule rule) {
11341177
recorder.addRuleUnchecked(rule);
11351178
}
11361179

1180+
/** Adds all targets, macros, and Starlark computation steps from a given package piece. */
1181+
public void addAllFromPackagePiece(PackagePiece packagePiece) throws NameConflictException {
1182+
// We add the BUILD file in newPackageFromPackagePiecesBuilder(), not here. (We want to ensure
1183+
// that the package always has a BUILD file target, even if addAllFromPackagePiece would throw
1184+
// a name conflict.)
1185+
this.recorder.addAllFromPackagePiece(packagePiece, /* skipBuildFile= */ true);
1186+
this.computationSteps += packagePiece.getComputationSteps();
1187+
}
1188+
11371189
@Override
11381190
public boolean eagerlyExpandMacros() {
11391191
return true;

src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.google.devtools.build.lib.packages.PackageValidator.InvalidPackageException;
3535
import com.google.devtools.build.lib.packages.PackageValidator.InvalidPackagePieceException;
3636
import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
37+
import com.google.devtools.build.lib.pkgcache.PackageOptions.LazyMacroExpansionPackages;
3738
import com.google.devtools.build.lib.profiler.Profiler;
3839
import com.google.devtools.build.lib.profiler.ProfilerTask;
3940
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
@@ -243,6 +244,37 @@ public Package.Builder newPackageBuilder(
243244
packageValidator.getPackageLimits());
244245
}
245246

247+
// This function is public only for the benefit of skyframe.PackageFunction,
248+
// which is morally part of lib.packages, so that it can create empty packages
249+
// in case of error before BUILD execution. Do not call it from anywhere else.
250+
public Package.Builder newPackageFromPackagePiecesBuilder(
251+
Package.Metadata metadata,
252+
Package.Declarations declarations,
253+
StarlarkSemantics starlarkSemantics,
254+
RepositoryMapping mainRepositoryMapping,
255+
@Nullable Semaphore cpuBoundSemaphore,
256+
@Nullable ImmutableMap<Location, String> generatorMap,
257+
@Nullable ConfigSettingVisibilityPolicy configSettingVisibilityPolicy,
258+
@Nullable Globber globber,
259+
InputFile buildFile) {
260+
return Package.newPackageFromPackagePiecesBuilder(
261+
packageSettings,
262+
metadata,
263+
declarations,
264+
starlarkSemantics.getBool(BuildLanguageOptions.INCOMPATIBLE_NO_IMPLICIT_FILE_EXPORT),
265+
starlarkSemantics.getBool(
266+
BuildLanguageOptions.INCOMPATIBLE_SIMPLIFY_UNCONDITIONAL_SELECTS_IN_RULE_ATTRS),
267+
mainRepositoryMapping,
268+
cpuBoundSemaphore,
269+
packageOverheadEstimator,
270+
generatorMap,
271+
globber,
272+
/* enableNameConflictChecking= */ true,
273+
/* trackFullMacroInformation= */ true,
274+
packageValidator.getPackageLimits(),
275+
buildFile);
276+
}
277+
246278
// This function is public only for the benefit of skyframe.PackageFunction, which is morally part
247279
// of lib.packages, so that it can create empty package pieces in case of error before BUILD
248280
// execution. Do not call it from anywhere else.
@@ -337,6 +369,7 @@ public NonSkyframeGlobber createNonSkyframeGlobber(
337369
public void afterDoneLoadingPackage(
338370
Package pkg,
339371
StarlarkSemantics starlarkSemantics,
372+
LazyMacroExpansionPackages lazyMacroExpansionPackages,
340373
Metrics metrics,
341374
ExtendedEventHandler eventHandler)
342375
throws InvalidPackageException {
@@ -364,7 +397,8 @@ public void afterDoneLoadingPackage(
364397
.build()));
365398
}
366399

367-
packageLoadingListener.onLoadingCompleteAndSuccessful(pkg, starlarkSemantics, metrics);
400+
packageLoadingListener.onLoadingCompleteAndSuccessful(
401+
pkg, starlarkSemantics, lazyMacroExpansionPackages, metrics);
368402
}
369403

370404
/**
@@ -373,6 +407,9 @@ public void afterDoneLoadingPackage(
373407
*
374408
* @throws InvalidPackagePieceException if the package is determined to be invalid
375409
*/
410+
// TODO(https://github.com/bazelbuild/bazel/issues/23852): merge with afterDoneLoadingPackagePiece
411+
// and perhaps move it all to PackageFunction (combining with existing PackageFunction.compute()
412+
// boilerplate such as finishBuild() and event replay). Requires package piece validation.
376413
public void afterDoneLoadingPackagePiece(
377414
PackagePiece pkgPiece,
378415
StarlarkSemantics starlarkSemantics,

src/main/java/com/google/devtools/build/lib/packages/PackageLoadingListener.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,26 @@
1414

1515
package com.google.devtools.build.lib.packages;
1616

17+
import com.google.devtools.build.lib.pkgcache.PackageOptions.LazyMacroExpansionPackages;
1718
import java.util.List;
1819
import net.starlark.java.eval.StarlarkSemantics;
1920

2021
/** Listener for package-loading events. */
2122
public interface PackageLoadingListener {
2223

23-
PackageLoadingListener NOOP_LISTENER = (pkg, semantics, metrics) -> {};
24+
PackageLoadingListener NOOP_LISTENER =
25+
(pkg, semantics, lazyMacroExpansionPackages, metrics) -> {};
2426

2527
/** Returns a {@link PackageLoadingListener} from a composed of the input listeners. */
2628
static PackageLoadingListener create(List<PackageLoadingListener> listeners) {
2729
return switch (listeners.size()) {
2830
case 0 -> NOOP_LISTENER;
2931
case 1 -> listeners.get(0);
3032
default ->
31-
(pkg, semantics, metrics) -> {
33+
(pkg, semantics, lazyMacroExpansionPackages, metrics) -> {
3234
for (PackageLoadingListener listener : listeners) {
33-
listener.onLoadingCompleteAndSuccessful(pkg, semantics, metrics);
35+
listener.onLoadingCompleteAndSuccessful(
36+
pkg, semantics, lazyMacroExpansionPackages, metrics);
3437
}
3538
};
3639
};
@@ -57,7 +60,12 @@ record Metrics(long loadTimeNanos, long globFilesystemOperationCost) {}
5760
*
5861
* @param pkg the loaded {@link Package}
5962
* @param starlarkSemantics are the semantics used to load the package
63+
* @param lazyMacroExpansionPackages determines which packages are loaded with lazy symbolic macro
64+
* expansion enabled
6065
*/
6166
void onLoadingCompleteAndSuccessful(
62-
Package pkg, StarlarkSemantics starlarkSemantics, Metrics metrics);
67+
Package pkg,
68+
StarlarkSemantics starlarkSemantics,
69+
LazyMacroExpansionPackages lazyMacroExpansionPackages,
70+
Metrics metrics);
6371
}

src/main/java/com/google/devtools/build/lib/packages/TargetDefinitionContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public abstract class TargetDefinitionContext extends StarlarkThreadContext {
156156

157157
protected boolean alreadyBuilt = false;
158158

159-
private long computationSteps = 0;
159+
protected long computationSteps = 0;
160160

161161
/** Retrieves this object from a Starlark thread. Returns null if not present. */
162162
@Nullable
@@ -772,7 +772,7 @@ void setFailureDetailOverride(FailureDetail failureDetail) {
772772
}
773773

774774
@Nullable
775-
FailureDetail getFailureDetail() {
775+
public FailureDetail getFailureDetail() {
776776
if (failureDetailOverride != null) {
777777
return failureDetailOverride;
778778
}

src/main/java/com/google/devtools/build/lib/packages/TargetRecorder.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,8 @@ public void addMacro(MacroInstance macro) throws NameConflictException {
454454
* Adds all rules and macros from a given package piece. Intended only for use by skyframe
455455
* machinery.
456456
*/
457-
public void addAllFromPackagePiece(PackagePiece packagePiece) throws NameConflictException {
457+
public void addAllFromPackagePiece(PackagePiece packagePiece, boolean skipBuildFile)
458+
throws NameConflictException {
458459
MacroFrame prev;
459460
if (packagePiece instanceof PackagePiece.ForMacro forMacro) {
460461
prev = setCurrentMacroFrame(new MacroFrame(forMacro.getEvaluatedMacro()));
@@ -464,7 +465,19 @@ public void addAllFromPackagePiece(PackagePiece packagePiece) throws NameConflic
464465
for (MacroInstance macro : packagePiece.getMacros()) {
465466
addMacro(macro);
466467
}
468+
@Nullable
469+
InputFile buildFile =
470+
packagePiece instanceof PackagePiece.ForBuildFile forBuildFile
471+
? forBuildFile.getBuildFile()
472+
: null;
467473
for (Target target : packagePiece.getTargets().values()) {
474+
if (skipBuildFile && target == buildFile) {
475+
continue;
476+
}
477+
if (target instanceof OutputFile) {
478+
// Rule output files are recorded as a side effect of addTarget(rule)
479+
continue;
480+
}
468481
addTarget(target);
469482
}
470483
var unused = setCurrentMacroFrame(prev);

src/main/java/com/google/devtools/build/lib/packages/metrics/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ java_library(
2525
"//src/main/java/com/google/devtools/build/lib/cmdline",
2626
"//src/main/java/com/google/devtools/build/lib/collect:extrema",
2727
"//src/main/java/com/google/devtools/build/lib/packages",
28+
"//src/main/java/com/google/devtools/build/lib/pkgcache:package_options",
2829
"//src/main/java/com/google/devtools/build/lib/vfs",
2930
"//src/main/java/com/google/devtools/common/options",
3031
"//src/main/java/net/starlark/java/eval",

src/main/java/com/google/devtools/build/lib/packages/metrics/PackageMetricsPackageLoadingListener.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import com.google.devtools.build.lib.packages.Package;
1717
import com.google.devtools.build.lib.packages.PackageLoadingListener;
18+
import com.google.devtools.build.lib.pkgcache.PackageOptions.LazyMacroExpansionPackages;
1819
import com.google.protobuf.util.Durations;
1920
import javax.annotation.concurrent.GuardedBy;
2021
import net.starlark.java.eval.StarlarkSemantics;
@@ -43,7 +44,10 @@ private PackageMetricsPackageLoadingListener() {
4344

4445
@Override
4546
public synchronized void onLoadingCompleteAndSuccessful(
46-
Package pkg, StarlarkSemantics starlarkSemantics, Metrics metrics) {
47+
Package pkg,
48+
StarlarkSemantics starlarkSemantics,
49+
LazyMacroExpansionPackages lazyMacroExpansionPackages,
50+
Metrics metrics) {
4751
if (recorder == null) {
4852
// Micro-optimization - no need to track.
4953
return;

0 commit comments

Comments
 (0)