NewToAndroid
NewToAndroid

Reputation: 581

Can compile from the commandline but not from a makefile

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

Answers (1)

MadScientist
MadScientist

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 #includeing 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

Related Questions