Problem: converting recursive builds into non-recusive builds while handling effective no-op (no operation) targets
A recursive build design trick that I have seen before and am now dealing with is where a bunch of work (target commands are being executed) is done only to find that the target is not actually modified. One example of this is generating a export list of symbols for a shared library. Specifically, even though the object files that go into a shared library have changed, possibly quite so, the 'external' symbol list including all argument specifications (ansi C) has not.
When this is so, no down stream executables or other shared libs need to be relinked with the new shared library since none of the external symbols have changed. In recursive build systems, a common trick is that the make process of the shared library directory ends up not modifying the library's export list file while it does modify the shared library itself. Then, when the build recurses into another directory, creating a new instance of a new DAG, recursive targets that depend on the export file (anything that links the library!) will see the old export file and not relink. Targets that depend on the shared library, like unit tests, 'make install' targets and the like, will see a new .so and re-run.
With the current recursive build system at hand, this trick saves over an hour of link time per build per platform.
There seems to be a problem when trying to convert this trick to a non-recusive build. The problem is that in a non-recursive system, the command rules of the export list target are always executed when, in this scenario, the object files that comprise the shared library have changed. This happens whether the export file ends up being changed or remains the same. But, even when the export file is not modified, that fact that the rules have fired appears to tell gmake to remake all the targets that depend on this (export file) target. There is no other DAG as in a recursive make implementation to escape to.
This is bad - people will be waiting many extra hours per day. (Note: scons support of this feature is one of the compelling reasons for scons, but scons is a different topic)
Have I missed something here?
Is there a way to do something like the following:
foo.exp : $(ALL_FOO_OFILES)
create_export_list.pl [EMAIL PROTECTED] $^
create_sharedlib.pl $(basename $@).so $^
ifeq ($(shell stat.pl $@),$(shell stat.pl [EMAIL PROTECTED]))
$(old $@)
rm [EMAIL PROTECTED] && touch $@
else
mv [EMAIL PROTECTED] $@
endifThe 'old' command basically performs what a "-o foo.exp" would do on the command line to make - it tells make to consider foo.exp as being old, but from this point on instead of from the initial invocation of make. The touch is there so that the next time make is run, of no object files have changed, then foo.exp is considered up-to-date to begin with.
Thanks much for any thoughts/comments. -sandy
p.s. the above example uses a stat.pl perl script so that it is up to the user as to whether a mtime or a MD5 hash is used to determine a real 'change' to foo.exp
_______________________________________________ Help-make mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/help-make
