[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: problems with 'include'
From: |
Paul D. Smith |
Subject: |
Re: problems with 'include' |
Date: |
Sat, 16 Nov 2002 11:52:10 -0500 |
%% Justin Chen-Wells <address@hidden> writes:
jc> Hi, I am having trouble using include. I am trying to get it to
jc> generate two include files, but I want to use variables defined in
jc> one include file as part of the build process for the other.
You will need to do this with a recursive make.
jc> It doesn't always work:
jc> -include include1 include2
jc> display:
jc> @echo A=$(A)
jc> @echo B=$(B)
jc> include1:
jc> @echo "A := hello" > $@
jc> include2:
jc> @echo "B := $(A)" > $@
If you don't need the actual value in the second one, but just to refer
to it, then you're fine. Change the above command line to this:
include2:
@echo 'B := $$(A)' > $@
The "$$" will keep make from expanding that variable, and the
single-quotes will keep the shell from expanding it.
Then the include2 file will contain this:
B := $(A)
rather than this:
B := hello
If that's fine with you, then you're done.
jc> clean:
jc> rm include1 include2
jc> So in the above I am using the value $(A) that is defined in the
jc> first generated make file in the commands that generate the second.
jc> If you run the above it will print out "B=" (empty value) indicating
jc> that $(A) was undefined when it executed the commands for include2.
jc> This would imply that you cannot use elements in an included makefile
jc> in the rules that generate another makefile.
jc> However if you first run "make include1" and then you run "make"
jc> it will display "B=hello" because apparently in that case it DOES
jc> pick up and use the values.
Correct. When make remakes makefiles it proceeds very simply:
1) It reads all the makefiles that exist (since you used -include).
So, if "include1" exists, it will read that (setting the value of
A). If "include2" exists, it reads that as well.
2) After all makefiles are read in, it considers each makefile as a
target, using the normal make algorithms. Basically it's exactly as
if you'd typed "make include1 include2".
3) For each makefile, if make finds a rule to build it and it is deemed
to be out of date, then make executes the rule.
4) After make considers _ALL_ the makefiles, then if _ANY_ of them were
rebuilt, make re-executes itself. It does not just start reading
makefiles over again, it actually replaces the running version of
make with a whole new instance and starts all over, from scratch.
Now go back to #1.
So, you can see that even after you rebuild include1, make does not
actually include it before it builds include2. Only after it builds
both include1 and include2, and re-execs, will it read in the new
version of include1.
jc> How can I get this to work automatically, so that you do not have
jc> to do a "make include1" before making other targets?
If the above solution is not good enough and you need the _actual_
value, then you have two choices.
First, you can use recursion. That is, the rule to build include2
should invoke make recursively; maybe something like:
-include include1
ifndef INCLUDE2_RECURSION
-include include2
include2:
$(MAKE) INCLUDE2_RECURSION=true include2
else
include2:
@echo 'B := $$(A)' > $@
endif
If you have GNU make 3.80, you can use the $(eval ...) function. Note,
though, that there are still some bugs with this which may cause it to
not work for you out of the box; you can apply patches or wait for 3.81
which will fix these bugs.
--
-------------------------------------------------------------------------------
Paul D. Smith <address@hidden> Find some GNU make tips at:
http://www.gnu.org http://make.paulandlesley.org
"Please remain calm...I may be mad, but I am a professional." --Mad Scientist