Solved

Altering a Makefile to add dependencies on the .hxx files?

Posted on 2004-10-25
275 Views
Last Modified: 2010-04-22
Hi,

If I alter the .hxx files, it doesnt recompile the project. How would I add dependencies on the .hxx files?

As an aside, any recommendations on how to make this makefile cleaner?

# makefile on Linux ELF with arm-linux-gcc

# Where the zlib library and include files are located.
ZLIBLIB=./libz/arm/
ZLIBINC=./libz/arm/

ZPNGLIB=./libpng-1.2.5/arm/
ZPNGINC=./libpng-1.2.5/arm/

WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
      -Wmissing-declarations -Wtraditional -Wcast-align \
      -Wstrict-prototypes -Wmissing-prototypes #-Wconversion

CC = arm-linux-gcc
CXX = arm-linux-g++
CFLAGS = -g -Wall -I$(ZLIBINC) -I$(ZPNGINC) -funroll-loops

LDFLAGS=-Wl,-Map,main.map -L. \
  -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBINC)  \
  -L$(ZPNGLIB) -Wl,-rpath,$(ZPNGINC)  \
      -Wl,-rpath,.  \
  -lpng12 -lz -lm -lpthread
      
RM = /bin/rm

OBJS =  \
  Time.o      \
  Global.o
BIN = main

OBJS += $(BIN:=.o)

.SUFFIXES:
.SUFFIXES: .c .cxx .o

.c.o:
      $(CC) $(CFLAGS) ${DEFINES} -c $< -o $@

.cxx.o:
      $(CXX) $(CFLAGS) ${DEFINES} -c $< -o $@

$(BIN): $(OBJS)
      $(CXX) $(OBJS) -o $@ $(LDFLAGS)

clean:
      $(RM) -f $(BIN) $(OBJS)
      #touch *.cxx
      #touch *.hxx
