我从这里使用 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
我已经成功地使用
libstdc++-6.dll
参数静态链接 libgcc_s_sjlj-1.dll
和 -static-libgcc -static-libstdc++
,但我找不到对 libwinpthread-1.dll
执行相同操作的命令。
如果您的工具链包含静态 winpthreads,请添加选项
-static
将拉入所有库的静态版本。
或者,您可以从工具链目录中删除 libwinpthread.dll.a 和 DLL 本身。不过,这可能会弄乱与 libstdc++ 和 libgcc DLL 链接的程序,所以要小心。
第三个选项是使用
-Wl,-Bdynamic
和 -Wl,-Bstatic
来选择要链接的版本(这是 ld 被调用时 -static
在内部执行的操作)。一个例子:
gcc -o someexec someobject.o -Wl,-Bdynamic -lsomelibIwantshared -Wl,-Bstatic -lsomelibIwantstatic
如果您在添加了
-v
的情况下运行链接命令,则当您使用 -static-libgcc
和 -static-libstdc++
时,您应该会看到这些选项出现在 ld/collect2 调用中。
试试这个:
-static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic
注意
-lstdc++
之前的 -lpthread
。这对我有用。
确保将其添加到
g++
命令行的最后。
您可能应该检查 GCC 的命令行选项文档。
这些不是“-static-something”命令,只有标准库(libgcc 和 libstdc++)可以通过一个命令设置为静态链接。对于其他库,您首先使用“-static”切换到静态链接,然后列出要包含单独命令的库,即“-lpthread”。
要静态链接 winpthread,即使程序中未使用线程,请将
-Bstatic
和 --whole-archive
参数传递给链接器:
g++ -o hello.exe hello.cpp -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive
注意以下事项:
<thread>
),则不需要执行此 hack,在这种情况下,当您静态链接库时,库不会被删除。对于使用 CMake 工作的任何人来说,此解决方案很容易在 CMakeLists.txt 文件中实现,如下所示...
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
显然,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
的库,仍然应该应用它,以确保标准的隐式链接库正确链接。
我通过使用 mingw 工具链的 win32 变体而不是 posix 变体来规避这个问题。对于 win32 变体,
-static-libgcc -static-libstdc++
对于独立构建来说已经足够了。
如果您使用 MSys2 的工具链(使用 gcc 版本 12 进行测试),静态使用 winpthread 的唯一方法是标准 -static (强制所有库都是静态的)或简单地删除/重命名 libwinpthread.dll.a && libpthread.dll .a imp 库。 其他方法如“Bstatic”、“-l:libwinpthread.a”将不再起作用(由于依赖地狱,尤其是在 CMake 中)。具有整个存档的版本仍然有效,但它会覆盖程序属性。 如果依赖项来自 libgcc 和 libstdc++,您可能还需要静态链接。
我发现通过 make 调用 gcc 编译时,程序会静态链接到 libwinpthread-1.dll。直接通过 gcc 编译时不会。我在 msys2 里编译的,指定了 -static 标志(-Wl,Bstatic 也行)因为我的程序里没有涉及到winpthread,所以我没有指定 -lwinpthread 或 -l:libwinpthread.a 标志(搜索到的一些解决办法要这样做,但我试了无效)。
只需链接
-l:libwinpthread.a
只需将
-static
添加到您的 CFLAGS
。
例如:
./configure CFLAGS="-static"
。
这会将所有静态库链接到您的可执行文件。