woohoos
woohoos

Reputation: 43

makefile issues multiple definitions

I'm learning how to use makefile however after a few hours of research and still being stuck I just can not manage to resolve what is wrong with my makefile:

output: main.o module.o
    g++ main.o module.o  -o output
main.o: module.cpp module.h
    g++ -c module.cpp
module.o: module.cpp module.h
    g++ -c main.cpp

my main.cpp file has #include "module.cpp" my module.cpp file has #include "module.h"

after attempting to execute my makefile i get lots of "multiple definitions of" and "undefined references"

help will be highly appreciated

p.s code in codeblocks works flawlessly, that's why i am so confused. i am using mingw32-make

Upvotes: 3

Views: 657

Answers (2)

jfMR
jfMR

Reputation: 24738

You are getting "multiple definition errors" becasue you are linking module.o and main.o together but your main.cpp already includes module.cpp. Do not include module.cpp in main.cpp (i.e.: remove the #include "module.cpp directive inside main.cpp). Since main.o won't depend then on module.cpp, you should remove that prerequisite from the main.o rule as well.

Also, consider using GNU Make's automatic variables instead of hard-coded filenames and predefined variables (i.e.: CXX) instead of hard-coded commands (i.e.: g++):

output: main.o module.o
    $(CXX) $^  -o $@

main.o: main.cpp module.h
    $(CXX) -c $<

module.o: module.cpp module.h
    $(CXX) -c $<

Or even better, rely on the predefined pattern rule for generating .o files from .cpp files:

output: main.o module.o
    $(CXX) $^  -o $@

main.o: module.h
module.o: module.h

Note that failing to provide the last two lines will cause main.o and module.o to be still up-to-date (i.e.: not being rebuilt) even though module.h changes.

Upvotes: 4

activout.se
activout.se

Reputation: 6106

Thanks to implicit rules in Makefiles, this should be enough:

output: main.o module.o
    g++ main.o module.o  -o output

The implicit rules allows make to know how to create .o files from .cpp files.

But this could be even simpler:

output: main.o module.o
    $(CXX) -o $@ @^

$(CXX) is your C++ compiler, usually g++

$@ is an automatic variable of the target (value before the colon)

@^ is an automatic variable of the prerequisites (values after the colon)

Upvotes: 2

Related Questions