[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

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

Posted on 2004-10-25
16
Medium Priority
?
353 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
Comment
Question by:Risky101
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
16 Comments
 
LVL 23

Expert Comment

by:brettmjohnson
ID: 12407696
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
ID: 12407859
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
ID: 12408998
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
 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

 
LVL 12

Expert Comment

by:stefan73
ID: 12409040
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
ID: 12415963
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
ID: 12417429
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
ID: 12417609
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
ID: 12419692
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
ID: 12426926
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
ID: 12431152
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
ID: 12431170
Ouch - comment out the ".SUFFIXES" lines. Otherwise .dep files will be ignored.
0
 

Author Comment

by:Risky101
ID: 12438907
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
ID: 12441981
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:
stefan73 earned 900 total points
ID: 12442057
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

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
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…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Suggested Courses

649 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