【问题标题】:makefile error: undefined reference to mainmakefile 错误:未定义对 main 的引用
【发布时间】:2012-06-27 11:24:18
【问题描述】:

我正在尝试使用 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

为了摆脱这个冗长的命令,我尝试编写一个 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

然后我得到这个错误:

/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

谁能帮帮我?

【问题讨论】:

  • 我喜欢makefile比整个命令长几倍。
  • rm -rf *o testing: 真的要删除所有以“o”结尾的文件和目录吗?
  • @R.MartinhoFernandes,但它应该可以节省编译时间,没什么大不了的。当然,它可以写得更紧凑。
  • @sth 其实没关系
  • %.o:%.cpp,%.h\n\t$(CC) $(CFLAGS) -c -o %<(其中\n 是新行,\t 是制表符)是编译(IIRC,查看手册)的通用规则可以替换所有手动部署的规则来编译每个翻译单元。

标签: c++ makefile


【解决方案1】:

只要您只是编译文件而不链接它,请使用“-c”标志。

例如:-

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

另外,在编译时,不需要向编译器提供“$(LIBS)”,仅在链接时提供。您也不需要链接器标志,因为使用“-c”标志时不会调用链接器。

所以你可以写,

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

已更新(基于 cmets):-

链接文件时,链接器需要一个且只有一个main 函数。在上述情况下,db.cpp 中没有定义 main 函数,因此尽管编译成功,但链接器会抛出错误,因为它找不到 main 函数。

【讨论】:

  • 没关系。但问题是:如果 OP 这样做,为什么链接会失败?
  • +1 此外,您可以通过编写规则(或让默认规则起作用)来避免编写 makefile 的大部分成本。
  • @Nawaz:如果您尝试单独链接每个翻译单元,链接器将无法找到main 函数,该函数仅存在于其中一个翻译单元中.
  • C/C++ 程序需要一个起点,即main 函数。当一个程序被编译链接时,编译器需要定义这个“main”函数。在您的情况下,正在编译和链接一个单独的文件,但它不包含“main”函数(这是我从错误中假设的),因此出现了错误。
  • @DavidRodríguez-dribeas,我想 Nawaz 知道这一点,他只是希望这成为答案的一部分。
【解决方案2】:

当你在没有 -c 标志的情况下编译时,gcc 会尝试链接程序。由于 main 函数很可能在 main.c 而不是 db.c 中,因此在 db.c 中搜索 main 函数时,链接器会失败。这意味着您需要告诉编译器您只需要尚未链接的输出,而是转换为目标文件,而这正是 -c 标志的作用。

这导致了 rajatkhanduja 所说的:

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

【讨论】:

    【解决方案3】:

    我猜你错过了链接规则。

    你应该有第一条规则告诉 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)
    

    并且这个规则必须是all的前置条件:

    all: testing$(EXEEXT)
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多