[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:

                @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


  -include include2

            $(MAKE) INCLUDE2_RECURSION=true include2


                @echo 'B := $$(A)' > $@


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:            
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist

reply via email to

[Prev in Thread] Current Thread [Next in Thread]