views:

321

answers:

5

Is it possible to get the "full" makefile if makefile contains "include"? For example:

   #here is the contents of Makefile
   include inc1.i
   include inc2.i
   clean:
       rm -rf *

   #here is the contents of inc1.i
   abc:
      touch abc

   #here is the contents of inc2.i
   def:
      touch def

How can I get a "full" Makefile without include? Because when Makefile include other inc, and inc file also include another sub-inc ... it is very hard to read!

I want to get a "full" makefile like:

   abc:
      touch abc
   def:
      touch def
   clean:
       rm -rf *
+3  A: 

When using GNU make, I often found output from make -p very useful (it will contain more than what you asked for).

Employed Russian
A: 

For debugging Makefiles with GNU Make, you can use

make -p

to print the (entire!) make database, after make finishes processing everything in your Makefiles. See the GNU Make manual: Options Summary (this is info node "(make)Options Summary").

It is probably a lot more information than you asked for -- you may have to dig to find what you need.


Note that using the C preprocessor ("cc -E") will not work for handling Makefile includes: C preprocessing handles "#include", while Makefile processing requires handling "include" and "-include".

ariels
A: 

It sounds to me like you want to teach your editor how to be 'smart' enough to recombine all of the included bits into one big makefile, or at least provide convenient access to the external stuff within the 'grand' makefile. Perhaps with logic to know what file to save which edit? Its a great dream!

For that, you'd have to check with the developers / vendor of your editor / IDE.

What I can say is, the only 'good' reason for breaking out various bits of business in separate included segments is conditional compilation. For instance, if you are using chunks of a diet C library to replace some of the stuff that the host system provides .. you'll want to include targets to do that based on the architecture and possibly OS distributor. That's when it makes sense to break it out .. let the ARM maintainers adjust their own targets and dependencies, just like the amd64 and ia32 folks would. When you do this and keep the logic that decides what to include in the central makefile, the logic is very easy to follow.

People who do it just to make the main Makefile appear smaller and easier to read are doing exactly what you say, making things more difficult in an effort to make something inherently inelegant appear elegant.

It frustrates me too, at times, even though I'm guilty of doing it in earlier projects :)

Tim Post
A: 

G'day,

I find entering make -np 2>&1 | tee results to check the makefile behaviour before you execute the make itself to be very useful. (Assuming bash, zsh or something similar for the dupe of stderr on to stdout.)

N.B. Only time this doesn't work properly is if the makefile contains a command to create a local code env.,e.g. untarring a tarball or making recursive copy of a source tree, before entering and running a recursive make. For those instances perform the analysis in two stages, namely:

  1. create the local copy as required and comment out the "cp -r" or "tar -xvf" command as applicable in the makefile, and
  2. now execute your make -np 2>&1 | tee results command as before.

BTW This was the only way I got to understand what was happening with building an awesome project that had 20+ makefiles for about 2,500 kSLOC of code. The build also had code generation phases, just to make life more interesting. (-:

HTH

Rob Wells
A: 

You can do something like the following to actually get what you want.

% cat include.mk
define include-func
dummy:=$(shell cat $(1) > /dev/stderr )
include $(1)
dummy:=$(info include-func $(1) evaled, going to be included)
endef

dummy:=$(eval $(call include-func,include1.mk))
dummy:=$(eval $(call include-func,include2.mk))


all: include1-target include2-target
        #all done
% cat include1.mk
dummy:=$(info include1 being included)

include1-target:
        @echo include1-target executed
% cat include2.mk
dummy:=$(info include2 being included)

include2-target:
        @echo include2-target executed

actual output:

% make -f include.mk  all
dummy:=$(info include1 being included)

include1-target:
        @echo include1-target executed
include-func include1.mk evaled, going to be included
include1 being included
dummy:=$(info include2 being included)

include2-target:
        @echo include2-target executed
include-func include2.mk evaled, going to be included
include2 being included
include1-target executed
include2-target executed
#all done
holmes