Monday, March 22, 2010

When make(1) Starts Spinning in Circles

I have this Linux project where the "depend" Makefile target reads:
${DEPDIR}/%.d:  %.cpp
@echo "Determining dependencies for $<"
@${CXX} ${CPPFLAGS} -E -MM $< | \
sed -e 's~\($*\)\.o[ :]*~\1.o $@ : ~g' > $@
In one instance this snippet would start to run in an infinite loop.

On a closer look it turned out that the build machine I was trying to make this the system clock was waaay behind the `real' time and there was nope in h*ll to get it sync'ed as the corporate firewall blocks the S/NTP.

The files were checked out out of TFS via Samba which somehow preserves the time stamp of the client Win32 machine (whose clock was right).

The clock being behind it means that all builds artefacts were indeed older than the files that came out of revision control, thus the infinite loop.

The solution is rather simple (as this is build machine, not a dev machine):
# The time on the Linux build machine may drift
# and be behind the time of the TFS agent. Yet when
# files are deposited on the Samba share their
# time stamps come from the agent and that can
# be "newer" than any file we produce locally
# on the Linux machine thus triggering an IFINITE loop.
#
# We time stamp all files with the (same) local time
# stamp to avoid this.
CO_TIME=$(date '+%Y%m%d%H%M'); export CO_TIME
find -type f -exec touch -t $CO_TIME {} \;
unset CO_TIME
What's frustrating is that I had this problem 4 years ago when I did not have this blog to remind myself of build oddities.

Also during the same exercise I learned that the Win32 DEL command does not cope well with symlinks on the Samba share so it needs a small assisst at the end of the build:
find -type l -delete
-ulianov