Multi Files
Multi files end in .wants. Unlike a unit file, a multi file declares a list
of Targets, and each Target must declare the paths it is allowed to write.
A multi file is a Spore body with a single export, .targets:
build = (#import "want:build")
paths = (#import "want:build/paths")
.targets = [
{
.input = [
(paths.unit "./input.txt")
]
.output = [
(paths.suffix ".out.txt")
]
.do = \(ctx: build.Ctx) build.FS {
// generate a bunch of files ending in ".out.txt"
}
}
]
.inputis a list of PathSets the target reads, exactly as for a unit file..outputis a list of PathSets the target may write to. TheFSreturned fromdois filtered through this set: writing to an undeclared path fails the build..dois the proc that produces the build, the same as for a unit file.
Rooting
Every target in a multi file is rooted at the parent directory of the .wants
file. The FS returned by do is positioned there, and .output is
interpreted there too.
A protobuf.wants file at the root of a module produces files at the module
root. If it were at a/b/c/protobuf.wants, and its do returned a filesystem
containing messages.pb.go and api.pb.go, the resulting output would be:
a/b/c/messages.pb.go
a/b/c/api.pb.go
The .output declaration does not need to repeat the prefix. Either of these
would accept the files above:
.output = [
(paths.unit "messages.pb.go")
(paths.unit "api.pb.go")
]
or, more flexibly, allowing the names to change as long as they keep the suffix:
.output = [
(paths.suffix ".pb.go")
]
Why declare outputs?
A unit file's output path is fixed by its name, so conflicts with other targets
are impossible. A multi file can write anywhere under its directory, so
declaring .output lets Want check, before anything runs, that no two targets
claim overlapping outputs, and that a target only writes where it said it
would.