给定一个简单的程序:
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hInstPrev,
LPSTR lpCmdLine, int nCmdShow)
{
return 0;
}
如果我跑g++ a.cpp
效果很好。
然而,运行g++ -c a.cpp && ar rcs a.a a.o && g++ a.a
给出以下错误:
c:/mingw32/bin/../lib/gcc/i686-w64-mingw32/4.8.1/../../../../i686-w64-mingw32/lib/../lib/libmingw32.a(lib32_libmingw32_a-crt0_c.o):crt0_c.c:(.text.startup+0x39): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status
任何关于为什么会发生这种情况的见解?如何链接仅包含 .a 文件的程序?
The gcc ld
链接器句柄*.a
静态库与*.o
对象文件。特别是静态库中的符号do not除非先前链接的目标文件或另一个静态库使用它,否则将被包含到最终的二进制映像可执行文件中。
此外,您在静态库中传递的顺序也很重要ld
。例如,说libb.a
需要一个函数liba.a
。如果你像这样链接它:
g++ -Wall 示例.cpp -o 示例.exe -la -lb
这将无法解决,因为当liba
已处理它看不到什么符号-lb
需要 (libb
尚未处理)。唯一检索到的符号liba.a
是它所看到的一切那一点.
为什么这很重要?
如果您将上述过程应用于您的问题,就会清楚为什么WinMain
没有得到解决。
g++ a.a
When ld
流程a.a
它说“哦,什么都没用WinMain
所以我不会包括它”;这在处理点上是正确的,因为在它之前没有提供其他目标文件。
上面你看不到的是 mingw 默认情况下,还包括程序运行所需的一堆重要的样板代码。其中之一是crt0_c.o
from mingw32.a
它构成了 mingw 运行时的一部分does打电话给你的WinMain
.
解决方案
有两种方法可以确保WinMain
从你的a.a
被包括在内:
-
Use -Wl,--whole-archive
强制包含所有符号a.a
因此它们可用于符号解析。附加-Wl,--no-whole-archive
之后,这样它就不会错误地将其应用于之后的其他库。例如。
g++ -o example.exe -Wl,--whole-archive a.a -Wl,--no-whole-archive
-
第二种方法是包含mingw32.a
手动before a.a
so WinMain
成为待处理的未解析符号时a.a
被处理:
g++ -o example.exe -lmingw32 a.a
or
g++ -o example.exe libmingw32.a a.a
但您可能需要完全限定路径libmingw32.a
否则链接器将找不到它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)