9

I am trying to compile my piece of code using make. Normally I compile my code like this:

mipsisa32r2el-timesys-linux-gnu-g++ -o testing -I/usr/include/libxml2 -L/develop/xc4/rootfs/parsecpp/lib -L/develop/xc4/rootfs/parsecpp/sqlite-mips2/lib -I/develop/xc4/rootfs/parsecpp/sqlite-mips2/include db.cpp main.cpp networkinterfacemodule.cpp network.cpp multiplex.cpp program.cpp service.cpp -lsqlite3 -lxml2

To get rid of this long command I tried to write a makefile:

CC= mipsisa32r2el-timesys-linux-gnu-g++

export LD_LIBRARY_PATH=:/parsecpp/sqlite-mips2/lib:/parsecpp/lib:/tmp/vixs_temp/DirectFB/single_core/lib


CFLAGS=-I/usr/include/libxml2 -I/develop/xc4/rootfs/parsecpp/sqlite-mips2/include

LDFLAGS=-L/develop/xc4/rootfs/parsecpp/lib -L/develop/xc4/rootfs/parsecpp/sqlite-mips2/lib

LIBS = -lsqlite3 -lxml2

PROG=testing

all: main.o db.o mod.o multiplex.o network.o networkinterfacemodule.o program.o service.o
    $(CC) -o $(PROG) $(CFLAGS) $(LDFLAGS)  main.o db.o mod.o multiplex.o network.o networkinterfacemodule.o program.o service.o $(LIBS) 

main.o: main.cpp 
    $(CC) $(CFLAGS) $(LDFLAGS) main.cpp db.cpp networkinterfacemodule.cpp mod.cpp multiplex.cpp network.cpp program.cpp service.cpp $(LIBS)

db.o: db.cpp 
    $(CC) $(CFLAGS) $(LDFLAGS) db.cpp $(LIBS)


mod.o: mod.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) mod.cpp $(LIBS)

multiplex.o: multiplex.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) multiplex.cpp $(LIBS)

network.o: network.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) network.cpp $(LIBS)

networkmoduleinterface.o: networkinterfacemodule.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) networkinterfacemodule.cpp $(LIBS)

program.o: program.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) program.cpp $(LIBS)

service.o: service.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) service.cpp $(LIBS)

clean:
    rm -rf *o testing

Then I get this error:

/opt/timesys/linux-gnu/toolchain/bin/../../toolchain/lib/crt1.o: In function `__start':
(.text+0xc): undefined reference to `main'
/opt/timesys/linux-gnu/toolchain/bin/../../toolchain/lib/crt1.o: In function `__start':
(.text+0x10): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [db.o] Error 1

Can anybody help me?

razlebe
  • 7,134
  • 6
  • 42
  • 57
nic
  • 125
  • 1
  • 3
  • 7

3 Answers3

26

Whenever you are just compiling a file and not linking it, use the "-c" flag.

For example :-

db.o: db.cpp 
$(CC) -c $(CFLAGS) $(LDFLAGS) db.cpp $(LIBS)

Also, while compiling, there's no need to provide "$(LIBS)" to the compiler, only provide them when linking. Nor do you need the linker flags since linker is not called when using the "-c" flag.

So you could write,

 db.o: db.cpp 
 $(CC) -c $(CFLAGS) db.cpp

UPDATED (based on comments):-

When linking the files, the linker expects one and only one main function. In the above case, the main function is not defined in db.cpp and hence although compilation succeeds, the linker throws an error as it cannot find the main function.

unkulunkulu
  • 11,576
  • 2
  • 31
  • 49
rajatkhanduja
  • 974
  • 1
  • 9
  • 28
  • That is okay. But the question is : why linking would fail if OP does that? – Nawaz Jun 27 '12 at 11:31
  • 1
    +1 Addtitionally, you can avoid much of the cost of writing the makefile by writing rules (or letting the default rules work. – David Rodríguez - dribeas Jun 27 '12 at 11:32
  • 4
    @Nawaz: If you try to *link* every translation unit by itself the linker will fail to find the `main` function, that is present only in one of the translation units. – David Rodríguez - dribeas Jun 27 '12 at 11:32
  • C/C++ programs require a starting point, which is the `main` function. When a program is compiled *and* linked, the compiler requires this "main" function to be defined. In your case, an individual file is being compiled and linked, but it doesn't contain the "main" function (that is what I assume from the error), hence the error. – rajatkhanduja Jun 27 '12 at 11:33
  • @DavidRodríguez-dribeas, I guess Nawaz knows it, he just wants this to be a part of the answer. – unkulunkulu Jun 27 '12 at 11:33
  • @rajatkhanduja, you should add this to the answer itself instead of the comments. – unkulunkulu Jun 27 '12 at 11:34
  • @rajatkhanduja yes, you are right, when i change the code it gives me an error and says that main.o no such an file or directory – nic Jun 27 '12 at 11:44
3

When you compile without the -c flag, gcc tries to link the program. Since the main function is most probably in the main.c and not in db.c, the linker fails when searching for the main function in db.c. This means that you need to tell the compiler that you just want output that is not yet linked, but translated into an object file and this is exactly what the -c flag does.

this results in what rajatkhanduja said:

db.o: db.cpp 
$(CC) -c $(CFLAGS) db.cpp
jpe
  • 1,013
  • 6
  • 14
risingDarkness
  • 698
  • 12
  • 25
0

I guess you missed the link rule.

You ought to have a first rule telling make how to link:

testing_OBJECTS = main.o db.o mod.o multiplex.o network.o networkinterfacemodule.o program.o service.o

testing$(EXEEXT): $(testing_OBJECTS)
    ld $(testing_OBJECTS) $(LDFLAGS) $(LIBS)

And this rule must be the precondition to all:

all: testing$(EXEEXT)

Futhermore, as all of your "*.o: *.cpp" rules are identical, you can specify a single rule and let make substitute the file names for you. Ask if you want more datails on it.

j4x
  • 3,595
  • 3
  • 33
  • 64