Symptom
In a variant build, an input that names a source file fails in the shell if an earlier rule has put an output under that file's path. sub is a regular file in the source tree:
: |> echo hi > %o |> sub/x.o
: sub |> cat %f > %o |> a.txt
$ putup -B build
cat: build/sub: Is a directory
[build] Build completed: 1 commands (1 failed) in 3ms
The input sub resolved to build/sub, the directory created for the first rule's output, not to the source file. Swap the two rules and the input binds to the source file. So the result depends on rule order.
Run against build/putup from PR #497 (0dc8b5352).
Upstream
tup accepts the Tupfile. In a variant build, both the output and its directory live in the variant tree, and the input sub names the source file.
Cause
resolve_input_node looks up a build-root spelling of the path before it consults the source tree (src/graph/builder.cpp:370). The earlier output's parent chain created a build-root Directory node for sub, and that lookup returns it. Disk is never consulted.
In an in-tree build the two spellings name the same file, so PR #497 refuses the Tupfile instead. In a variant build they name different files, and only the source one is an input.
Fix direction
A build-root node should satisfy an input only when it is something a rule produces (Generated or Ghost), not a Directory created as an output's parent. Otherwise the lookup should fall through to the source tree. Check whether the other lookups in resolve_input_node share this shape.
Symptom
In a variant build, an input that names a source file fails in the shell if an earlier rule has put an output under that file's path.
subis a regular file in the source tree:The input
subresolved tobuild/sub, the directory created for the first rule's output, not to the source file. Swap the two rules and the input binds to the source file. So the result depends on rule order.Run against
build/putupfrom PR #497 (0dc8b5352).Upstream
tup accepts the Tupfile. In a variant build, both the output and its directory live in the variant tree, and the input
subnames the source file.Cause
resolve_input_nodelooks up a build-root spelling of the path before it consults the source tree (src/graph/builder.cpp:370). The earlier output's parent chain created a build-root Directory node forsub, and that lookup returns it. Disk is never consulted.In an in-tree build the two spellings name the same file, so PR #497 refuses the Tupfile instead. In a variant build they name different files, and only the source one is an input.
Fix direction
A build-root node should satisfy an input only when it is something a rule produces (Generated or Ghost), not a Directory created as an output's parent. Otherwise the lookup should fall through to the source tree. Check whether the other lookups in
resolve_input_nodeshare this shape.