diff options
Diffstat (limited to 'android/rule_builder.go')
-rw-r--r-- | android/rule_builder.go | 87 |
1 files changed, 79 insertions, 8 deletions
diff --git a/android/rule_builder.go b/android/rule_builder.go index afb5f4e4a..8dc9d6a42 100644 --- a/android/rule_builder.go +++ b/android/rule_builder.go @@ -246,6 +246,41 @@ func (r *RuleBuilder) Outputs() WritablePaths { return outputList } +func (r *RuleBuilder) symlinkOutputSet() map[string]WritablePath { + symlinkOutputs := make(map[string]WritablePath) + for _, c := range r.commands { + for _, symlinkOutput := range c.symlinkOutputs { + symlinkOutputs[symlinkOutput.String()] = symlinkOutput + } + } + return symlinkOutputs +} + +// SymlinkOutputs returns the list of paths that the executor (Ninja) would +// verify, after build edge completion, that: +// +// 1) Created output symlinks match the list of paths in this list exactly (no more, no fewer) +// 2) Created output files are *not* declared in this list. +// +// These symlink outputs are expected to be a subset of outputs or implicit +// outputs, or they would fail validation at build param construction time +// later, to support other non-rule-builder approaches for constructing +// statements. +func (r *RuleBuilder) SymlinkOutputs() WritablePaths { + symlinkOutputs := r.symlinkOutputSet() + + var symlinkOutputList WritablePaths + for _, symlinkOutput := range symlinkOutputs { + symlinkOutputList = append(symlinkOutputList, symlinkOutput) + } + + sort.Slice(symlinkOutputList, func(i, j int) bool { + return symlinkOutputList[i].String() < symlinkOutputList[j].String() + }) + + return symlinkOutputList +} + func (r *RuleBuilder) depFileSet() map[string]WritablePath { depFiles := make(map[string]WritablePath) for _, c := range r.commands { @@ -467,6 +502,7 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string Implicits: r.Inputs(), Output: output, ImplicitOutputs: implicitOutputs, + SymlinkOutputs: r.SymlinkOutputs(), Depfile: depFile, Deps: depFormat, Description: desc, @@ -478,14 +514,15 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string // RuleBuilderCommand, so they can be used chained or unchained. All methods that add text implicitly add a single // space as a separator from the previous method. type RuleBuilderCommand struct { - buf strings.Builder - inputs Paths - implicits Paths - orderOnlys Paths - outputs WritablePaths - depFiles WritablePaths - tools Paths - rspFileInputs Paths + buf strings.Builder + inputs Paths + implicits Paths + orderOnlys Paths + outputs WritablePaths + symlinkOutputs WritablePaths + depFiles WritablePaths + tools Paths + rspFileInputs Paths // spans [start,end) of the command that should not be ninja escaped unescapedSpans [][2]int @@ -715,6 +752,40 @@ func (c *RuleBuilderCommand) ImplicitOutputs(paths WritablePaths) *RuleBuilderCo return c } +// ImplicitSymlinkOutput declares the specified path as an implicit output that +// will be a symlink instead of a regular file. Does not modify the command +// line. +func (c *RuleBuilderCommand) ImplicitSymlinkOutput(path WritablePath) *RuleBuilderCommand { + c.symlinkOutputs = append(c.symlinkOutputs, path) + return c.ImplicitOutput(path) +} + +// ImplicitSymlinkOutputs declares the specified paths as implicit outputs that +// will be a symlinks instead of regular files. Does not modify the command +// line. +func (c *RuleBuilderCommand) ImplicitSymlinkOutputs(paths WritablePaths) *RuleBuilderCommand { + for _, path := range paths { + c.ImplicitSymlinkOutput(path) + } + return c +} + +// SymlinkOutput declares the specified path as an output that will be a symlink +// instead of a regular file. Modifies the command line. +func (c *RuleBuilderCommand) SymlinkOutput(path WritablePath) *RuleBuilderCommand { + c.symlinkOutputs = append(c.symlinkOutputs, path) + return c.Output(path) +} + +// SymlinkOutputsl declares the specified paths as outputs that will be symlinks +// instead of regular files. Modifies the command line. +func (c *RuleBuilderCommand) SymlinkOutputs(paths WritablePaths) *RuleBuilderCommand { + for _, path := range paths { + c.SymlinkOutput(path) + } + return c +} + // ImplicitDepFile adds the specified depfile path to the paths returned by RuleBuilder.DepFiles without modifying // the command line, and causes RuleBuilder.Build file to set the depfile flag for ninja. If multiple depfiles // are added to commands in a single RuleBuilder then RuleBuilder.Build will add an extra command to merge the |