c语言 - MinGW GCC - 未定义对"退出"的引用



我正在尝试将一个大型项目与 MinGW 的 GCC 4.8.1 链接起来,以实现 x86 目标。我像这样调用链接器

D:MyGCCPathgcc -L [LIBPATHS]  -nostdlib -Wl,-Map,D:PathToMapFile.map,--emit-relocs [OBJECTFILES AND LIBS] -lmsvcrt -lgcc -o D:PathToMyOutputFile

通过这个调用,我得到了这个链接器rror:

libgcc.a(__main.o):(.text+0x5a): undefined reference to `atexit'

我尝试了不同的msvcr版本(100 和 90),但这更像是一种绝望的尝试,因为我对这个问题不是很熟悉。我使用的是MinGW提供的正确库。有什么方法可以解决此错误吗?

您正在与-nostdlib链接,并且atexit()是来自stdlib.h的函数。

根据 GCC 链接选项:

-nostdlib

链接时不要使用标准系统启动文件或库。不会将启动文件传递到链接器,并且仅将指定的库传递到链接器,并且将忽略指定系统库链接的选项(如 -static-libgcc-shared-libgcc)。

库按命令行上使用的顺序进行检查,因此请使用 -lgcc -lmsvcrt

你和余浩的评论链中的推理是完全正确的。

您需要导入带有-lmsvcr120 libmsvcr120.a才能获得atexit符号。

您可能还需要其中的一些,具体取决于您引用的符号,但这是基于非常简短地浏览源代码的推测,clang/lib/Driver/ToolChains字符串OPT_nostdlib

  • lgcc_eh
  • lgcc_s
  • lgcc
  • lgomp
  • liomp5md
  • lmingw32
  • lmingwex
  • lmingwthrd
  • lmoldname
  • lmsvcr100
  • lmsvcr110
  • lmsvcr80
  • lmsvcr90
  • lmsvcrt-os
  • lomp
  • lssp_nonshared
  • lssp

通常,您可以通过在您拥有的所有库(例如x86_64-w64-mingw32lib)上调用 MinGW 的 nm.exe(或 Linux 上的 GNU nm)并将输出管道传输到文本文件来找到哪些库包含您要查找的符号。你会得到几十万行这样的文本,你可以搜索:

libmsvcr120_defs01591.o:
0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 i .idata$4
0000000000000000 i .idata$5
0000000000000000 i .idata$6
0000000000000000 i .idata$7
0000000000000000 t .text
0000000000000000 I __imp_atexit
                 U _head_lib64_libmsvcr120_def_a
0000000000000000 T atexit

T atexit(大写T)表示要导出的符号,其定义在.text部分中。

如果你看到U atexit,这意味着"我不知道atexit在哪里,但这里需要它"。如果导入库仅包含带有 U atexit 的行,则定义不在该导入库中。

您会注意到atexit也由 libmsvcr120d.a 定义,这是 libmsvcr120.a 的调试版本,并由 libmsvcr120_app.a 定义,这是(据我收集)在 Windows 应用商店上分发可执行文件时要链接的版本。

相关内容

最新更新