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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:57:52  来源:igfitidea点击:

makefile error: undefined reference to main

c++makefile

提问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 mainfunction. In the above case, the main function is not defined in db.cppand hence although compilation succeeds, the linker throws an error as it cannot find the mainfunction.

链接文件时,链接器需要一个且只有一个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 makesubstitute the file names for you. Ask if you want more datails on it.

此外,由于您所有的“*.o: *.cpp”规则都是相同的,您可以指定一个规则并让我们make为您替换文件名。询问您是否想要更多数据。