如何在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.dll
和libgcc_s_sjlj-1.dll
,但我找不到使用libwinpthread-1.dll
执行相同操作的命令。
【问题讨论】:
只是为了技术上的清晰,如果你是静态链接,你没有链接到 DLL。libgcc
和 libstdc++
库有静态和非静态 (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++-posix
和 i686-w64-mingw32-g++-win32
。在我的构建环境中,我指定了CXX=/usr/bin/i686-w64-mingw32-g++-win32
。【参考方案9】:
只需链接-l:libwinpthread.a
【讨论】:
以上是关于如何在mingw中进行libwinpthread-1.dll的静态链接?的主要内容,如果未能解决你的问题,请参考以下文章