The current kbuild tracks changes to CFLAGS and related variables via
the %.o: %.c rule in Rules.make and forces a recompile if the flags
have changed. This rule, like much of kbuild, does about 90% of the
job but I want 100% accuracy. The existing rule only checks flags and
does not detect changes to CC. Also it does not support user commands
at all. Some user commands attempt to auto detect changes (msndperm.c
in drivers/sound/Makefile) but it is ugly, the majority of user defined
commands do not detect changes to their commands.
I have code that works 100% and handles user commands but I am not
happy with it so I am looking for alternatives or suggestions to make
it cleaner. The problem is the scope of variables such as $< and $@,
they are only valid after make has decided to rebuild a target. Since
the whole point of auto detection is to decide if a target needs to be
rebuilt, it follows that the detection method cannot use $<, $@ etc.
Take an existing 2.5 user defined rule.
objfile(System.map): objfile(vmlinux)
$(NM) $< | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw]
\)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > $@
My aim is to detect if the command has changed and force the target to
be rebuilt. This is just a specific example of a general problem, how
to detect if user defined targets need to be rebuilt, so don't get
bogged down in arguments about "that command never changes". My
current code uses
usercommand(target (source list) command and options)
and usercommand() expands into
KCN.target := command and options
ifneq ($(KCO.target),$(KCN.target))
target: FORCE_BUILD
endif
target: source list
@rm -f target.d
$(KCN.target)
@echo 'KCO.target := $(subst $$,$$$$,$(subst ','"'"',$(KCN.target)))' >>
target.d
KCN and KCO stand for kbuild command new and old respectively. KCN is
the command we would use if the target were rebuilt. KCO is the
command that was used last time, read from the .d file when the global
makefile is built.
$(subst ','"'"',$(KCN.target) replaces ' in the command with '"'"' to
satisfy the shell quoting rules, the entire command is enclosed in ''.
Then $(subst $$,$$$$,...) replaces each $ with $$ so when the command
is read back by make it generates $ again.
Replace the System.map rule with
usercommand(objfile(System.map) (objfile(vmlinux)) \
$(NM) source() | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw]
\)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > target())
Note the use of source() and target() in the user command. Because
KCN.target is defined in make scope, not command scope, variables $<
and $@ are not available. I could emulate $@ and $< in usercommand()
as target and the first entry in source list, but it runs the risk of
developers trying to use other make variables in usercommand() when
they are not supported.
usercommand() for System.map expands into
KCN.objfile(System.map) := $(NM) objfile(vmlinux) | grep -v
'\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort >
objfile(System.map)
ifneq ($(KCO.objfile(System.map)),$(KCN.objfile(System.map)))
objfile(System.map): FORCE_BUILD
endif
objfile(System.map): objfile(vmlinux)
@rm -f objfile(System.map).d
$(KCN.objfile(System.map))
@echo 'KCO.objfile(System.map) := $(subst $$,$$$$,$(subst
','"'"',$(KCN.objfile(System.map))))' >> objfile(System.map).d
As I said, this works for user commands and detects changes to the
entire command, not just the flags. But it is not very nice to look
at, can anybody see a better way of doing this? Remember that users
and most developers will only see usercommand(), most people will not
care how messy the generated global makefile is.
Life would be so much easier if make had $(eval).
_______________________________________________
kbuild-devel mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/kbuild-devel