2012-06-27 14 views
8

Estoy tratando de compilar mi código usando make. Normalmente puedo compilar mi código como este:error de archivo MAKE: referencia indefinida al principal

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 

para deshacerse de este comando largo intenté escribir un 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 

Entonces me sale este 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 

Puede alguien me ayude?

+0

Me gusta cómo el archivo MAKE es varias veces más largo que todo el comando. –

+2

'rm -rf * o testing': ¿Realmente desea eliminar todos los archivos y directorios que terminan en el carácter" o "? – sth

+1

@ R.MartinhoFernandes, pero debería ahorrar tiempos de compilación, no es gran cosa.Sin embargo, podría escribirse de forma mucho más compacta, claro. – unkulunkulu

Respuesta

16

Cuando esté compilando un archivo y no vinculándolo, use el indicador "-c".

Por ejemplo: -

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

Además, durante la compilación, no hay ninguna necesidad para proporcionar "$ (LIBS)" para el compilador, sólo proporcionan ellos cuando la vinculación. Tampoco necesita los indicadores del enlazador ya que no se llama al enlazador cuando se usa el indicador "-c".

Por lo que podría escribir,

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

actualizado (basado en los comentarios): -

Al vincular los archivos, el enlazador espera una y sólo una main función. En el caso anterior, la función principal no está definida en db.cpp y, por lo tanto, aunque la compilación tiene éxito, el enlazador arroja un error ya que no puede encontrar la función main.

+0

Eso está bien. Pero la pregunta es: ¿por qué los enlaces fallarían si OP hace eso? – Nawaz

+1

+1 Además, puede evitar gran parte del costo de escribir el archivo MAKE escribiendo reglas (o dejando que las reglas predeterminadas funcionen. –

+4

@Nawaz: Si intenta * vincular * cada unidad de traducción por sí misma, el vinculador no podrá encontrar el función 'main', que está presente solo en una de las unidades de traducción. –

2

Cuando compila sin el distintivo -c, gcc intenta vincular el programa. Dado que la función principal es muy probablemente en main.c y no en db.c, el enlazador falla al buscar la función principal en db.c. Esto significa que debe decirle al compilador que solo desea un resultado que aún no esté vinculado, pero traducido a un archivo de objeto y esto es exactamente lo que hace el indicador -c.

esto se traduce en lo que rajatkhanduja dijo:

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

supongo que se ha perdido la regla de enlace.

Usted debe tener un primer revelador norma crea la forma de enlace:

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) 

Y esta regla debe ser la condición previa para all:

all: testing$(EXEEXT) 

Futhermore, como todos los de su " * .o: * .cpp "las reglas son idénticas, puede especificar una sola regla y dejar que make sustituya los nombres de archivo por usted. Pregunte si quiere más datos sobre él.

Cuestiones relacionadas