| A few days ago a couple of colleagues came to me and asked for help
with a really strange phenomenon. They have a C++ program that
consists of a few files that they link with a number of libraries. The
problem is that when they run the program it gets stuck - just hangs
at some point. The weird part of it is that when they
touch(1) the file that contains the main(), say
prog.cc, build the application (using GNU make(1),
of course) again, and re-run, the program works and terminates
normally. Well, first of all I of course reproduced the effect successfully. I also ran the program in the debugger, killed it when it hung, and looked at the stack backtrace. Looks like they had a deadlock somewhere. But what's with this touch(1) business?
Let's look at the Makefile. Looks simple enough, and actually
quite decent. The main target is built with the equivalent of $(PROG): prog.o foo.o bar.o
Oh, well, now it is clear: a quick change of $? to
$^ did not fix the deadlock problem, but restored the sanity
of everybody involved: it turned out that the application worked even
without foo.o or bar.o, and the latter only
introduced additional mutithreaded stuff with buggy synchronization. In case you still have not got the picture: with GNU make(1) $? stands for the newly updated prerequisites only, so after touch prog.cc only prog.o, but not foo.o or bar.o were linked into the executable. $^ stands for all the prerequisites. Fixing the deadlock was left as an exercise. |