Ninja 1.9.0 builds static libraries twice
Hello,
I found a quite annoying but interesting bug. Since Ninja 1.9.0 on macOS I noticed that static libraries are always built twice (one time for build-all, one time for install):
ninja clean && ninja && ninja -n -d explain
[1/1] Cleaning all built files...
Cleaning... 4 files.
[3/4] Linking C static library libfoo.a
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libfoo.a(foo.c.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libfoo.a(foo.c.o) has no symbols
warning: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: warning for library: libfoo.a the table of contents is empty (no object file members in the library define global symbols)
[4/4] Linking C executable timestamp
ninja explain: output libfoo.a older than most recent input CMakeFiles/foo.dir/foo.c.o (1556814196000000000 vs 1556814196613609054)
ninja explain: libfoo.a is dirty
[1/1] Linking C static library libfoo.a
The problem here is that the fractional seconds part of the mtime of libfoo.a
is truncated (lots of zeroes). This only happens on APFS and with Ninja 1.9.0 (which added sub-second timestamp support).
The culprit seems to be the ranlib
call:
touch bar.c
clang -c bar.c
ar -qc bar.a bar.o
./timestamp bar.a # outputs: 1556814480 10926633 bar.a
ranlib bar.a
./timestamp bar.a # outputs: 1556814492 0 bar.a
Adding the -s
flag to ar also seems to invoke ranlib
under the hood and leads to truncation.