MinGW .exe 需要一些 gcc dll,无论代码如何?

75

使用MinGW编译时,我必须从MinGW bin目录复制某些dll文件,然后exe才能运行(即使使用“-static”和/或“-static-libstdc ++”)。

我该怎么改变这种情况?是否有特殊的MinGW版本需要使用?最终,我希望能够仅通过exe在目录中运行程序(而不需要设置任何Windows环境变量)。这些文件是:

  • libstdc++-6.dll
  • libgcc_s_seh-1.dll
  • libwinpthread-1.dll

以下是我遵循的完整步骤:

  1. 打开Code::Blocks
  2. 选择“文件->新建->项目->控制台”
  3. 填写“Hello World”项目设置
  4. 右键单击项目->构建选项...->Hello World(根目标)->其他选项
  5. 在已经设置的“-fexceptions”下输入“-static”(或“-static-libstdc ++”)
  6. CTRL-F9:构建项目(不要执行)
  7. 在Windows资源管理器中导航到并运行生成的“Hello World.exe”文件。
  8. 当弹出消息显示“错误:计算机缺少libstdc++-6.dll”时,单击“确定”。
  9. 从/MinGW/bin/目录中复制“libstdc++-6.dll”到“Hello World.exe”目录中。
  10. 运行“Hello World.exe”
  11. 单击消息显示“错误:计算机缺少libgcc_s_seh-1.dll”的“确定”。
  12. 将“libgcc_s_seh-1.dll”复制到“Hello World.exe”目录中。
  13. 重复操作并最终也需要复制“libwinpthread-1.dll”。
  14. 查看消息

Hello World!

编辑:我的命令行是:

g++.exe -Wall -fexceptions -static -static-libgcc -static-libstdc++ -g -static-libgcc -static-libstdc++ -L. -c "C:\Users\______\Desktop\Hello World\main.cpp" -o obj\Debug\main.o
g++.exe -o "bin\Debug\Hello World.exe" obj\Debug\main.o

需要所有上述提到的 DLL 文件。为了保险起见,代码如下:

// main.cpp
#include <iostream>

using namespace std;

int main()
{
    cout << "Hello world!" << endl;
    return 0;
}

听起来你想做的是将所有东西捆绑成一个单独的可重定位可执行文件。 - Jiminion
我会在代码块之外构建它。你需要查看你的构建命令。 - Jiminion
你是否在NSYS2环境中使用msys/gcc编译器进行构建?如果是这种情况,你应该使用mingw64终端并使用mingw64/mingw-w64-x86_64-gcc编译器。 - Foad S. Farimani
3个回答

67

你的命令有误!

前往存放main.cpp文件的目录,并尝试以下步骤。

g++.exe -Wall -c -g main.cpp -o obj\Debug\main.o
g++.exe -static -static-libgcc -static-libstdc++ -o "bin\Debug\Hello World.exe" obj\Debug\main.o

那么您将不再需要复制DLL(用于Hello World程序)。

其他注意事项:

MinGW安装说明建议进行设置。

c:\minGW;c:\MinGW\bin;

添加到PATH环境变量中。

通常情况下,

-static -static-libgcc -static-libstdc++

链接选项应该可以工作(同时尝试三个选项)。但对于libwinpthread-1.dll无效。

另外,在重新编译之前尝试执行clean操作。

没有“-static-something”命令。

只有标准库libgcclibstdc++可以进行静态链接。

对于其他库,您需要先使用“-static”切换到静态链接,然后使用单独的命令列出要包含的库,即“-lpthread”。

Cmake用户应尝试添加:

set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++ -lwsock32 -lws2_32 ${CMAKE_CXX_STANDARD_LIBRARIES}")

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive")

2
因为他可能想要分发应用程序,而不希望客户安装MinGW或修改环境变量。 - Praetorian
5
最终,我希望能够只通过目录中的exe文件来运行程序。...看起来不打包DLL文件正是他想要做的。如果所有运行时库都有静态库版本的话,这应该是可能的。 - Praetorian
2
由于某些原因,这三个命令行选项没有改变任何东西。(进行了编辑)此外,Praetorian是正确的。如果我这样做,我可以将dll文件与exe打包在一起,或者添加环境变量使其在我的机器上工作,但对于一个只打印“Hello World!”的控制台应用程序来说,这似乎过于冗余。对我来说,它看起来像是不必要的负担,也会随着我可能编写的其他更高级的应用程序而附带。除此之外,查看其他更高级的应用程序时,所包含的dll是开发人员创建的库或类似的东西。 - Wolfgang Skyler
8
需要翻译的内容:A pitfall to watch out for: if your app links to a DLL (e.g. wxbase) and that DLL dynamically links to libstdc++ then you're out of luck (and it will be confusing why adding -static-libstdc++ doesn't remove libstdc++ from the dependencies until you realize what is going on!)需要注意的陷阱:如果您的应用程序链接到一个动态链接库(例如wxbase),而该动态链接库又动态链接到libstdc++,那么您就会遇到麻烦(并且当您意识到问题所在时,添加“-static-libstdc++”无法从依赖项中移除libstdc++时,这会令人困惑!) - M.M
3
对于libwinpthread-1.dll,可以使用以下链接器技巧:-Wl,-Bstatic,--whole-archive -lwinpthread,具体详见这里。这将静态链接winpthread而无需使用-static选项。 - user7023624
显示剩余6条评论

12
如果使用异常处理的话,-static-libgcc 可能不是一个好主意。 链接选项文档 指出:

在多个共享库之间抛出和捕获异常时,应用程序应该使用共享的 libgcc,而不是静态版本。这是最常见的几种情况之一。在这种情况下,每个库以及应用程序本身都应该使用共享的 libgcc。


1

上面答案的评论包含完整的解决方案,因此我只想添加CodeBlocks的视角。我在Windows7 x64上使用CodeBlocks16和MinGW-W64 8.1.0“i686-posix-dwarf”进行了验证。

这解决了OP的问题。

  • Create new project and name it "Hello World"

  • accept all defaults in the wizard

  • select Project/BuildOptions/ and select "Hello World". Out edits will be valid for both Debug and Release

  • add the following at "Other linker option" in the "Linker" Tab

    -static
    -static-libgcc
    -static-strc++
    -lwinpthread
    
  • On the Toolbar select "Debug" and press Build (the yellow gear icon)

  • Press the green run icon and confirm that the build was ok

测试

  • 打开终端窗口并转到 HelloWorld\bin\debug 文件夹
  • 在那里启动hello world。
  • 确认它可以正常工作而不需要任何DLL。

您还可以从资源管理器窗口启动它,并确认它也不会要求 DLL。

注意:在我的Win7x64系统上,从资源管理器启动HelloWorld.exe并添加“-lwinpthread”行会导致CodeBlocks忽略“项目/属性/选项卡_BuildTargets/“执行结束时暂停”的设置。因此,“Hello World”输出几乎不可见,因为窗口在执行后立即关闭(也许有人知道原因)

请注意,如果您没有OP的winpthread.dll未找到问题,则可能不使用具有'posix'线程模型的MinGW-W64编译器。 Code blocks MinGW-W64捆绑安装包都使用这些版本。对于CB20.03,来自MinGW-W64下载页面的相关下载将是

  • 32位:8.1.0 ''i686-posix-dwarf''
  • 64位:8.1.0 ''x86_64-posix-seh''

例如,如果我直接使用Codeblocks设置编译器并选择32位编译器包''i686-win32-dwarf'',只会丢失前两个DLL。在这种情况下,解决方法是仅将链接器选项设置为

  -static-libgcc
  -static-strc++

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接