Symptom
An output may name a directory that exists in the source tree, or the directory a group lives in. putup does not refuse it at parse time. tup does.
Output onto a source directory, in-tree. srcdir/ holds f.c:
: |> echo hi > %o |> srcdir
$ putup -B .
[.] Error: Attempting to create files the build does not own:
srcdir
You can do one of two things to fix this:
1) If a file is really supposed to be created from the command, delete it from the filesystem and try again.
putup does refuse this, but later in the build and as an ownership conflict. That message tells the user to delete a directory of sources.
The same, in a variant build. putup -B build prints Build completed: 1 commands and writes a regular file build/srcdir.
Output onto a group's directory. d does not exist on disk:
: |> echo a > %o |> a.txt d/<g>
: |> echo hi > %o |> d
$ putup -B .
[.] Build completed: 2 commands in 1ms
This writes a regular file d, while the graph still holds d as the directory of <g>.
All three were run against build/putup from PR #497 (0dc8b5352).
Upstream
tup parse refuses all three:
tup error: Attempting to insert 'srcdir' as a generated node when it already exists as a different type (directory). ...
tup error: Attempting to insert 'd' as a generated node when it already exists as a different type (generated directory). ...
In a variant build, do_rule_outputs checks the output against its source-tree counterpart ("... in the source directory").
Cause
PR #497 refuses an output whose bound node is not a file (REQ-OUTPUT-NOT-A-DIRECTORY, the switch after ensure_file_node in expand_rule, src/graph/builder.cpp:2254). That catches only a Directory node under the build root.
- An output is a build-root path. In an in-tree build,
ensure_file_node's alias branch (src/graph/dag.cpp:171) aliases it to its source-root twin only when the twin is a Ghost or a File. A Directory twin, whether it was read from disk or created for a group, is skipped. So the output gets a second, Generated node beside it, and the check accepts that node.
- In a variant build, nothing compares an output against the source tree.
Fix direction
At the output check, also look up the output's source-root twin, in-tree and in a variant build, and refuse when it is a Directory. That would conform to validate_output and do_rule_outputs. REQ-OUTPUT-NOT-A-DIRECTORY (spec/requirements/output-paths.ears.md) records this gap as its third divergence; the fix removes it.
Symptom
An output may name a directory that exists in the source tree, or the directory a group lives in. putup does not refuse it at parse time. tup does.
Output onto a source directory, in-tree.
srcdir/holdsf.c:putup does refuse this, but later in the build and as an ownership conflict. That message tells the user to delete a directory of sources.
The same, in a variant build.
putup -B buildprintsBuild completed: 1 commandsand writes a regular filebuild/srcdir.Output onto a group's directory.
ddoes not exist on disk:This writes a regular file
d, while the graph still holdsdas the directory of<g>.All three were run against
build/putupfrom PR #497 (0dc8b5352).Upstream
tup parserefuses all three:In a variant build,
do_rule_outputschecks the output against its source-tree counterpart ("... in the source directory").Cause
PR #497 refuses an output whose bound node is not a file (REQ-OUTPUT-NOT-A-DIRECTORY, the
switchafterensure_file_nodeinexpand_rule,src/graph/builder.cpp:2254). That catches only a Directory node under the build root.ensure_file_node's alias branch (src/graph/dag.cpp:171) aliases it to its source-root twin only when the twin is a Ghost or a File. A Directory twin, whether it was read from disk or created for a group, is skipped. So the output gets a second, Generated node beside it, and the check accepts that node.Fix direction
At the output check, also look up the output's source-root twin, in-tree and in a variant build, and refuse when it is a Directory. That would conform to
validate_outputanddo_rule_outputs.REQ-OUTPUT-NOT-A-DIRECTORY(spec/requirements/output-paths.ears.md) records this gap as its third divergence; the fix removes it.