C++ makefile 错误:对 main 的未定义引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11225118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
makefile error: undefined reference to main
提问by nic
I am trying to compile my piece of code using make. Normally I compile my code like this:
我正在尝试使用 make 编译我的一段代码。通常我编译我的代码是这样的:
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:
为了摆脱这个长命令,我尝试编写一个 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?
有谁能够帮助我?
回答by rajatkhanduja
Whenever you are just compiling a file and not linking it, use the "-c" flag.
每当您只是编译文件而不链接它时,请使用“-c”标志。
For example :-
例如 :-
db.o: db.cpp
$(CC) -c $(CFLAGS) $(LDFLAGS) db.cpp $(LIBS)
Also, while compiling, there's no needto 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.
此外,在编译时,无需向编译器提供“$(LIBS)”,仅在链接时提供。您也不需要链接器标志,因为使用“-c”标志时不会调用链接器。
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.
链接文件时,链接器需要一个且只有一个main
函数。在上述情况下,main 函数未定义db.cpp
,因此尽管编译成功,但链接器由于找不到该main
函数而引发错误。
回答by risingDarkness
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.
当您在没有 -c 标志的情况下进行编译时,gcc 会尝试链接该程序。由于 main 函数很可能在 main.c 中而不是在 db.c 中,因此在 db.c 中搜索 main 函数时链接器失败。这意味着您需要告诉编译器您只需要尚未链接的输出,而是转换为目标文件,而这正是 -c 标志的作用。
this results in what rajatkhanduja said:
这导致了 rajatkhanduja 所说的:
db.o: db.cpp
$(CC) -c $(CFLAGS) db.cpp
回答by j4x
I guess you missed the link rule.
我猜你错过了链接规则。
You ought to have a first rule telling make how to link:
你应该有第一条规则告诉 make 如何链接:
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 thisrule must be the precondition to all
:
而这条规则必须是前提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.
此外,由于您所有的“*.o: *.cpp”规则都是相同的,您可以指定一个规则并让我们make
为您替换文件名。询问您是否想要更多数据。