[opensuse-programming] make - simple vs. recursive variables
All, I think I'm seeing something odd in 'make': Makefile#1: ALLDOMAIN:=alldomains.list #ALLDOMAIN:=$(shell mktemp alldomain.XXXXXX) .PHONY: $(ALLDOMAIN) .SILENT: $(ALLDOMAIN) $(ALLDOMAIN): <commands to produce the file> >$@ include $(ALLDOMAIN) The $(ALLDOMAIN) file defines a target named 'alldomains', so I should now be able to do "make -f Makefile#1 alldomains". Except - when ALLDOMAIN is a simple variable (assigned with :=) it doesn't work. The 'alldomains' target can not be found. When ALLDOMAIN is a recursive variable it works fine .... I need ALLDOMAIN to be set up only once - see the commented out line that gives me a temp file. What am I doing wrong here? /Per Jessen, Zürich --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
Per Jessen wrote:
I think I'm seeing something odd in 'make':
Makefile#1:
ALLDOMAIN:=alldomains.list #ALLDOMAIN:=$(shell mktemp alldomain.XXXXXX)
.PHONY: $(ALLDOMAIN) .SILENT: $(ALLDOMAIN)
$(ALLDOMAIN): <commands to produce the file> >$@
include $(ALLDOMAIN)
The $(ALLDOMAIN) file defines a target named 'alldomains', so I should now be able to do "make -f Makefile#1 alldomains".
Except - when ALLDOMAIN is a simple variable (assigned with :=) it doesn't work. The 'alldomains' target can not be found.
When ALLDOMAIN is a recursive variable it works fine ....
I need ALLDOMAIN to be set up only once - see the commented out line that gives me a temp file.
Correction - if I skip the tempfile setup and just have a fixed name for ALLDOMAIN, it works fine either way. It's when I go back to getting a tempfile that it stops working. /Per Jessen, Zürich --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
Per Jessen wrote:
I think I'm seeing something odd in 'make':
Makefile#1:
ALLDOMAIN:=alldomains.list #ALLDOMAIN:=$(shell mktemp alldomain.XXXXXX)
.PHONY: $(ALLDOMAIN) .SILENT: $(ALLDOMAIN)
$(ALLDOMAIN): <commands to produce the file> >$@
include $(ALLDOMAIN)
[...]
What am I doing wrong here?
I think make and this Makefile do not work in the way you expect them to work. When you enter "make alldomains", then make starts to parse the Makefile (see [1]) and after some time finds the include statement. The file alldomains.list does not exist on disk at that point, so it's content cannot be included. This is no immediate error for make (you should get a warning though, see [2]), it continues parsing the Makefile. At the end, it looks for a rule to generate the file to be included because make determined that it is a dependency. This rule exists, so make goes off and generates the file alldomains.list which will (according to your description) contain a rule called "alldomains". Finally, make now tries to execute the rule "alldomains" - however, you should note that at this point the content of the alldomains.list file has still not been included in the Makefile (make parses a Makefile only once). Therefore, make aborts and you should get an error message like "no rule to make target alldomains" (see [2]). If you have a look at the directory, then you should observe that the include file alldomains.list has been generated (see [3]). If you run "make alldomains" a second time, it will work because now the include file exists when make parses the Makefile and therefore it knows about the target (see [4]). Regards, Thomas $[1]> cat Makefile ALLDOMAIN := alldomains.list .PHONY: $(ALLDOMAIN) $(ALLDOMAIN): ; @echo "alldomains: ;" > $@ @echo -e "\t@echo \"hello, world!\"" >> $@ include $(ALLDOMAIN) $[2]> make alldomains Makefile:9: alldomains.list: No such file or directory make: *** No rule to make target `alldomains'. Stop. $[3]> ls alldomains.list Makefile $[4]> make alldomains hello, world! $> --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
Thomas Hertweck wrote:
I think make and this Makefile do not work in the way you expect them to work.
Thanks for the explanation, but according to the make manual, make _will_ reparse the Makefile(s) if one of them is changed on the first pass: (see the text in ////).
From "3.7 How Makefiles Are Remade"
Sometimes makefiles can be remade from other files, such as RCS or SCCS files. If a makefile can be remade from other files, you probably want make to get an up-to-date version of the makefile to read in. To this end, after reading in all makefiles, make will consider each as a goal target and attempt to update it. If a makefile has a rule which says how to update it (found either in that very makefile or in another one) or if an implicit rule applies to it (see section Using Implicit Rules), it will be updated if necessary. After all makefiles have been checked, //if any have actually been changed, make starts with a clean slate and reads all the makefiles over again.// (It will also attempt to update each of them over again, but normally this will not change them again, since they are already up to date.) Your example/explanation was good, but why does make not reparse as it should? If you cannot rely on make doing that, how can you have makefiles that generate their own dependencies for a compile for instance? Here's an example of make re-executing due to an included file changing: per@io:~/workspace/bulwark/klop99> make -r -d GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This program built for i686-pc-linux-gnu Reading makefiles... Reading makefile `Makefile'... Reading makefile `depend' (search path) (no ~ expansion)... Makefile:15: depend: No such file or directory Updating makefiles.... Considering target file `depend'. File `depend' does not exist. Finished prerequisites of target file `depend'. Must remake target `depend'. gcc -M -c *.c >depend Putting child 0x0807ab88 (depend) PID 6235 on the chain. Live child 0x0807ab88 (depend) PID 6235 Reaping winning child 0x0807ab88 PID 6235 Removing child 0x0807ab88 PID 6235 from chain. Successfully remade target file `depend'. Considering target file `Makefile'. Looking for an implicit rule for `Makefile'. No implicit rule found for `Makefile'. Finished prerequisites of target file `Makefile'. No need to remake target `Makefile'. Re-executing[1]: make -r -d GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. /Per Jessen, Zürich --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
Per Jessen wrote:
Your example/explanation was good, but why does make not reparse as it should? If you cannot rely on make doing that, how can you have makefiles that generate their own dependencies for a compile for instance?
OK, I've found the answer, although I'm sure about the explanation. I had the included file listed with .PHONY. The intention was for it to be rebuilt every time. When I tried with a Makefile for a regular compile-link job, everything worked fine - only because the included dependencies file was not listed with .PHONY. I'm guessing that make would start looking if it had to restart/reparse everytime a .PHONY target was remade ... /Per Jessen, Zürich --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
Per Jessen wrote:
Thomas Hertweck wrote:
I think make and this Makefile do not work in the way you expect them to work.
Thanks for the explanation, but according to the make manual, make _will_ reparse the Makefile(s) if one of them is changed on the first pass: [...]
No, you declared ALLDOMAIN as PHONY target. make will not re-execute in this case. When targets are declared as PHONY, make will not consider them as actual files (that's the whole purpose of declaring something PHONY). Cheers, Thomas --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
participants (2)
-
Per Jessen
-
Thomas Hertweck