Rajeshwar
Rajeshwar

Reputation: 11671

Is there a way to further shorten and generalize this Makefile

I currently have the following Makefile

test:  main.o car.o student.o   house.o 
    $(CXX) $(CXXFLAGS) -o test main.o car.o student.o house.o
    objcopy --only-keep-debug test test.debug   

main.o: student.h house.h    main.cpp
    $(CXX) $(CXXFLAGS) -c main.cpp

car.o: car.h
student.o: student.h car.h
house.o: house.h 

My question is can I shorten the file as to something like

test:   *.o 
        $(CXX) $(CXXFLAGS) -o test *.o
        objcopy --only-keep-debug test test.debug   

How would the target dependency work? The reason I am thinking about pursuing something like this is because I would not like to add stuff to my Makefile everytime I add a new header or cpp file?

Upvotes: 0

Views: 1137

Answers (3)

Mark Galeck
Mark Galeck

Reputation: 6405

It is a good idea to "add stuff to Makefile everytime I add a cpp file", and you should convince yourself to it.

The first reason is, if you change the Makefile everytime you change source list, and you depend the targets on the Makefile, then the targets will automatically recompile when you change the source list, as they should, and that is the way Make was designed to work. Don't fight it.

The second reason is, you want to declare your sources explicitly somewhere, so you can clarify your intentions to yourself and others. My practice shows this makes code more maintainable.

The third reason is, so you can add other files, perhaps temporary, with the same extensions, which are not sources.

Bearing that in mind, here I think is the best way to rewrite your Makefile. Note that I did not do any automatic dependency generation here. If you do that, then instead of listing various dependencies of .o files on .h files, you would have them generated automatically, as others pointed out.

SRCS := main.cpp car.cpp student.cpp house.cpp

OBJS := $(SRCS:cpp=o)

.PHONY: all
all: test test.debug

test:  $(OBJS) Makefile 
    $(CXX) $(CXXFLAGS) -o $@ $(OBJS)

%.debug: % Makefile
    objcopy --only-keep-debug $< $@  

$(OBJS): %o: %cpp Makefile
    $(CXX) $(CXXFLAGS) -c $< 

main.o: student.h house.h

car.o: car.h

student.o: student.h car.h

house.o: house.h 

Upvotes: 0

Deduplicator
Deduplicator

Reputation: 45704

This might do what you want, with automatic dependency recomputation:

CPPFLAGS += -MMD
SOURCES = $(wildcard *.C *.c *.cpp *.cxx *.c++)
OBJECTS = $(addsuffix .o,$(basename $(SOURCES)))
.PHONY: all
all: appname appname.debug
appname.debug: appname
    objcopy --only-keep-debug $< $@
appname: $(OBJECTS)
include *.d

See https://gcc.gnu.org/onlinedocs/gcc-4.9.1/gcc/Preprocessor-Options.html#Preprocessor-Options for the -MMD-option, which on compilation extracts dependencies to .d-files

I computed all possible source-files and from them all object-files, because *.o would only match already existing files.

Upvotes: 1

Etan Reisner
Etan Reisner

Reputation: 81042

You absolutely can use test: *.o in a makefile.

You likely don't want to though. That will never include .o files for newly created .c files as they will not exist.

You can do away with listing each file in the recipe body though by using the $^ automatic variable.

Upvotes: 0

Related Questions