我正在尝试将一个大型项目与 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 应用商店上分发可执行文件时要链接的版本。