Cannot link SDL2 statically - c++

I'm trying to link to SDL2 statically on Arch Linux in order to produce single, cross-platform executable for a game. SDL2 headers are installed in /usr/include/SDL2, and libraries in /usr/lib. Compiling dynamically with g++ -I/usr/include/SDL2 -lSDL2 hello.cpp works, as ./a.out produces a blank window, but I am unable to link SDL2 to the executable statically.
Contents of hello.cpp:
#include <iostream>
#include "SDL.h"
int main() {
bool quit{false};
SDL_Event inputEvent;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("Hello", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 1280, 0);
while (!quit) {
SDL_WaitEvent(&inputEvent);
switch (inputEvent.type) {
case SDL_QUIT:
quit = true;
break;
}
}
SDL_Quit();
std::cout << "Bye!";
return 0;
}
g++ -I/usr/include/SDL2 -static -lSDL2 hello.cpp returns /usr/bin/ld: cannot find -lSDL2, while g++ -I/usr/include/SDL2 -l:libSDL2 hello.cpp returns /usr/bin/ld: cannot find -l:libSDL2.

It turns out that PKGBUILD of sdl2-hg in the AUR was renaming libSDL2.a to libSDL2main.a, hence the libSDL2.a not found error. Removing the problematic line from the PKGBUILD and recompiling SDL2 alleviated the issue.

Related

failure to initialize SDL audio

When i Call SDL_Init passing in SDL_AUDIO_INIT, the function returns a failure.
I called SDL_GetError() but there does not seem to be any message.
I am not having problems getting VIDEO to initialize, only audio. I don't get any errors when compiling. I have linked the SDL mixer library in my makefile.
Here is a minimum reproducible example code:
#include <SDL2/SDL.h>
#include <stdio.h>
#include <string>
int main( int argc, char* args[] )
{
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO < 0))
{
printf( "SDL VIDEO could not initialize! SDL Error: %s\n", SDL_GetError() );
}
else if ( SDL_Init( SDL_INIT_AUDIO) < 0)
{
printf( "SDL AUDIO could not initialize! SDL Error: %s\n", SDL_GetError() );
}
else
{
printf("video and audio initialized");
}
return 0;
}
output: SDL AUDIO could not initialize! SDL Error:
(there is no message for the error)
Here is the makefile
#OBJS specifies which files to compile as part of the project
OBJS = 21_sound_effects_and_music.cpp
#CC specifies which compiler we're using
CC = g++
#COMPILER_FLAGS specifies the additional compilation options we're using
# -w suppresses all warnings
COMPILER_FLAGS = -g -Wall
#LINKER_FLAGS specifies the libraries we're linking against
LINKER_FLAGS = -lSDL2 -lSDL2_image -lSDL2_ttf -lSDL2_mixer
#OBJ_NAME specifies the name of our exectuable
OBJ_NAME = sdl_program
#This is the target that compiles our executable
all : $(OBJS)
$(CC) $(OBJS) $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $(OBJ_NAME)
I am using Ubuntu 20.04
install libasound2-dev libpulse-dev
and recompyling SDL2
Audio drivers : disk dummy oss alsa(dynamic) pulse(dynamic) <--- IS OK

Undefined reference when using glew and mingw?

