MinGW .exe requires a few gcc dll's regardless of the code? - c++

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

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")

-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.

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++

Related

Wine cannot load DLLs even though the directory is added to PATH

I am trying to cross-compile Windows software on Linux using mingw32-w64 and running it with wine. However wine cannot load the libstdc++-6.dll library file. I searched online and found out that you have to put the directory that contains the DLL file into the path registry. In my case, that directory is Z:\bin\i686-w64-mingw32\bin.
Then I tried to run the compiled file by using wine executable.exe and the output is:
0100:err:module:import_dll Loading library libstdc++-6.dll (which is needed by L"Z:\\home\\sunnymonster\\dev\\c++\\opengl-tests\\cmake-build-debug\\opengl_tests.exe") failed (error c000007b).
0100:err:module:LdrInitializeThunk Importing dlls for L"Z:\\home\\sunnymonster\\dev\\c++\\opengl-tests\\cmake-build-debug\\opengl_tests.exe" failed, status c0000135
I have verified that I am using the correct wine prefix.
Additional information:
Linux distro: Manjaro Linux 21.2.5
Linux kernel: 5.16.14-1
There're multiple approaches. First, let's formalize the problem:
$ cat test.cpp
#include <iostream>
int main() { std::cout << "hello" << std::endl; }
$ i686-w64-mingw32-g++ test.cpp -o a && WINEDEBUG=-all,err+module wine ./a.exe
0024:err:module:import_dll Library libgcc_s_dw2-1.dll (which is needed by L"Z:\\tmp\\a.exe") not found
0024:err:module:import_dll Library libstdc++-6.dll (which is needed by L"Z:\\tmp\\a.exe") not found
0024:err:module:LdrInitializeThunk Importing dlls for L"Z:\\tmp\\a.exe" failed, status c0000135
Solutions:
Link the core libraries statically:
$ i686-w64-mingw32-g++ test.cpp -o a -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic
$ WINEDEBUG=-all,err+module wine ./a.exe
hello
Use WINEPATH env. variable to tell wine the additional paths to load dlls from. In the example I pass it the location with mingw dlls that wine complains about. It may be different on your system, you might find it by asking package manager to list files in mingw-g++/gcc packages (whatever it's called on your system). Multiple paths should be separated by semicolon.
$ i686-w64-mingw32-g++ test.cpp -o a
$ WINEDEBUG=-all,err+module WINEPATH=/usr/i686-w64-mingw32/sys-root/mingw/bin/ wine ./a.exe
hello
Install a Windows version of MinGW, and then use it to compile the app. However, from what I remember, if you want to distribute the executable produced, you still need to either statically link against MinGW libs, or provide them together with the binary. So the only difference to point 1 is that the binary should work under your WINEPREFIX with no modifications.
Using wineg++. I mention it solely for completeness, I think it's the least useful solution. It produces a Linux file, which in itself might be okay, one could use that for debugging. However, in my tests, I didn't manage to makewineg++ link against a dll, even though mingw links to the same dll without a problem. It seems to link against .so files instead, even though the application you build with it can load .dll files dynamically. Odd utility.
$ wineg++ test.cpp -o a
$ WINEDEBUG=-all,err+module wine ./a.exe
hello

Error loading SDL2 shared libraries while executing program on another pc

I'm trying to compile a program i made using SDL2 to work on others computers (or testing VM in this case).
I've been compiling it with what i think are the correct flags, e.g. g++ main.cpp -o main -lSDL2, however when i try executing it on another Ubuntu installation i get this error.
error while loading shared libraries: libSDL2-2.0.so.0: cannot open shared object file: No such file or directory
From my understanding it's not a problem in my compiling but with how i expect it to work on another Linux installation; I've cross-compiled (using mingw32) and tested it (using a freshly installed VM) on Windows adding the correct dlls with the exe (seems to work fine) and I was expecting for it to work in a similar fashion.
What's the standard in this cases? Should i write a setup scripts to install the library dependencies on the target machine? Is there another way I'm not aware of? I've never released an application for Linux (nor Windows) and I'm struggling to find the resources to do things "the right way".
Thanks for everyone suggestions, I ended up settling for the easy way, compiling the "easy to install" libraries dynamically e.g.-lSDL2 and the others statically (checked the licenses and it should be fine) like so:
g++ main.cpp -o main -Wl,-Bdynamic -lSDL2 -lSDL2_image -lSDL2_ttf -Wl,-Bstatic -lSDL2_gfx -static-libgcc -static-libstdc++
I'll put in my documentation how to install the required SDL2 libraries.
I am not sure how familiar you are with pkg-config, but the output for sdl2 is this:
-D_REENTRANT -I/usr/include/SDL2 -lSDL2
This was found from running this:
pkg-config --cflags --libs sdl2
Basically, you need to point to where SDL2 is located BEFORE you actually link to it.
The tool pkg-config is designed to tell you the information you need when you want to link to a package in Linux. You were linking with the library, but you forgot to tell GCC where the library is located.
If you want to compile you code, try this:
g++ main.cpp -o runme `pkg-config --cflags --libs sdl2`
This will automatically grab all of the flags that you need to compile with SDL2 included.
Oh, and you should note, ORDER MATTERS WHEN ADDING FLAGS AND LIBRARIES!!!
There are many questions on SO where the order of compiler options caused all of the problems. Do not be like those people. I suggest you search SO for more info on that.

Executing cross-compiled C++ program using Boost on Raspberry Pi

I have built a GCC cross toolchain for the RPi and can cross-compile C++ source and successfully run it after copying the executable to the RPi.
Next I built the Boost libraries targeting ARM, using the cross toolchain. I can successfully build and link C++ source to those Boost libraries using the cross toolchain on my PC.
I then copied the program, dynamically linked to Boost, to the RPi and copied all built libraries into /usr/local/lib on the Pi. However, executing fails:
$ ./my_program
./my_program: error while loading shared libraries: libboost_system.so.1.60.0: cannot open shared object file: No such file or directory
Again, this library, libboost_system.so.1.60.0, exists in /usr/local/lib.
I also tried
export LD_LIBRARY_PATH='/usr/local/lib'
but that doesn't change anything. What am I doing wrong?
EDIT:
I build all source files like this (rpi-g++ is a symlink to my cross-compiler):
rpi-g++ -c -std=c++1y -Wall -Wextra -pedantic -O2 -I /path/to/cross/boost/include *.cpp
rpi-g++ -o myprog *.o -L /path/to/cross/boost/lib/ -lboost_system -pthread
EDIT 2:
When linked with
rpi-g++ -o myprog *.o -L /path/to/cross/boost/lib/ -rdynamic -lboost_system -pthread
the problem remains the same. I have checked and verified everything suggested by Technaton as well. Strangely, ldd insists that the created executable is "not a dynamic executable" (checked that on my PC and on the RPi), which doesn't make sense to me.
There are several things you can check. I've posted a complete check list here, but judging from your linker command line, number 5 is probably the culprit.
Check that your library and your program are correctly build for the target architecture. You can verify that by using file ./myprog and file libboost_system.so.1.60.0.
Make sure that you have copied the actual shared object, and not a link to it.
Ensure that the shared object file's permissions are sane (0755).
Run ldconfig -v and check that your shared object file is picked up. Normally, /usr/local/lib is in the standard library search path, and LD_LIBRARY_PATH is not required.
Make sure that your program is actually dynamically linked by running ldd ./myprog. Judging from your linker command line, that is the problem: You're missing -rdynamic.
Check the paths returned from ldd: If you have linked with rpath, the library search path might be screwed up. Try again without -rpath.

Static-linking of SDL2 libraries

I am using Windows 7, Code::Blocks and MinGW. I have little to no experience when it comes to compiling/building anything, especially when Code::Blocks doesn't use makefiles.
I downloaded SDL2-devel-2.0.0-mingw.tar.gz (SDL Development Libraries) from http://www.libsdl.org/tmp/download-2.0.php, and I'd like to create a standalone executable using SDL2 libraries, but so far I've always had to bundle the SDL2.dll file with the executable to make it work.
I've heard that I can not static-link dynamic libraries, so my only option seems to be doing something with the source files using the file SDL2-2.0.0.tar.gz (Source Code) from the link I mentioned above. However, I do not know what I should do with those.
What I managed to try with the source files is importing the Visual Studio project to Code::Blocks and building it, but it tells me "sdl-config No such file or directory" (I do not know what triggered that). I'm also not sure if building merely gives me an executable, with which I do not know what I can do to link it to my own executable.
A fool proof idiot's step by step guide would be the best bet to solve this case.
EDIT:
I managed to compile the SDL libraries with the guide Jonas provided, and got a libSDL2.a file.
At first I only added the path of libSDL2.a to "Link libraries:" -section of Code::Blocks, but I got a bunch of errors such as "SDL_Init() not declared in this scope".
In addition to the libSDL2.a path, I also added the path of SDL2-2.0.0\include to the Compiler's search directory as well as the path of SDL2-2.0.0\build.libs to the Linker's search directory. I also wrote this to my test file: #include "SDL.h". My test file now looks like this:
#include "SDL.h"
int main( int argc, char* args[] ) {
//Start SDL
SDL_Init( SDL_INIT_EVERYTHING );
//Quit SDL
SDL_Quit();
return 0;
}
It appears it did fix the declaration problem, but now Code::Blocks opened a SDL_mmjoystick.c file and gave me even more errors: "undefined reference to 'waveInClose#4'", "undefined reference to 'waveOutClose#4'", "undefined reference to 'joyGetNumDevs#0'" and tons of other ones.
Here's a screenshot of what's happening, note the different color of #include texts, I'm not sure why that happens: http://gyazo.com/00656a9c1e57a2bd0db1414fa7d68ced.png
I am not sure how to correctly take this library into use. Any help in this case, or should I make another question for it?
EDIT:
I added -lSDL2 to the linker options and deleted the other parameters. Now it builds fine:
mingw32-g++.exe -Wall -fexceptions -g -IC:\Users\User\Desktop\SDL2-2.0.0\include -c "C:\Users\User\Desktop\CppProjects\SDL project\main.cpp" -o obj\Debug\main.o
mingw32-g++.exe -Wall -fexceptions -g -IC:\Users\User\Desktop\SDL2-2.0.0\include -c "C:\Users\User\Desktop\CppProjects\SDL project\thetestfile.cpp" -o obj\Debug\thetestfile.o
mingw32-g++.exe -LC:\Users\User\Desktop\SDL2-2.0.0\build\.libs -o "bin\Debug\SDL project.exe" obj\Debug\main.o obj\Debug\thetestfile.o -lSDL2 ..\..\SDL2-2.0.0\build\.libs\libSDL2.a C:\Users\User\Desktop\SDL2-2.0.0\build\.libs\libSDL2.a -mwindows
Output size is 945.80 KB
Process terminated with status 0 (0 minutes, 1 seconds)
0 errors, 0 warnings (0 minutes, 1 seconds)
But when I try to run it, it says my computer lacks SDL2.dll, while the whole point was to static-link.
So currently I have the path to build/.libs in my Link libraries -settings, -lSDL2 in the Other linker options, and for search directories I have the path to SDL2-2.0.0/include for the compiler and SDL2-2.0.0/build/.libs for the linker.
In the build/.libs directory I can also see libSDL2.a, libSDL2.dll.a, libSDL2.la and libSDL2.lai files, which I don't know what they are.
It's not necessary to recompile the library,
SDL2 is given with static-link library named "libSDL2.a"
on the folder "SDL2-2.0.0\i686-w64-mingw32\lib\".
Just be sure to add these options to the linker :
"-lmingw32 -lSDL2main -lSDL2 -mwindows -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc"
on Code:Blocks at "Project / Build Options... / Linket settings / Other linker options"
These options allow you to link with what SDL2.dll was using.
You can retreive them on the file "SDL2-2.0.0\i686-w64-mingw32\bin\sdl2-config"
The magical trick is to delete or rename the file "libSDL2.dll.a"
on the folder "SDL2-2.0.0\i686-w64-mingw32\lib\".
I added a "-" before to keep it in case I need it.
I don't know why this librairy overcomes the other and a clue would be appreciated.
I tried with Code::Blocks 12.11 MinGW32 and it worked.
If you run with some projects that use dynamic-link
and some other which use static-link, you will have to
keep your librairies in two different folders knowing that
"libSDL2main.a" will be in those two.
Sorry for my writing, I'm not used to write in english.
Mike

Help on build using g++ on Windows

There is a small project C++ (it has win32 code) that I need to build. It already has its Makefile. I was told to use MinGW. I have never used it before. I downloaded and installed the latest MinGW installer.
Then, I opened the MinGW shell and did make. The exe file was created. But when I try to run it I get libgcc_s_dw2-1.dll is missing! Why do I get this error? Shouldn't the exe be self-contained and run anywhere?
UPDATE
Here's more information, from the Makefile:
CC = g++
CCOPTIONS=-DWINDOWS -DFORCEINLINE -DMINGW -DSRTP_SUPPORT -D__EXPORT= -D_WIN32_WINNT=0x0501 -DNOMVS
setup.exe: setup.o common.o
$(CC) -ggdb -g -O0 -o $# setup.o common.o -mno-cygwin -mwindows -lwsock32 -lws2_32 -lwinmm -lgdi32 -lcomctl32 -lmapi32 -lVfw32
Whether or not the exe should be self-contained depends on how you built it. We need to see the commands that were executed, or post the makefile. But that DLL does not seem to be part of the current version of MinGW. Also, please clarify if you are actually doing this under cygwin, or if you added the tag by mistake.
Edit: A bit of googling seems like it has to do with the horrible "official" MinGW installation. Remove it, and download the Twilight Dragon build from http://tdm-gcc.tdragon.net and then rebuild completely. The "official" build is cr*p anyway - I don't know why anyone uses it.
If what you want to do is a stand alone application with MinGW, you should add -static to the linking options.
On a side note, if you're making a Win32 application, add the -mwindows option to the C++ compiler so it doesn't open a console together with your main window.