Reputation: 581
I am trying to compile a program that consists of a main C file and two auxiliary C++ files. Main.c depends on Wrapper.cpp which in turn depends on Utility.cpp. Specifically, Main.c invokes a function func() defined in Wrapper.cpp.
The funny issue is that I can compile the program from the command-line but I can't do so from a makefile. I get a linking error "main.o: reference to func() is undefined". This could be primarily because I understand the notion of makefiles but they can get way too complicated!
Here's how I compile from command-line:
g++ -c Wrapper.cpp Utility.cpp
gcc -c Main.c Wrapper.cpp
g++ -o myProg Main.o Wrapper.o Utility.o
Here's my makefile:
# Rules to produce the targets
all: Main
Main: Utility.o Main.o Wrapper.o
g++ -o myProg Utility.o Main.o Wrapper.o -lstdc++
# Rules to produce the object files
Utility.o: Utility.cpp
g++ -c Utility.cpp
Wrapper.o: Wrapper.cpp Utility.cpp
g++ -c Wrapper.cpp Utility.cpp
Main.o: Main.c Wrapper.cpp
gcc -c Main.c Wrapper.cpp
I know that I might be compiling Utility.cpp and Wrapper.cpp twice but I really don't know how to write the rules to compile. Could someone give me some useful insights. Also please do not give me complicated makefiles because I'm very new to them.
Upvotes: 0
Views: 2160
Reputation: 101081
Your main problem is that you are imagining that source files depend on other source files. That's not true. You don't need the contents of Utility.cpp
to compile Wrapper.cpp
(unless you're doing something strange like #include
ing source files into other source files).
Similarly, object files depend only on the source file that they're compiling, and any headers that source file includes.
And executable files depend on all the object files and libraries needed to build the program.
So in the simplest case you'd write (note you don't need to link with -lstd++
explicitly if you use g++
:
all: Main
Main: Utility.o Main.o Wrapper.o
g++ -o myProg Utility.o Main.o Wrapper.o
# Rules to produce the object files
Utility.o: Utility.cpp
g++ -c Utility.cpp
Wrapper.o: Wrapper.cpp
g++ -c Wrapper.cpp
Main.o: Main.c
gcc -c Main.c
Although this is simple to understand, it really removes most of the power of make. You could write this makefile to get exactly the same results:
CXX = g++
CC = gcc
Main: Main.o Utility.o Wrapper.o
That's it, all done.
Upvotes: 1