74

When compiling with MinGW, I have to copy over certain dll files from the MinGW bin directory before the exe will run (Even when using "-static" and/or "-static-libstdc++".) How do I change that? Is there a special build of MinGW that I have to use? Ultimately I want to be able to run the program with nothing but the exe in the directory (and no windows environment variables set.) These File's are:

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

And here is the complete list of step's I fallow:

  1. Open Up Code::Blocks
  2. Select "File->New->Project->Console"
  3. Fill out the project settings for project "Hello World"
  4. Right click Project->Build Options...->Hello World (Root target)->Other Options
  5. Enter "-static" (or "-static-libstdc++") under the already set "-fexceptions"
  6. CTRL-F9 : Build Project (Without executing)
  7. Navigate to, in Windows Explorer, and run the built "Hello World.exe" file.
  8. Click "OK" when a message pop's up saying "Error: libstdc++-6.dll is missing from your computer."
  9. Copy "libstdc++-6.dll" from the /MinGW/bin/ directory, into the "Hello World.exe" directory.
  10. Run "Hello World.exe"
  11. Click "OK" for the message saying "Error: libgcc_s_seh-1.dll is missing from your computer."
  12. Copy "libgcc_s_seh-1.dll" into the "Hello World.exe" directory.
  13. Repeat and end up copying "libwinpthread-1.dll" over aswell.
  14. View the message

    Hello World!
    

Edit: My command line is:

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

With all the dll files mentioned above required. And, just to be safe, the code is:

// main.cpp
#include <iostream>

using namespace std;

int main()
{
    cout << "Hello world!" << endl;
    return 0;
}
greatwolf
  • 20,287
  • 13
  • 71
  • 105
Wolfgang Skyler
  • 1,338
  • 1
  • 13
  • 26
  • It sounds like what you want to do is bundle everything into a single relocatable executable. – Jiminion Aug 09 '13 at 01:44
  • I would build it outside of code blocks. You need to see your build command. – Jiminion Aug 09 '13 at 01:49
  • Any chance that you are building inside the NSYS2 environment with the `msys/gcc` compiler? Because if that's the case you should be using the mingw64 terminal and using the `mingw64/mingw-w64-x86_64-gcc` compiler. – Foad S. Farimani Nov 10 '22 at 20:23

3 Answers3

67

Your commands are wrong !

Go to the directory where your main.cpp file is, and try the following.

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

then you'll no longer need to copy the DLLs (for your Hello World program).

Other notes:

The MinGW installation instructions recommends setting

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

to the PATH environment variable.

Normally the

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

linker options should work (try all 3 of them at once). But not for libwinpthread-1.dll.

Also, try to clean before recompiling.

There's no "-static-something" command.

Only standard libraries libgcc and libstdc++ can be set to static linking.

For other libraries, you first switch to static linking with "-static" and then list the libraries to include with separate commands, i.e. "-lpthread".

Cmake users should try adding:

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")
tresf
  • 7,103
  • 6
  • 40
  • 101
moskito-x
  • 11,832
  • 5
  • 47
  • 60
  • 2
    Because he probably wants to distribute the app, and doesn't want clients to have to install MinGW or modify environment variables – Praetorian Aug 09 '13 at 01:50
  • @Praetorian : This is a development environment. If the OP wants to give to his customers, he has to pack all necessary dll's with the setup file anyway. But it looks like it's only `Hello World` tests. Therefore, it would be pretty stupid not to have the required files in a folder where they can be found. For a downvote that's pretty vague. – moskito-x Aug 09 '13 at 02:03
  • 5
    *Ultimately I want to be able to run the program with nothing but the exe in the directory* ... it seems not packaging the DLLs is exactly what he wants to do. Which should be possible if there are static library versions of all the runtime libraries. – Praetorian Aug 09 '13 at 02:08
  • 2
    For some reason, the three command line options didn't change anything. (made an edit) Also, Praetorian, is right. I could package the dlls with the exe (if I did), or add the env variable to make it work on **my** machine, but it seems excessive with a console application that print's "Hello World!" to require 3 dll files. It, to me, look's like unnecessary bulk that is also going to be tagging along in other, more advanced, applications I might write. On-top of that, looking at other more advanced applications, the dlls included are library's that the developer created or something similar. – Wolfgang Skyler Aug 09 '13 at 03:58
  • 7
    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!) – M.M Feb 05 '15 at 11:57
  • 3
    For **libwinpthread-1.dll** the following linker trick can be used `-Wl,-Bstatic,--whole-archive -lwinpthread` as detailed [here](http://stackoverflow.com/a/43402308/7023624). This will link **winpthread** statically without having to resort to `-static`. – user7023624 Apr 17 '17 at 07:17
  • I assume `CMAKE_CSS_STANDARD_LIBRARIES` was intended to be `CMAKE_CXX_STANDARD_LIBRARIES`? – tresf Mar 26 '19 at 05:55
  • `CMAKE_CSS_STANDARD_LIBRARIES` was added by @bremen_matt. I don't know right or wrong! – moskito-x Mar 26 '19 at 09:56
  • Did you delete it? It was a good command just had a typo. Please don't delete good code! I would have fixed it myself, but minor changes are generally rejected in favor of comments. Resubmitted with typo corrected. – tresf Mar 26 '19 at 18:04
  • Maybe @bremen_matt looks at it ;-) – moskito-x Mar 26 '19 at 18:21
  • Sorry. I don't have time to look into this. I thought the code was right. But if the original poster disagrees, then I feel obliged to remove the code, particularly since I don't have time to investigate further. – bremen_matt Mar 27 '19 at 06:21
11

-static-libgcc may be a bad idea if exceptions are used. link options documentation states that

There are several situations in which an application should use the shared libgcc instead of the static version. The most common of these is when the application wishes to throw and catch exceptions across different shared libraries. In that case, each of the libraries as well as the application itself should use the shared libgcc.

J.J. Hakala
  • 6,136
  • 6
  • 27
  • 61
1

The comments to the answer above contain the full solution, so I would like to merely add the CodeBlocks perspective. I verified it on Windows7 x64 with CodeBlocks16 and MinGW-W64 8.1.0 ''i686-posix-dwarf''.

This solves the OPs question

  • 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

Testing

  • open a terminal window and go to the HelloWorld\bin\debug folder
  • start hello world there.
  • Confirm it works without asking for any DLLs.

You could also start it from an explorer window and confirm that it also does not ask for DLLs.

Note: On my Win7x64 system when starting the HelloWorld.exe from the explorer adding the "-lwinpthread" line causes CodeBlocks to ignore the setting in "Projects/Properties/Tab_BuildTargets/ "Pause when execution ends". So the "Hello World" output is hardly visible because the window immediately closes after execution (mabye someone knows why)

Note that if you do not have the winpthread.dll not found problem of the OP then you likely do not use a MinGW-W64 compiler with a 'posix' thread model. Both Code blocks MinGW-W64-bundled install packages use such versions. For CB20.03 the relevant downloads from MinGW-W64 download page would be

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

For example if I set setup compilers with Codeblocks direcly and chose the 32-bit compiler package ''i686-win32-dwarf'', only the first 2 DLLs would go missing. In that case the fix is to set the linker options only to

  -static-libgcc
  -static-strc++
CatMan
  • 173
  • 8