SDL mingw static lib linking errors - c++

I'm trying to compile a simple SDL program using Mingw w64. Here is my code:
test.c
#include "SDL2/SDL.h"
#include <stdio.h>
int main( int argc, char* args[] )
{
SDL_Window *window;
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("SDL2 Window", 100, 100, 640, 480, 0);
if(window==NULL)
{
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
SDL_Delay(3000);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
and here is the command I'm using to compile the program:
g++ -o text.exe test.c -I./include -L./lib -lmingw32 -lSDL2main -lSDL2
but when I compile the program, I get hundreds of linking errors that look like this:
./lib/libSDL2.a(SDL_wasapi_win32.o): In function `WASAPI_PlatformInit':
/Users/valve/release/SDL/SDL2-2.0.22-source/foo-x64/../src/audio/wasapi/SDL_wasapi_win32.c:255: undefined reference to `__imp_CoCreateInstance'
I downloaded the library from the second link down in the windows development libraries section on the official SDL website, and took the libraries from the following directory:
SDL2-2.0.22\x86_64-w64-mingw32\lib
The contents of ./lib are:
libSDL2main.a
libSDL.a
What is the problem and how can I fix it?

You have two options, depending on your intent:
If you want to link SDL2 dynamically (this should be your default course of action), you need to add libSDL2.dll.a to your library directory. Then libSDL2.a will be ignored and can be removed. It should just work, no other changes are needed.
If you want to statically link SDL2, you need more linker flags. The exact flags are listed in sdl2.pc in the Libs.private section.
As of SDL 2.0.22, those are: -Wl,--dynamicbase -Wl,--nxcompat -Wl,--high-entropy-va -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid.
Those should be added to the right of -lmingw32 -lSDL2main -lSDL2.
You also might want to add -static to statically link everything, including the standard library. (What's the point of statically linking SDL2, when your program still needs the DLLs of the standard library to work?) It also makes the linker prefer libSDL2.a to libSDL2.dll.a if both are available, meaning you don't need to worry what's in your library directory.

Related

Missing objects in SDL2.0.2 installation for Ubuntu

I installed SDL2 in Ubuntu, and I've been having trouble getting the sample program that comes with it to work. Here are the errors that appear.
|In function ‘int main(int, char**)’:|
‘SDL_HWSURFACE’ was not declared in this scope|
‘SDL_DOUBLEBUF’ was not declared in this scope|
‘SDL_SetVideoMode’ was not declared in this scope|
‘SDL_Flip’ was not declared in this scope|
||=== Build finished: 4 errors, 0 warnings ===|
Here is my header (I added SDL_image in case there were some issues, but it didn't change anything).
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#ifdef __APPLE__
#include <SDL/SDL.h>
#else
#include <SDL.h>
#endif
#ifdef _SDL_imageH
#include <SDL_image.h>
#endif
Here are the libraries I included in the linker settings:
libSDL2.a
libSDL2main.a
libSDL2_image.a
libz.a
I added on those libraries consecutively, but none of them seemed to help my program run. Below are the other linker options:
-lmingw32
-lSDL2main
-lSDL2
-mwindows
-lm
-ldinput8
-ldxguid
-ldxerr8
-luser32
-lgdi32
-lwinmm
-limm32
-lole32
-loleaut32
-lshell32 -lversion -luuid -static-libgcc
I also included in the compiler search directories /usr/local/include/SDL2.
I also tried -lmingw64 as I have a 64-bit compiler, although I don't know whether or not that option is available to me, but I suspect my compiler may be the problem.
Another issue is that when I run grep -r SDL_HWSURFACE /usr/ none of the files in the directory (or other directories I've searched) have that text other than the main.cpp file that is used to generate the test sample.
The location of the first two errors are in this line
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16,
SDL_HWSURFACE|SDL_DOUBLEBUF);
although I don't think that is extremely relevant.
SDL_SetVideoMode, as well as many other things, belongs to SDL 1.2 and no longer exists in SDL2. Please read https://wiki.libsdl.org/MigrationGuide

Issues compiling SDL with g++

When I try compiling the file
#include "SDL2\SDL.h"
int main( int argc, char* argv[] )
{
//Start SDL
SDL_Init( SDL_INIT_EVERYTHING );
//Quit SDL
SDL_Quit();
return 0;
}
--an example from the SDL wiki--on the command line with
g++ -o SDL_Test.exe SDL_Test.cpp -lmingw32 -lSDLmain -lSDL
I get an error that says my computer cannot find -lSDLmain and -lSDL. Without the library things, it has trouble interpreting the functions.
I think the problem has something to do with the -l things, but I have no idea what they do....
My computer is 64-bit, if that makes a difference. I copied the x84_64-mingw32 bin, include, and lib into the C:\MinGW versions.
I would mostly just like an explicite solution to my problem, but if you could try explaining the -l things and other - things, that would be awesome.
-::- Answered by greatwolf in chat: turns out I was using 32-bit MinGW with 64-bit SDL files; I just needed to replace the 64-bit files with the 32-bit versions. Also, I had to direct the compiler to my SDL2.dll file. End compile command was g++ -o SDL_Test.exe SDL_Test.cpp -LC:\MinGW\lib -lmingw32 -lSDL2main C:\MinGW\bin\SDL2.dll.
You've got to make sure that you specify the appropriate search path for libraries using the -L compiler flag. Otherwise it won't know where to look for linking.

SDL library in linux

I'm trying to compile this code:
#include "SDL/SDL.h"
int main(void) {
SDL_Surface *Hello = NULL;
SDL_Surface *Screen = NULL;
SDL_Init( SDL_INIT_EVERYTHING );
return 0;
}
But it happens that the compiler says that:
undefined reference to SDL_Init
I dont know why this is happening. I'm using Debian Mint and Code::Blocks. Could you Help me?
It looks like you haven't got -lSDL on your link line.
sdl-config returns the compile and link flags for your installation of SDL.
Assuming the program is sdl.cpp
g++ -o sdl `sdl-config --cflags` sdl.cpp `sdl-config --libs`
Should give you the correct flags.
Go to project and then build options and select your project name.
Now go to the linker setting and type the following lines in the Other Linker options textbox:
-lSDLmain
-lSDL
SDL also requires command line arguments in the main function so you should change
int main(void)
to
int main(int argc, char **argv)
Now compile your project and it should work.

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

I can compile with SDL1.2 but not with SDL2 (C::B)

I've been learning SDL for a little time, and now I've decided to try out SDL2, mainly to try its hardware acceleration. But the problem is, I can't compile it at all, while the same code compiled correctly with SDL1.2.
The sample code is:
#include "SDL/SDL.h"
int main( int argc, char *args[] )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Quit();
return 0;
}
With the original linker settings: -lmingw32 -lSDLmain -lSDL
everything compiles.
But as soon as I change #include "SDL/SDL.h" to #include "SDL2/SDL.h"
and change linker settings to
-lmingw32 -lSDL2main -lSDL2
I get the errors:
obj\Debug\main.o||In function `SDL_main':|
main.cpp|5|undefined reference to `SDL_Init'|
main.cpp|8|undefined reference to `SDL_Quit'|
libmingw32.a(main.o):main.c:(.text.startup+0xa7)||undefined reference to `WinMain#16'|
I've got SDL1.2 installed in C:/SDL-1.2.15 and SDL2 installed in C:/SDL2
In search directories, I added both SDL1.2 and SDL2 Include and Lib folders.
I'm not sure if this will work, but if you are using the "x86_64-w64-mingw32" folder, try using the other one (the one with i686) this helped me. I was having the EXACT same problem as you, and using literally, to the line, the same test code as you. I hope this helps.