On Mon, 28 May 2001, Keith Owens wrote:

> My aim is to detect if the command has changed and force the target to
> be rebuilt.

This definitely makes sense. Actually, the entire dependency stuff is
straight forward (but very messy to implement): A target needs to be
rebuild, if the command used to built-it changed, or any file which is
used during executing the command.

I started my own rewrite of kbuild some time ago, I never got around to
publish it, but I believe it has some good ideas in it. Here's what I do
in your case:

.PHONY: FORCE
FORCE:

# ----------------------------------------------------------------------
# -- compile objects

__compile_cmd = $(strip $(CC) -MD $(CFLAGS) $(__CFLAGS) $(__EXPFLAGS) $(__NAMEFLAGS) 
$(EXTRA_CFLAGS_$(@D)) $(CFLAGS_$@) -c -o $@ $<)

define __compile_rule
        $(V1) Compiling $@ ...
        $(V2) $(__compile_cmd)
        DEPENDENCIES_OUTPUT=$(@D)/$(@F:.o=.d) $(__compile_cmd)
        scripts/fix_dep $(TOPDIR) $(TOPDIR) $(@D) $(@F:.o=) >
$(@D)/$(patsubst %.o,.%.d,$(@F))
        echo 'COMMAND_$@ := $(__compile_cmd)' > $(@D)/.$(@F).command
endef

%.o: %.c FORCE
        @ $(if $(strip $? $(filter-out $(__compile_cmd),$(COMMAND_$@))
$(filter-out $(COMMAND_$@),$(__compile_cmd))),$(__compile_rule) )

# -- include command lines

__command_files := $(foreach m,$(subdirs),$(wildcard $(m)/.*.command))
ifneq ($(__command_files),)
include $(__command_files)
endif

Now, that's maybe not so straightforward, and actually looks really ugly,
but the user doesn't need to see this, your parser could automatically
generate something like this.

How does that work? Well, due to the dependency on FORCE, the target will
have to be remade everytime. Only, if neither the command changed, nor the
other files we depend on, the $(if ...) part will end up empty. If
$? (changed dependencies) is not empty, or the compile command is not
equal to the saved compile command for this target (didn't find any
easier way of expressing this than double filter-out), we execute
$(__compile_rule). In this rule, we save the compile command for this
target in a .command file, and include it the next time we "make"
something.

Now, to make it a bit more complicated, when I want to use variables like
$^, I have to take into account that these now have FORCE added, but
that's of course easy enough handled by exchanging $^ with $(filter-out
FORCE,$^), and could be done by your parser. Example:

# ----------------------------------------------------------------------
# -- link O_TARGETs

__o_link_cmd = $(if $(filter-out FORCE,$^),$(LD) $(EXTRA_LDFLAGS_$(@D)) -r -o $@ 
$(filter-out FORCE,$^),$(AR) rcs $@)

define __o_link_rule
        $(V1) Linking built-in $@ ...
        $(V2) $(__o_link_cmd)
        rm -f $@
        $(__o_link_cmd)
        echo 'COMMAND_$@ := $(__o_link_cmd)' > $(@D)/.$(@F).command
endef

$(O_TARGETS): FORCE
        @$(if $(strip $? $(filter-out $(__o_link_cmd),$(COMMAND_$@)) $(filter-out 
$(COMMAND_$@),$(__o_link_cmd))),$(__o_link_rule))

Of course, this means that make will remake every single target, but most
of the time, the commands to execute are empty, which means that we don't
need to fork etc. The overhead of calculating the dependencies for the
entire tree seems to be where the most time is spent, so a "make
installable" equivalent with my typical config takes about 5 secs, when
nothing needs to be rebuilt. (laptop iwth PIII 600, hot cache)
make has to consider a full dependency tree here, though,  not only
directly included files, but the "real thing", as mentioned above, that is
all files which are read when executing a command. This means that I even
get modversions etc. right. Well, there's for sure still bugs in there,
so this may turn out to be not entirely true, but the concept allows for
this kind of provable correctness.

Maybe I should mention that I achieve this without relying on any new
external tools/parsers/whatever, except for a mkdep replacement, which is
basically mec's dancing Makefile's fix_dep program, that handles the
splitted autoconf.h :)

Did I attract anybody's attention?

--Kai


_______________________________________________
kbuild-devel mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/kbuild-devel

Reply via email to