如何在mingw中进行libwinpthread-1.dll的静态链接?

Posted

技术标签:

【中文标题】如何在mingw中进行libwinpthread-1.dll的静态链接?【英文标题】:how to do static linking of libwinpthread-1.dll in mingw? 【发布时间】:2012-11-25 22:50:34 【问题描述】:

我从这里使用 mingw:http://sourceforge.net/projects/mingwbuilds/files/host-windows/releases/4.7.2/32-bit/threads-posix/sjlj/x32-4.7.2-release-posix-sjlj-rev2.7z/download

我已经成功地使用-static-libgcc -static-libstdc++ 参数静态链接libstdc++-6.dlllibgcc_s_sjlj-1.dll,但我找不到使用libwinpthread-1.dll 执行相同操作的命令。

【问题讨论】:

只是为了技术上的清晰,如果你是静态链接,你没有链接到 DLL。 libgcclibstdc++ 库有静态和非静态 (DLL) 版本,如果您静态链接,则不会链接到 DLL。您希望静态链接到 pthreads 库,而不是 libwinpthread-1.dll(因为您不能静态链接到动态库......这违背了动态库的目的)。 我得到:c++: error: unrecognized command line option '-static-pthreads',和winpthreads一样 小窍门:mingw 自带的 libwinpthread-1.dll 和网上流传的不一样。使用错误的会导致无限递归的 DLL 调用(根据 Dependency walker),然后是堆栈溢出。 只需链接-l:libwinpthread.a 【参考方案1】:

您可能应该查看 GCC 的命令行选项文档。

这些没有“-static-something”命令,只有标准库(libgcc 和 libstdc++)可以通过一个命令设置为静态链接。对于其他库,您首先使用“-static”切换到静态链接,然后使用单独的命令列出要包含的库,即“-lpthread”。

【讨论】:

当我从使用我下载的 mingw 版本切换到 Ubuntu 上 apt-get 安装的版本时,我发现这个问题浮出水面。 apt-get 版本较旧,但我认为问题出在用于构建 mingw 工具集的不同配置。添加“-static -lpthread”解决了这个问题。 libgcc 不是标准库。见here 请告诉我如何使用-static,如果可以的话,我的程序仍然依赖于线程dll。 (我很确定通过放置 -static 你所做的就是让它链接所有静态的东西。你不需要再在它之后放置 -l 库。除非你能告诉我如何让它依赖于一个 dll ,这个答案是不正确的)【参考方案2】:

如果您的工具链包含静态 winpthreads,请添加选项

-static

将拉入所有库的静态版本。

或者,您可以从工具链目录中删除 libwinpthread.dll.a 和 DLL 本身。这可能会弄乱与 libstdc++ 和 libgcc DLL 链接的程序,所以要小心。

第三个选项是使用-Wl,-Bdynamic-Wl,-Bstatic 来选择您想要链接的版本(这是-static 在调用ld 时内部所做的)。一个例子:

gcc -o someexec someobject.o -Wl,-Bdynamic -lsomelibIwantshared -Wl,-Bstatic -lsomelibIwantstatic

如果您运行添加了-v 的链接命令,当您使用-static-libgcc-static-libstdc++ 时,您应该会看到这些选项出现在ld/collect2 调用中。

【讨论】:

【参考方案3】:

只需将-static 添加到您的CFLAGS

例如:./configure CFLAGS="-static"

这会将所有静态库链接到您的可执行文件。

【讨论】:

【参考方案4】:

试试这个:

-static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic

注意-lstdc++ 之前的-lpthread。它对我有用。

确保将其添加到 g++ 命令行的最后。

【讨论】:

不幸的是,这对我不起作用,除非我删除尾随的-Wl,-Bdynamic(这是无稽之谈)。 @rr- 尝试使用 gcc -v 打印出详细信息,发送给我。我会调查的。 我想我明白了...我需要libwinpthread-1.dll,只有当我使用静态libstdc++ 编译时,这意味着在我的环境(arch 和官方存储库)中,libstdc++ 的静态版本取决于共享的 winpthread。为了解决这个问题,我可能需要自己编译 mingw-w64。 @rr- 很高兴你已经弄清楚了。如果你解决了,请告诉我。 (另外,我现在只是在使用 ArchLinux,没有任何问题。) @rr- 我认为您应该添加您的评论作为答案。我浪费了下午的时间来解决这个问题。【参考方案5】:

