Incremental static-library builds retain removed source objects
When a source is removed from a static-library target and deleted from disk, rebuilding can retain its old object in the archive. An application that references its function can still link, while a clean build fails.
Reproduced on macOS with Python 3.13 at commit 76970c97c67f3c14c627e4420c0a3f02b6de66ed:
- Define a static library containing
keep.c and removed.c, and an executable that depends on the library and calls a function in removed.c.
- Build successfully.
- Delete
removed.c and remove it from the target's sources.
- Rebuild in the existing build directory: the executable still links.
- Build into a fresh directory: linking correctly fails because the function is missing.
Expected: both builds reject the reference to the removed function.
Actual: ar t shows removed.o still in the incrementally rebuilt archive.
The generated ar rcs $out $in command updates supplied members but retains omitted members. Recreating the archive when its Ninja edge runs resolves this inconsistency.
Incremental static-library builds retain removed source objects
When a source is removed from a static-library target and deleted from disk, rebuilding can retain its old object in the archive. An application that references its function can still link, while a clean build fails.
Reproduced on macOS with Python 3.13 at commit
76970c97c67f3c14c627e4420c0a3f02b6de66ed:keep.candremoved.c, and an executable that depends on the library and calls a function inremoved.c.removed.cand remove it from the target's sources.Expected: both builds reject the reference to the removed function.
Actual:
ar tshowsremoved.ostill in the incrementally rebuilt archive.The generated
ar rcs $out $incommand updates supplied members but retains omitted members. Recreating the archive when its Ninja edge runs resolves this inconsistency.