[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: 'How makefiles are remade'
From: |
Jim |
Subject: |
Re: 'How makefiles are remade' |
Date: |
Wed, 21 Apr 2004 02:43:11 -0700 |
User-agent: |
Mozilla Thunderbird 0.5 (Windows/20040207) |
Paul D. Smith wrote:
Yes it is, if you write it correctly.
(sorry, this is such an attacking statement...)
The correct way being that a makefile includes one and only one other
makefile? I mean sure, if the documentation didn't say if ANY change,
then the make is restrated (one would assume that to imply at the end of
the rule which generates a changed makefile - and maybe that's my error
- but then I still have to submit this as a documentation bug, that it
is unclear that make lacks the functionatilty to cleanly reload product
include files) And yes, when building a project and spontanseously
having .d files populating the direcotyr, these being included, I would
not assume that these should be done... but again, that would typically
be under the section of "Updating goal targets..." when producing object
and as a by product the dependancies thereof. but when in the "Updating
makefiles...." section (as indicated when running with a -d option) I
would think that it would be reasonable to restart the make at the end
of each target which causes an include to change.
j> and what you're really saying is that only the LAST included file
j> can be re-loaded, since ALL includes are read before their
j> dependancies are even checked.
Well, your second statement is true: all includes (that exist) _ARE_
read in first, then make tries to create any included files that were
read (or failed to be read), and if any changed it re-execs itself.
j> And THAT is not at all what the documentation indicates, it says -
j> " if any have actually been changed, make starts with a clean slate and
j> reads all the makefiles over agai"
j> if ANY changed, clean all, and reload all again...
Yes, exactly.
Consider this makefile; it works exactly as you expect (IIUC). The
warning statements prove that make is re-execing at every step:
$(warning Reading makefile)
include first.mk
all:: ; @echo "MAIN"
first.mk:
@echo 'include second.mk' > $@
@echo 'all:: ; @echo FIRST' >> $@
@echo 'first.mk: second.mk' >> $@
@echo 'second.mk:' >> $@
@echo ' @echo "all:: ; @echo SECOND" >> $$@' >> $@
clean: ; rm -f *.mk
Okay. That $(warning reading Makefile) gave me a good idea... There was
definatly some question of order... it seems the last included is the
first checked, unless that depends on the first included....
some later run... TICKS starts at XIV (14)
Makefile:1: Reading makefile
ticks:1: reading ticks
x:1: reading x TICKS=XIV
y:1: reading y
# everything exists at the moment
Makefile:30: making ticks
#yeah something changed, and ticks has to be updated... new value
# will be XV(15) (value at start shown above is XIV(14) )
Makefile:45: making x
#hmm no reload there, therefore TICKS will still be the old value...
x:4: making y with TICKS=XIII
#yeah ticks is definatly not current, having just been remade
# X creates Y with value loaded in last passes X product (not this one)
Makefile:1: Reading makefile
# ahh SO there are times when it really does restart....
ticks:1: reading ticks
x:1: reading x
y:1: reading y
#yeah, okay so everything's current, no updates needed...
Final result in Y is : XIII
# ooo XIII, that would make this 2 steps behind...
In all these examples where all the data is static it's hard to see when
it fails, and it needs to be at least 2 levels to really demonstrate the
problem.
Maybe you could chalk this up to a documentation bug, it says whenever
ANY included makefile is read, it reloads, the above trace indicates
that two rules to generate makefiles were performed before reloading...
Note that in the last @echo line, you have to make sure a TAB character
is inserted in the string that is echoed.
Yes, it's gross, but it does work as you expect. Here's a sample run:
temp$ make
makefile:1: Reading makefile
makefile:3: first.mk: No such file or directory
makefile:1: Reading makefile
first.mk:1: second.mk: No such file or directory
makefile:1: Reading makefile
SECOND
FIRST
MAIN
temp$ make
makefile:1: Reading makefile
SECOND
FIRST
MAIN
I still think you may find using $(eval ...) to be overall simpler.
#include <stdio.h>
int main( int argc, char **argv )
{
int n;
int iscmd = 0;
char cmd[8192];
if( argc < 2 )
{
printf( "usage: echoto [-x] <output> <command line.....>\n" );
printf( "usage: c : prefix with a tab character..\n" );
return 1;
}
n = 1;
while( argv[n][0] == '-' )
{
int c = 1;
while( argv[n] && argv[n][c] ) switch( argv[n][c] )
{
case 'c':
case 'C':
iscmd = 1;
c++;
break;
default:
printf( "Unknown option: %c\n", argv[n][c] );
c++;
break;
}
n++;
}
{
int ofs = 0;
FILE *out = fopen( argv[n], "at+" );
if( !out )
out =fopen( argv[n], "wt" );
if( !out )
{
printf( "echoto: Failed to open %s for output\n",
argv[n] );
return 1;
}
if( iscmd )
fprintf( out, "\t" );
for( n++; n < argc; n++ )
{
fprintf( out, "%s ", argv[n] );
}
fprintf( out, "\n" );
fclose( out );
}
return 0;
}
$(warning Reading makefile)
ifdef __LINUX__
EXEC:=$(QUIET)exec
else
EXIT:=$(QUIET)exit
endif
# need this if $(REMAKE) cause /bin/false deletes this...
.PRECIOUS: x y
MAKEFILE=$(word 1,$(MAKEFILE_LIST))
#$(warning remake will be: $(MAKE) -s -C $(CURDIR) -f $(MAKEFILE)
$(MAKECMDGOALS))
define REMAKE
@--$(QUIETCMD)$(MAKE) -s -C $(CURDIR) -f $(MAKEFILE) $(MAKECMDGOALS)
@/bin/false
endef
.PHONY: fakeall all
fakeall: all ticks x
#fakeall:echoto
#echoto: echoto.c
# @gcc -o $@ $<
include ticks
#.PHONY:ticks
ticks: Makefile bob dillon
$(warning making ticks)
@echo $$(warning reading ticks $$(TICKS))>ticks
@echo TICKS=$(patsubst %ILI,%L,$(patsubst %XXXXIX,%IL,$(patsubst
%IXI,%X,$(patsubst %VIV,%IX,$(patsubst %IVI,%V,$(patsubst
%IIII,%IV,$(TICKS)I))))))>>ticks
@echo Prior Ticks : $(TICKS)
# $(REMAKE)
include x
bob dillon:
@echo . >$@;
x:ticks Makefile bob dillon
$(warning making x)
@echo $$(warning reading x $$(TICKS))>x
@echo include y >>x
@echo y: $@ $? >>x
@echoto -c x $$(warning making y $(TICKS))
@echoto -c x @echo $$$$(warning reading y) \>y
@echoto -c x @echo fakeall: \>\>y
@echoto -c x @./echoto -c y @echo hey we made it:$(TICKS)
# @echo ' $$(REMAKE)' >>x
# $(REMAKE)
Makefile: ;
- Re: 'How makefiles are remade', (continued)
- Re: 'How makefiles are remade', Noel Yap, 2004/04/20
- Re: 'How makefiles are remade', Paul D. Smith, 2004/04/20
- Re: 'How makefiles are remade', Jim, 2004/04/20
- Re: 'How makefiles are remade', Noel Yap, 2004/04/20
- Re: 'How makefiles are remade', Jim, 2004/04/20
- Re: 'How makefiles are remade', Noel Yap, 2004/04/20
- Re: 'How makefiles are remade', Jim, 2004/04/20
- Re: 'How makefiles are remade', Noel Yap, 2004/04/20
- Re: 'How makefiles are remade', Jim, 2004/04/21
- Re: 'How makefiles are remade', Paul D. Smith, 2004/04/21
- Re: 'How makefiles are remade',
Jim <=
- Re: 'How makefiles are remade', Jim, 2004/04/21
- Re: 'How makefiles are remade', Noel Yap, 2004/04/21
- Re: 'How makefiles are remade', Jim, 2004/04/21
- Re: 'How makefiles are remade', Noel Yap, 2004/04/21
- Re: 'How makefiles are remade', Noel Yap, 2004/04/21
- Re: 'How makefiles are remade', Paul D. Smith, 2004/04/21
- Re: 'How makefiles are remade', Noel Yap, 2004/04/21
- Re: 'How makefiles are remade', Jim, 2004/04/23
- Re: 'How makefiles are remade', Jim, 2004/04/21
- Re: 'How makefiles are remade', Jim, 2004/04/21