Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/build/build_step.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,17 @@ func buildTarget(state *core.BuildState, target *core.BuildTarget, runRemotely b
return err
}
log.Debug("Finished pre-build function for %s", target.Label)

// Wait for any new dependencies added by pre-build commands before continuing.
for _, dep := range target.Dependencies() {
dep.WaitForBuild(target.Label)
if dep.State() >= core.DependencyFailed { // Either the target failed or its dependencies failed
// Give up and set the original target as dependency failed
target.SetState(core.DependencyFailed)
return fmt.Errorf("error in pre-rule dependency for %s: %s", target.Label, dep.Label)
}
}
log.Debug("Finished waiting for dependencies for %s", target.Label)
}

state.LogBuildResult(target, core.TargetBuilding, "Preparing...")
Expand Down Expand Up @@ -343,6 +354,16 @@ func buildTarget(state *core.BuildState, target *core.BuildTarget, runRemotely b
return err
}

// Wait for any new dependencies added by post-build commands before continuing.
for _, dep := range target.Dependencies() {
dep.WaitForBuild(target.Label)
if dep.State() >= core.DependencyFailed { // Either the target failed or its dependencies failed
// Give up and set the original target as dependency failed
target.SetState(core.DependencyFailed)
return fmt.Errorf("error in post-rule dependency for %s: %s", target.Label, dep.Label)
}
}

if runRemotely && len(outs) != len(target.Outputs()) {
// postBuildFunction has changed the target - must rebuild it
log.Info("Rebuilding %s after post-build function", target)
Expand Down
45 changes: 45 additions & 0 deletions src/core/build_input.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,51 @@ func (label SystemPathLabel) String() string {
return label.Name
}

// SingleOutputLabel represents a build label for a specific output of a rule.
// This can be used to target a specific output of this rule when depended on or an entry point when used in
// the context of tools.
type SingleOutputLabel struct {
BuildLabel
Output string
}

// MarshalText implements the encoding.TextMarshaler interface, which makes AnnotatedOutputLabel
// usable as map keys in JSON.
func (label SingleOutputLabel) MarshalText() ([]byte, error) {
return []byte(label.String()), nil
}

// Paths returns a slice of paths to the files of this input.
func (label SingleOutputLabel) Paths(graph *BuildGraph) []string {
target := graph.TargetOrDie(label.BuildLabel)
return addPathPrefix([]string{label.Output}, target.PackageDir())
}

// FullPaths is like Paths but includes the leading plz-out/gen directory.
func (label SingleOutputLabel) FullPaths(graph *BuildGraph) []string {
target := graph.TargetOrDie(label.BuildLabel)
return addPathPrefix([]string{label.Output}, target.OutDir())
}

// LocalPaths returns paths within the local package
func (label SingleOutputLabel) LocalPaths(graph *BuildGraph) []string {
return []string{label.Output}
}

// Label returns the build rule associated with this input. For a SingleOutputLabel it's always non-nil.
func (label SingleOutputLabel) Label() (BuildLabel, bool) {
return label.BuildLabel, true
}

func (label SingleOutputLabel) nonOutputLabel() (BuildLabel, bool) {
return BuildLabel{}, false
}

// String returns a string representation of this input.
func (label SingleOutputLabel) String() string {
return label.BuildLabel.String() + "+" + label.Output
}

// AnnotatedOutputLabel represents a build label with an annotation e.g. //foo:bar|baz where baz constitutes the
// annotation. This can be used to target a named output of this rule when depended on or an entry point when used in
// the context of tools.
Expand Down
10 changes: 10 additions & 0 deletions src/core/build_target.go
Original file line number Diff line number Diff line change
Expand Up @@ -1664,6 +1664,16 @@ func (target *BuildTarget) AddMaybeExportedDependency(dep BuildLabel, exported,
}
}

// RegisterDependencyTarget registers a build target to be used for a dependency label on the given target.
func (target *BuildTarget) RegisterDependencyTarget(dep BuildLabel, deptarget *BuildTarget) {
info := target.dependencyInfo(dep)
if info == nil {
log.Fatalf("Target %s doesn't contain dependency %s.\n", target.Label, dep)
} else {
info.deps = append(info.deps, deptarget)
}
}

// IsTool returns true if the given build label is a tool used by this target.
func (target *BuildTarget) IsTool(tool BuildLabel) bool {
if target.isTool(tool, target.Tools, target.namedTools) {
Expand Down
1 change: 1 addition & 0 deletions src/parse/asp/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,7 @@ func addDep(s *scope, args []pyObject) pyObject {
dep := s.parseLabelInPackage(string(args[1].(pyString)), s.pkg)
exported := args[2].IsTruthy()
target.AddMaybeExportedDependency(dep, exported, false, false)
target.RegisterDependencyTarget(dep, s.state.Graph.Target(dep))
// Queue this dependency if it'll be needed.
if target.State() > core.Inactive {
err := s.state.QueueTarget(dep, target.Label, false, core.ParseModeNormal)
Expand Down
10 changes: 10 additions & 0 deletions src/parse/asp/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,16 @@ type scope struct {
// parseAnnotatedLabelInPackage similarly to parseLabelInPackage, parses the label contextualising it to the provided
// package. It may return an AnnotatedOutputLabel or a BuildLabel depending on if the label is annotated.
func (s *scope) parseAnnotatedLabelInPackage(label string, pkg *core.Package) core.BuildInput {
if strings.Contains(label, "+") {
parts := strings.Split(label, "+")
if len(parts) == 2 {
return core.SingleOutputLabel{
BuildLabel: s.parseLabelInPackage(parts[0], pkg),
Output: parts[1],
}
}
}

label, annotation := core.SplitLabelAnnotation(label)
if annotation != "" {
return core.AnnotatedOutputLabel{
Expand Down
Loading