I am using Eclipse, I had originally downloaded the binary from the website until someone pointed out that I needed to build it from source to make it work with mingw, so I did and I got these files: glew32.dll, libglew32.a, and libglew32.dll.a
I dropped the glew32.dll into the debug folder, and linked the libraries but it did not work.
The weird part: GLenum status = glewInit(); works but glClearColorand glClear do not work and I get a undefined reference to error when I try to call them.
Please see these screenshots: http://imgur.com/a/L8iNb and http://imgur.com/a/nYoWD
C++.cpp
#include <iostream>
#include "classHeaders\display.h"
#include "GL\glew.h"
int main(int argv, char** args){
display x(800,600,"something");
while(!x.isClosed()){
glClearColor(0.0f,0.15f,0.3f,1.0f); //undefined reference to ERROR here
glClear(GL_COLOR_BUFFER_BIT); //undefined reference to ERROR here
x.Update();
}
return 0;
}
display.cpp
#include "classHeaders\display.h"
#include "GL\glew.h"
#include <iostream>
display::display(int width, int height, const std::string& title){
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
m_window = SDL_CreateWindow(title.c_str(),SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,width,height, SDL_WINDOW_OPENGL);
m_glContext = SDL_GL_CreateContext(m_window);
GLenum status = glewInit(); //NO ERRORS OCCUR
if(status != GLEW_OK){
std::cerr << "glew failed to initialize" << std::endl;
}
m_isClosed = false;
}
display::~display(){
SDL_GL_DeleteContext(m_glContext);
SDL_DestroyWindow(m_window);
SDL_Quit();
}
bool display::isClosed(){
return m_isClosed;
}
void display::Update(){
SDL_GL_SwapWindow(m_window);
SDL_Event e;
while(SDL_PollEvent(&e)){
if(e.type == SDL_QUIT){
m_isClosed = true;
}
}
}
display.h
#ifndef DISPLAY_H_
#define DISPLAY_H_
#include <string>
#include "SDL2\SDL.h"
#undef main /*need to put this in or else it gives me "undefined reference to WinMain" ERROR*/
class display{
public:
display(int width, int height, const std::string& title);
void Update();
bool isClosed();
virtual ~display();
private:
display(const display& other){}
display& operator=(const display& other){}
SDL_Window* m_window;
SDL_GLContext m_glContext;
bool m_isClosed;
};
#endif /* DISPLAY_H_ */
To set up GLEW, a current OpenGL Context is needed (see Creating an OpenGL Context (WGL) for more information).
Create OpenGL context and window
A OpenGL Context and a window can easily created by SDL, GLFW or GLUT (see Initializing GLEW for more information).
Initilize SDL
If you are using SDL you have to create the window and you have to create the OpenGL context.
SDL_Window *window = SDL_CreateWindow(""OGL window", SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL );
SDL_GLContext glContext = SDL_GL_CreateContext( window );
Note, you should check for errors with SDL_GetError.
The OpenGL context has to become the current context before you use it. Use SDL_GL_MakeCurrent therefor.
SDL_GL_MakeCurrent( window, glContext );
Initilize GLUT
To set up GLUT you have to use glutInit and can follow the instructions of initializing glew.
glutInit(&argc, argv);
glutCreateWindow("OGL window");
Initilize GLFW
Note, glfwInit returns GLFW_TRUE if succeded:
if ( glfwInit() != GLFW_TRUE )
return;
GLFWwindow *wnd = glfwCreateWindow( width, height, "OGL window", nullptr, nullptr );
if ( wnd == nullptr )
{
glfwTerminate();
return;
}
glfwMakeContextCurrent( wnd );
After you have created an OpenGL Context and you have made it become the current context, you have to initialize glew.
Set up GLEW
Note that glewInit returns GLEW_OK if succeded:
if ( glewInit() != GLEW_OK )
return;
To link the GLEW library correctly you have to set up proper preprocessor definitions:
On Windows, you also need to define the GLEW_STATIC preprocessor token when building a static library or executable, and the GLEW_BUILD preprocessor token when building a dll
See also the answer to GLEW Linker Errors (undefined reference to `__glewBindVertexArray')
So basically to solve this problem you want to download the source from the glew website and compiler it yourself. You use the command prompt to get in the directory of the folder you downloaded and execute these commands line by line in order:
gcc -DGLEW_NO_GLU -O2 -Wall -W -Iinclude -DGLEW_BUILD -o src/glew.o -c src/glew.c
gcc -nostdlib -shared -Wl,-soname,libglew32.dll -Wl,--out-implib,lib/libglew32.dll.a -o lib/glew32.dll src/glew.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
and finnally:
gcc-ar cr lib/libglew32.a src/glew.o (though the "gcc-" may not be needed, it was for me)
Once you're done with that left click on your project and go to Properties, then under C/C++ Build go to settings, then under MinGW C++ Linker click in Libraries. Once you're there make sure your Library search path is correct (the place where Eclipse looks for your libraries) then in Libraries enter these one by one: glew32 opengl32 glu32 glew32.dll SDL2 SDL2main SDL2_test
Also when you compiled from source there should be a glew32 with a .dll not a .a extension in your lib folder inside the glew folder you downloaded from the website, drop that in into your debug (where your .exe is created). Do the same for the .dllnot the .dll.a for SDL and also make sure you have your include folders for both glew and SDL set up under the GCC C++ Compiler (also under your settings for the C/C++ Builder). It should work now.

Can't run SDL2 project, "Cannot execute "": %1 Not a valid Win32-application"

I'm trying to teach myself how to use SDL2 with Qt Creator but keep getting into these "just let me code" situations. Currently, I'm just trying to open a window with a green picture on it (doing a tutorial) but I get this error:
Cannot execute "": %1 not a valid Win32-application
I'm using MinGw 5.3.0 32bit2 as the compiler and I've managed to run other projects without this error. I tried tinkering with the Build and Run configurations, but haven't had any luck. Currently my (essential) Run configurations look like this:
Executable C:\...\sdl_test\debug\sdl_test.exe
Working directory: C:\...\sdl_test
Also for reference, here's main.cpp:
#include <iostream>
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
using namespace std;
int main()
{
bool quit = false;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = nullptr;
window = SDL_CreateWindow("MVP", 100, 100, 600, 400,
SDL_WINDOW_SHOWN);
if(window == nullptr){
cout << "Window could not be created." << endl;
return 0;
}
SDL_Renderer* renderer = nullptr;
renderer = SDL_CreateRenderer(window, -1,
SDL_RENDERER_ACCELERATED);
SDL_Event* mainEvent = new SDL_Event();
SDL_Texture* grass_image = NULL;
grass_image = IMG_LoadTexture(renderer, "grass.bmp");
SDL_Rect grass_rect;
grass_rect.x = 10;
grass_rect.y = 50;
grass_rect.w = 250;
grass_rect.h = 250;
while(!quit && mainEvent->type != SDL_QUIT){
SDL_PollEvent(mainEvent);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, grass_image, NULL, &grass_rect);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
delete mainEvent;
return 0;
}
Feeling hopeless, since I just want to open a window with a green rectangle on it... is that too much to ask?!
EDIT:
Here's my .pro file
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
win32: LIBS += -L$$PWD/../../../../SDL2-2.0.5/i686-w64-mingw32/lib/ -lmingw32 -lSDL2main -lSDL2
INCLUDEPATH += $$PWD/../../../../SDL2-2.0.5/i686-w64-mingw32/include
DEPENDPATH += $$PWD/../../../../SDL2-2.0.5/i686-w64-mingw32/include
win32: LIBS += -L$$PWD/../../../../SDL2_image-2.0.1/i686-w64-mingw32/lib/ -lmingw32 -lSDL2_image
INCLUDEPATH += $$PWD/../../../../SDL2_image-2.0.1/i686-w64-mingw32/include
DEPENDPATH += $$PWD/../../../../SDL2_image-2.0.1/i686-w64-mingw32/include
win32:QMAKE_LFLAGS += -shared
The code you are showing to us works for Linux and any sane system :)
There could be a few issues for your problem:
1 - you are trying to run a 64 bit application in a 32 bit system
2 - your dll's could be corrupt
3 - your SDL dll's could be compiled with Microsoft Visual Studio (and you would need to get dll's generated with MinGW)
also, you should pass a few flags to the compiler, since you told us that you are using Qt Creator, possibly you have a projectname.pro file or a CMakeLists.txt
discover what you have, and pass those flags to the compiler:
-Wl,-subsystem,windows
and link against those libraries
-lmingw32 -lSDL2main -lSDL2

Compile and Run SDL On Terminal

Ok, so I compiled SDL/C++ on terminal easily by just doing:
g++ main.cpp -o main.out -pthread -std=c++11 `sdl2-config --cflags --libs` .
And then this is my main.cpp:
// #include <SDL/SDL.h>
#include "SDL2.0.4/SDL2-2.0.4/include/SDL.h"
int main(int argc, char** argv)
{
SDL_Window *__window;
//Init SDL
SDL_Init(SDL_INIT_EVERYTHING);
//Creation Window
__window = SDL_CreateWindow(
"Engine",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
640,
430,
SDL_SWSURFACE
);
while(true){
}
return 0;
}
Well when I do ./main.out to run it, it just stops iterating over while loop. There is no window popping up. I am using Ubuntu Linux. And as I said I want to run and compile sdl on terminal, I'm pretty sure I passed the compiling stage, it's the running that's irritating me.

GLEW and glfw compile error: undefined reference to symbol 'XConvertSelection'

I'm trying to compile this code:
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow* window;
#include <glm/glm.hpp>
using namespace glm;
int main( void )
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_RESIZABLE,GL_FALSE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Playground", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
do{
// Draw nothing, see you in tutorial 2 !
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
// Close OpenGL window and terminate GLFW
glfwTerminate();
return 0;
}
It's a code from a tutorial I found about OpenGL, I program mostly in Java when it comes to OpenGL, but I wanted to try something new so I went to try in C++.
I'm using QtCreator for this project.
At first I included GLEW and glfw3 libraries:
And the same for the glfw library file.
And then, when I try compiling the program I get this error:
In text:
$ /home/sapir/Qt/5.4/gcc_64/bin/qmake -spec linux-g++ CONFIG+=debug -o Makefile ../Test/Test.pro
$ g++ -Wl,-rpath,/home/sapir/Qt/5.4/gcc_64 -o Test main.o -L/home/sapir/Dropbox/Development/Computer/openGLTest/Test/../../../../../../../usr/local/lib/ -lglfw3 -lGLEW -lGLEWmx
/usr/bin/ld: /home/sapir/Dropbox/Development/Computer/openGLTest/Test/../../../../../../../usr/local/lib//libglfw3.a(glx_context.c.o): undefined reference to symbol 'glXQueryExtension'
//usr/lib/x86_64-linux-gnu/mesa/libGL.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make: *** [Test] Error 1
23:12:13: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project Test (kit: Desktop Qt 5.4.0 GCC 64bit)
When executing step "Make"
23:12:13: Elapsed time: 00:00.
I tired searching for an answer in forums and here, but I couldn't find anything that solved this problem.
Anybody got any Ideas?
After adding
-lXxf86vm -lXrandr -lGL -lGLU -lXi
to the gcc compiler, I get a different error, which contains:
/usr/bin/ld: /home/sapir/Dropbox/Development/Computer/openGLTest/Test/../../../../../../../usr/local/lib//libglfw3.a(x11_window.c.o): undefined reference to symbol 'XConvertSelection'
This is my make file: http://pastebin.com/xL5Hpwsf
And this is my .pro file: http://pastebin.com/yhkV7nn7
Ok, after some research I found that the DSO error which I got means that the order of the includes I've implemented is incorrect and cause the compilation to fail.
So what I did is I used the command:
pkg-config --static --libs x11 xrandr xi xxf86vm glew glfw3
To get the packages I need for them to run and in the right order.
Then I compiled the project accordingly.
That's it :)
I got same error "undefined reference to symbol 'XConvertSelection'" while compiling example from Irrlicht 3D, solved by adding "-lX11".
Then I got error "undefined reference to symbol 'XF86VidModeGetGamma'", solved by adding "-lXxf86vm"