对于从事 CMake 工作的任何人,此解决方案都可以在您的 CMakeLists.txt 文件中轻松实现,如下所示...

set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -static")

【讨论】:

【参考方案6】:

要静态链接 winpthread,即使程序中没有使用线程,请将 -Bstatic--whole-archive 参数传递给链接器:

g++ -o hello.exe hello.cpp -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive

注意以下几点:

之后应立即禁用“整个存档”选项。 如果您的程序实际使用库中的符号(即您使用 C++11 中的 <thread>),则无需执行此 hack,在这种情况下,静态链接时库不会被删除. 此 hack 适用于 MinGW-w64,用于修复 libwinpthread-1.dll 依赖项。

【讨论】:

这是个好主意,但至少有一个缺点。主要exe 的win32 资源被libwinpthread-1.dll 的资源替换(使用文件资源管理器查看exe 属性;条目涉及libwinpthread-1.dll 而不是hello.exe)。 为我工作,只需要-Bdynamic--no-whole-archive,因为我没有办法将整个位附加到我的命令的最后(工具链的限制),并且最终目标是共享库。【参考方案7】:

显然,CMake 对 -Wl 编译器标志的处理方式做了一些奇怪的事情,使得 -Wl,-Bstatic -lstdc++ -lwinpthread -Wl,-Bdynamic 解决方案不起作用,似乎只剩下两个其他选项:错误的编译器标志 -static 和丑陋的编译器标志-Wl,--whole-archive.

同时,在 CMake 中实际工作但似乎没有记录的好选择是直接使用链接器标志。因此,在 CMake 中,这似乎是静态链接到所有 mingw-w64 C++ 依赖项的最佳方式:

target_link_libraries (MyVeryAwesomeApp -static gcc stdc++ winpthread -dynamic)

应该注意,即使-dynamic 后面没有明确的库,仍应应用它以确保标准的隐式链接库得到正确链接。

【讨论】:

-static -dynamic 将静态链接所有内容,将 -dynamic 放在最后不会做任何事情。事实上,把-static -dynamicdgdf 工作。我找不到关于 -dynamic 选项的文档,只有 -static 选项。你所做的只是-static 和不需要的额外内容。在-static 之后没有额外选项,exe 实际上也更小 @Puddle 如果在-static 之后缺少额外选项时可执行文件更小,请解释一下究竟是如何发生的,如果如您所说,这会使 gcc 静态链接所有内容?我认为一个涉及尝试在没有安装 g++ 工具链的 Windows 实例上运行这样一个较小的可执行文件的实验,在同一目录中没有 gcc、stdc++ 和 winpthread dll,会解释很多。据我了解,target_link_libraries-static-dynamic 选项的作用与没有 CMake 的 -Bstatic-Bdynamic 的行为非常相似。 谢谢 我在尝试使用 OpenGL 为 SDL2 设置开发环境时遇到了这个问题。【参考方案8】:

我通过使用 mingw 工具链的 win32 变体而不是 posix 变体绕过了这个问题。使用 win32 变体,-static-libgcc -static-libstdc++ 足以独立构建。

【讨论】:

怎么选择win32变种? 在 Ubuntu 上,mingw 带有两个编译器 i686-w64-mingw32-g++-posixi686-w64-mingw32-g++-win32。在我的构建环境中,我指定了CXX=/usr/bin/i686-w64-mingw32-g++-win32【参考方案9】:

只需链接-l:libwinpthread.a

【讨论】:

以上是关于如何在mingw中进行libwinpthread-1.dll的静态链接?的主要内容,如果未能解决你的问题,请参考以下文章

部署Qt应用时候报错0xc000007b

windows上如何卸载C语言编译器MinGW?

未找到 MinGW msys 包:一般建议如何进行

Windows系统中如何安装并配置MinGW

Windows系统中如何安装并配置MinGW

如何在 QT Creator 中使用 mingw 在多核上编译