0
Question by:Risky101
    14 Comments
     
    LVL 23

    Expert Comment

    by:brettmjohnson
    The above makefile contains mostly generic rules.
    The only project-specific dependencies are defined in the OBJS and BIN macros.  
    The $(BIN): $(OBJS) dependency line states the output executable binary depends
    upon the object files defined by $OBJS.  However, only a generic rules are specified
    for deriving a .o from a .c or .cxx, and those generic rules do not specify that any
    specific .o file depends upon a particular set of header files in addition to the .c or .cxx
    file.

    You will have to add specific rules to the makefile.  For instance, suppose xyzzy.cxx
    depends upon xyzzy.hxx and foobar.hxx, you will need to add dependency line like:

    xyzzy.o:      xyzzy.cxx xyzzy.hxx foobar.hxx

    0
     

    Author Comment

    by:Risky101
    Thanks - but I still can't work out how to alter the specific makefile, listed above, to add dependencies on the appropriate .hxx files.
    0
     
    LVL 12

    Expert Comment

    by:stefan73
    Hi Risky101,
    Have a look at gcc's -M family of switches:

           -M  Instead of outputting the result of preprocessing, output a rule
               suitable for make describing the dependencies of the main source
               file.  The preprocessor outputs one make rule containing the object
               file name for that source file, a colon, and the names of all the
               included files, including those coming from -include or -imacros
               command line options.

               Unless specified explicitly (with -MT or -MQ), the object file name
               consists of the basename of the source file with any suffix
               replaced with object file suffix.  If there are many included files
               then the rule is split into several lines using \-newline.  The
               rule has no commands.

               This option does not suppress the preprocessor's debug output, such
               as -dM.  To avoid mixing such debug output with the dependency
               rules you should explicitly specify the dependency output file with
               -MF, or use an environment variable like DEPENDENCIES_OUTPUT.
               Debug output will still be sent to the regular output stream as
               normal.

               Passing -M to the driver implies -E, and suppresses warnings with
               an implicit -w.

    That's probably what you're looking for. You can include the generated dependency rules with the "include" command of GNU make. Use "-include" if you don't want to generate errors in case the files are not there yet.

    Check http://www.gnu.org/software/make/make.html for details.

    Cheers!

    Stefan
    0
     
    LVL 12

    Expert Comment

    by:stefan73
    your Makefile additions would look like this:

    DEPS = $(OBJS:.o=.dep)

    -include $(DEPS)

    .c.dep:
        $(CC) $(CFLAGS) -M ${DEFINES} $< -o $@

    .cxx.dep:
        $(CC) $(CFLAGS) -M ${DEFINES} $< -o $@


    Also make sure the rule creating your final binary is your first rule, because that is the default target to build when you just call make without any arguments.
    0
     

    Author Comment

    by:Risky101
    Er, I spent a while on this but couldn't get it to work. I might need a listing of the finished Makefile.
    0
     
    LVL 3

    Expert Comment

    by:guynumber5764
    You could try a hack and change "$(BIN): $(OBJS)" to "$(BIN): $(OBJS) $(HDRS)"  where HDRS =  Time.h  Global.h  (or whatever)

    or you could explicitly write out your rules:

    Global.o: Global.c Global.h
         $(CC) $(CFLAGS) ${DEFINES} -c $< -o $@

    Time.o: Time.c Time.h Global.h
         $(CC) $(CFLAGS) ${DEFINES} -c $< -o $@

    main: Time.o Global.o
         $(CXX) $(OBJS) -o $@ $(LDFLAGS)

    Don't forget to make sure all your [TAB]s are in the right place.  You might even be able to mix and match the general rules (.c.o:) and specific rules but IMO you are better to just use specific rules.
    0
     

    Author Comment

    by:Risky101
    Hi,

    I would prefer to use the -M switch, as it automatically works out the dependencies on the .h files.

    To make it easier, could you cut'n'paste the Makefile below, and add the correct alterations to it, in the correct place.

    # makefile on Linux ELF with arm-linux-gcc

    # Where the zlib library and include files are located.
    ZLIBLIB=./libz/arm/
    ZLIBINC=./libz/arm/

    ZPNGLIB=./libpng-1.2.5/arm/
    ZPNGINC=./libpng-1.2.5/arm/

    WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
         -Wmissing-declarations -Wtraditional -Wcast-align \
         -Wstrict-prototypes -Wmissing-prototypes #-Wconversion

    CC = arm-linux-gcc
    CXX = arm-linux-g++
    CFLAGS = -g -Wall -I$(ZLIBINC) -I$(ZPNGINC) -funroll-loops

    LDFLAGS=-Wl,-Map,main.map -L. \
      -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBINC)  \
      -L$(ZPNGLIB) -Wl,-rpath,$(ZPNGINC)  \
         -Wl,-rpath,.  \
      -lpng12 -lz -lm -lpthread
         
    RM = /bin/rm

    OBJS =  \
      Time.o      \
      Global.o
    BIN = main

    OBJS += $(BIN:=.o)

    .SUFFIXES:
    .SUFFIXES: .c .cxx .o

    .c.o:
         $(CC) $(CFLAGS) ${DEFINES} -c $< -o $@

    .cxx.o:
         $(CXX) $(CFLAGS) ${DEFINES} -c $< -o $@

    $(BIN): $(OBJS)
         $(CXX) $(OBJS) -o $@ $(LDFLAGS)

    clean:
         $(RM) -f $(BIN) $(OBJS)
         #touch *.cxx
         #touch *.hxx
    0
     
    LVL 12

    Expert Comment

    by:stefan73
    Here's the changes. For the first call, you can type "make depend".

    # makefile on Linux ELF with arm-linux-gcc

    # Where the zlib library and include files are located.
    ZLIBLIB=./libz/arm/
    ZLIBINC=./libz/arm/

    ZPNGLIB=./libpng-1.2.5/arm/
    ZPNGINC=./libpng-1.2.5/arm/

    WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
         -Wmissing-declarations -Wtraditional -Wcast-align \
         -Wstrict-prototypes -Wmissing-prototypes #-Wconversion

    CC = arm-linux-gcc
    CXX = arm-linux-g++
    CFLAGS = -g -Wall -I$(ZLIBINC) -I$(ZPNGINC) -funroll-loops

    LDFLAGS=-Wl,-Map,main.map -L. \
      -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBINC)  \
      -L$(ZPNGLIB) -Wl,-rpath,$(ZPNGINC)  \
         -Wl,-rpath,.  \
      -lpng12 -lz -lm -lpthread
         
    RM = /bin/rm

    OBJS =  \
      Time.o      \
      Global.o
    BIN = main

    OBJS += $(BIN:=.o)

    DEPS = $(OBJS:.o=.dep)


    # Change start

    all: $(BIN) depend

    depend: $(DEPS)

    -include $(DEPS)

    .c.dep:
        $(CC) $(CFLAGS) -M ${DEFINES} $< -o $@

    .cxx.dep:
        $(CC) $(CFLAGS) -M ${DEFINES} $< -o $@

    # Change end

    .SUFFIXES:
    .SUFFIXES: .c .cxx .o

    .c.o:
         $(CC) $(CFLAGS) ${DEFINES} -c $< -o $@

    .cxx.o:
         $(CXX) $(CFLAGS) ${DEFINES} -c $< -o $@

    $(BIN): $(OBJS)
         $(CXX) $(OBJS) -o $@ $(LDFLAGS)

    clean:
         $(RM) -f $(BIN) $(OBJS)
         #touch *.cxx
         #touch *.hxx
    0
     

    Author Comment

    by:Risky101
    Hi,

    This doesnt seem to work.If the .cxx files are changed, it recompiles appropriately, if the .hxx files are changed it does not recompile.

    I executed "make depend" before "make". The only way to get it working at the moment is to do a "make clean" then a "make" if any of the .hxx files are changed.

    Shane.

    I'm increasing the points every time - this script is going to work at some point!
    0
     
    LVL 12

    Expert Comment

    by:stefan73
    Did it create the .dep files?
    Did you check the content of $(DEPS)?
    The .dep files should contain the dependency rules of your .hxx files, too. You can simply look into one of them and check if they're there.

    Or do a "make depend" and then replace "-include" by "include" in your make file. In case make complains, something went wrong with file creation.
    0
     
    LVL 12

    Expert Comment

    by:stefan73
    Ouch - comment out the ".SUFFIXES" lines. Otherwise .dep files will be ignored.
    0
     

    Author Comment

    by:Risky101
    Hmmmm ... I think this makefile is a long way off from working.

    It didn't create the .dep files.

    For example:

    .c.dep:
        $(CC) $(CFLAGS) -M ${DEFINES} $< -o $@

    Should be:

    .c.dep:
        $(CC) $(CFLAGS) -M $(LIST_OF_C_FILES)
    0
     
    LVL 12

    Expert Comment

    by:stefan73
    Risky101,
    > Should be:
    >
    > .c.dep:
    >     $(CC) $(CFLAGS) -M $(LIST_OF_C_FILES)

    No, unless you want to create a common dependency file for all your .c/.cxx files. That's a possibility, but you'd normally want this only for small projects, since a single .c file modification will result in a dependency rebuild for all your .c files. If you want that, your rule should be:

    -include common.dep

    common.dep: $(LIST_OF_C_FILES)
         $(CC) $(CFLAGS) -M $(LIST_OF_C_FILES) -o common.dep

    Unless the number of your source files is small, you'd usually want to have seperate dependency files.
    0
     
    LVL 12

    Accepted Solution

    by:
    Try GNU make's static pattern rules:

    DEPS = $(OBJS:.o=.dep)

    -include $(DEPS)

    $(DEPS): %.dep: %.c
        $(CC) $(CFLAGS) -M ${DEFINES} $< -o $@

    $(DEPS): %.dep: %.cxx
        $(CC) $(CFLAGS) -M ${DEFINES} $< -o $@


    $(OBJS): %.o: %.c
         $(CC) $(CFLAGS) ${DEFINES} -c $< -o $@

    $(OBJS): %.o: %.cxx
         $(CXX) $(CFLAGS) ${DEFINES} -c $< -o $@

    ...these work fine for me.
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to run any project with ease

    Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
    - Combine task lists, docs, spreadsheets, and chat in one
    - View and edit from mobile/offline
    - Cut down on emails

    The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
    The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
    In this sixth video of the Xpdf series, we discuss and demonstrate the PDFtoPNG utility, which converts a multi-page PDF file to separate color, grayscale, or monochrome PNG files, creating one PNG file for each page in the PDF. It does this via a c…
    Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

    884 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    18 Experts available now in Live!

    Get 1:1 Help Now