diff --git a/src/main/java/com/google/devtools/build/lib/analysis/WorkspaceStatusAction.java b/src/main/java/com/google/devtools/build/lib/analysis/WorkspaceStatusAction.java index 3e1205f7384174..6c063d5c8af989 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/WorkspaceStatusAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/WorkspaceStatusAction.java @@ -58,6 +58,9 @@ *

There are two of these files: volatile and stable. Changes in the volatile file do not cause * rebuilds if no other file is changed. This is useful for frequently-changing information that * does not significantly affect the build, e.g. the current time. + * + *

For more information, see {@link + * com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory}. */ public abstract class WorkspaceStatusAction extends AbstractAction { diff --git a/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoFactory.java index 19dd0de920c1ad..8c4891081bbc37 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoFactory.java @@ -19,9 +19,54 @@ import com.google.devtools.build.lib.vfs.PathFragment; /** - * A factory for language-specific build-info files. Use this to translate the build-info into - * target-independent language-specific files. The generated actions are registered into the action - * graph on every build, but only executed if anything depends on them. + * A factory for language-specific build-info files. + * + *

The goal of the build info system is to "stamp" non-hermetic information into output files, + * for example, the time and date of the build that resulted in the output, the hostname it was run + * on or the set of sources the output was built from. + * + *

This non-hermetic data gets into the action graph by calling the script specified in the + * --workspace_status_command command line argument, which results in a text file which + * containts a build info entry in each line, with its name ("key") and value separated by a space. + * This script is unconditionally invoked on every build and therefore should be very fast. + * + *

Build info keys come in two kinds: volatile and non-volatile. The difference is that the + * former is expected to change very frequently (e.g. current time) and therefore changes to it + * should not invalidate downstream actions whereas a rebuild is required if a non-volatile build + * info entry changes. + * + *

This is accomplished by splitting the build info file emitted by the workspace status command + * into two files, a volatile and a non-volatile. The former kind of artifact is special-cased in + * the execution phase machinery so that changes to it never trigger a rebuild. This artifact is + * marked by {@link + * com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType#CONSTANT_METADATA}. + * + *

The invocation of the workspace status command and splitting its output into two is done in + * descendants of {@link com.google.devtools.build.lib.analysis.WorkspaceStatusAction} . + * + *

However, this is not enough because the workspace status files cannot always be ingested by + * the actions that need them; for example, if a C++ file wants to incorporate build info, the + * compiler cannot process build info text files, therefore the data needs to be transformed into a + * format that the compiler likes. + * + *

This is done for each language by an implementation of {@link BuildInfoFactory}: rules can + * call {@link com.google.devtools.build.lib.analysis.AnalysisEnvironment#getBuildInfo(boolean, + * BuildInfoKey, BuildConfigurationValue)} with the language-specific build info key, which then + * invokes {@link com.google.devtools.build.lib.skyframe.BuildInfoCollectionFunction}, which in turn + * calls the language-specific implementation of {@link BuildInfoFactory}, which creates the + * language-specific actions and artifacts. These are then returned to the caller of {@code + * getBuildInfo()} (This could probably be replaced by an implicit dependency on a language-specific + * special rule does all this; there are only historical reasons why it works this way) + * + *

{@link com.google.devtools.build.lib.skyframe.BuildInfoCollectionValue} is a thin wrapper + * around the data structure {@code BuildInfoFactory} returns (a set of artifacts and actions). Its + * purpose is to allow Skyframe to look up the generating actions of build info artifacts. This is + * done by implementing {@link com.google.devtools.build.lib.actions.ActionLookupValue}. It is + * necessary because actions are usually generated by configured targets or aspects, but not build + * info actions which are instead created by the mechanism described above. + * + *

Build info factories are registered in {@link + * com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider}. */ public interface BuildInfoFactory { /** diff --git a/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoKey.java b/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoKey.java index 405e6331ceb194..9987a9c10120ab 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoKey.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/buildinfo/BuildInfoKey.java @@ -16,6 +16,9 @@ /** * Build-info key for lookup from the {@link * com.google.devtools.build.lib.analysis.AnalysisEnvironment}. + * + *

For more information, see {@link + * com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory}. */ public final class BuildInfoKey { private final String name; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BuildInfoCollectionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/BuildInfoCollectionFunction.java index c2bc3bc2ef13d7..3d21a891a50956 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/BuildInfoCollectionFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BuildInfoCollectionFunction.java @@ -36,6 +36,9 @@ /** * Creates a {@link BuildInfoCollectionValue}. Only depends on the unique {@link * WorkspaceStatusValue} and the constant {@link #BUILD_INFO_FACTORIES} injected value. + * + *

For more information, see {@link + * com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory}. */ public class BuildInfoCollectionFunction implements SkyFunction {