【问题标题】:MinGW .exe requires a few gcc dll's regardless of the code?无论代码如何,MinGW .exe 都需要一些 gcc dll?
【发布时间】:2022-01-10 09:12:46
【问题描述】:

使用 MinGW 编译时,我必须在运行 exe 之前从 MinGW bin 目录中复制某些 dll 文件(即使使用“-static”和/或“-static-libstdc++”。) 我该如何改变呢?是否有我必须使用的特殊版本的 MinGW?最终,我希望能够在目录中除了 exe 之外什么都没有运行程序(并且没有设置 windows 环境变量。)这些文件是:

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

这是我休闲的步骤的完整列表:

  1. 打开代码::Blocks
  2. 选择“文件->新建->项目->控制台”
  3. 填写项目“Hello World”的项目设置
  4. 右键Project->Build Options...->Hello World (Root target)->Other Options
  5. 在已设置的“-fexceptions”下输入“-static”(或“-static-libstdc++”)
  6. CTRL-F9:构建项目(不执行)
  7. 在 Windows 资源管理器中导航到并运行构建的“Hello World.exe”文件。
  8. 当弹出消息“错误:您的计算机中缺少 libstdc++-6.dll”时,单击“确定”。
  9. 将“libstdc++-6.dll”从 /MinGW/bin/ 目录复制到“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;
}

【问题讨论】:

  • 听起来您想要做的是将所有内容捆绑到一个可重定位的可执行文件中。
  • 我会在代码块之外构建它。您需要查看您的构建命令。

标签: c++ dll mingw


【解决方案1】:

你的命令错了!

转到您的 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++

链接器选项应该可以工作(一次尝试所有 3 个)。但不适用于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")

【讨论】:

  • 因为他可能想要分发应用程序,并且不希望客户端必须安装 MinGW 或修改环境变量
  • 最终我希望能够在目录中只使用 exe 来运行程序 ...似乎不打包 DLL 正是他想要做的。如果所有运行时库都有静态库版本,这应该是可能的。
  • 出于某种原因,三个命令行选项没有改变任何东西。 (进行了编辑)另外,Praetorian 是对的。我可以用 exe 打包 dll(如果我这样做了),或者添加 env 变量以使其在 my 机器上工作,但对于打印“Hello World!”的控制台应用程序来说似乎太过分了。需要3个dll文件。对我来说,它看起来像是不必要的批量,也将在我可能编写的其他更高级的应用程序中进行标记。最重要的是,看看其他更高级的应用程序,包含的 dll 是开发人员创建的库或类似的东西。
  • 一个需要注意的陷阱:如果您的应用程序链接到一个 DLL(例如 wxbase)并且该 DLL 动态链接到 libstdc++,那么您就不走运了(为什么要添加 @987654328 会令人困惑@ 不会从依赖项中删除 libstdc++,直到您意识到发生了什么!)
  • 对于 libwinpthread-1.dll,可以使用以下链接器技巧 -Wl,-Bstatic,--whole-archive -lwinpthread,详细说明 here。这将静态链接 winpthread 而无需求助于-static
【解决方案2】:

如果使用异常,-static-libgcc 可能是个坏主意。 link options documentation 声明

在几种情况下,应用程序应该使用 共享 libgcc 而不是静态版本。其中最常见的 是当应用程序希望抛出和捕获异常时 不同的共享库。在这种情况下,每个库作为 以及应用程序本身应该使用共享的 libgcc。

【讨论】:

    【解决方案3】:

    上述答案的 cmets 包含完整的解决方案,因此我只想添加 CodeBlocks 透视图。我在 Windows7 x64 上使用 CodeBlocks16 和 MinGW-W64 8.1.0 ''i686-posix-dwarf'' 验证了它。

    这解决了 OPs 问题

    • 创建新项目并将其命名为“Hello World”

    • 接受向导中的所有默认值

    • 选择 Project/BuildOptions/ 并选择“Hello World”。 Out 编辑对 Debug 和 Release 都有效

    • 在“链接器”选项卡的“其他链接器选项”中添加以下内容

      -static
      -static-libgcc
      -static-strc++
      -lwinpthread
      
    • 在工具栏上选择“调试”并按构建(黄色齿轮图标)

    • 按下绿色运行图标并确认构建正常

    测试

    • 打开终端窗口并转到 HelloWorld\bin\debug 文件夹
    • 从那里开始 hello world。
    • 无需任何 DLL 即可确认它可以正常工作。

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

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

    请注意,如果您没有遇到 OP 的 winpthread.dll not found 问题,那么您可能不会使用带有“posix”的 MinGW-W64 编译器线程模型。两个代码块 MinGW-W64 捆绑安装包都使用此类版本。对于 CB20.03,来自MinGW-W64 download page 的相关下载将是

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

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

      -static-libgcc
      -static-strc++
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-31
      相关资源
      最近更新 更多