Linking SDL library in a Makefile, c++ - c++

I'm working on a collaborative project and the guy who controls the master branch of the project works on a mac. Because of this, there are a few minor differences in his makefile that don't translate well to me on Windows. I use MinGW to hold my libraries, and compile using g++.
Makefile (as I thought it should go)
bomb: source/Level.cpp source/Level.h source/main.cpp
g++ -o bomb source/Level.cpp source/main.cpp -Wall -I. -I\MinGW\include\SDL -lSDLmain -lSDL -lSDL_image
The Makefile that works for him:
bomb: source/Level.cpp source/Level.h source/main.cpp
g++ -o bomb source/Level.cpp source/main.cpp -Wall -I. -I/Library/Frameworks/SDL.framework/Headers -lSDLmain -lSDL -lSDL_image -framework
My include files for the SDL library are at "C:\MinGW\include\SDL". Using that knowledge, how would I correctly write the makefile? As a side note, the error I get when using my current makefile is:
C:\MinGW\msys\1.0\src\mingwrt/../mingw/main.c:73: undefined reference to 'WinMain#16'

Have you tried adding -lmingw32 to the end of the libraries list? And do you have a int main(int argc, char** argv) function defined somewhere? Also, see the SDL FAQ

Related

SFML undefined reference even with defining libs

I tried to install SFML library to VS Code project using a Makefile. But I am faced with a problem. I have the following code:
#include <SFML/Graphics.hpp>
#include <string>
int main()
{
// Creating the main window
sf::RenderWindow window(sf::VideoMode(800, 600), "Asteroids");
return EXIT_SUCCESS;
}
And I have the following Makefile:
CXX := g++
CXX_FLAGS := -Wall -Wextra -std=c++17 -ggdb
BIN := bin
SRC := src
INCLUDE := include
LIB := lib
LIBRARIES := -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio -lsfml-main
EXECUTABLE := main
SFML_LIBRARY := "C:\\vcpkg\\installed\\x64-windows\\include"
SFML_LIB := "C:\\vcpkg\\installed\\x64-windows\\lib"
all: $(BIN)/$(EXECUTABLE)
run: clean all
cls
./$(BIN)/$(EXECUTABLE)
$(BIN)/$(EXECUTABLE): $(SRC)/*.cpp
$(CXX) $(CXX_FLAGS) -I$(INCLUDE) -L$(LIB) -I$(SFML_LIBRARY) -L$(SFML_LIB) $^ -o $# $(LIBRARIES)
clean:
-del $(BIN)\* /Q
But when I try to compile the code, I get the following error message:
g++ -Wall -Wextra -std=c++17 -ggdb -Iinclude -Llib -I"C:\\vcpkg\\installed\\x64-windows\\include" -L"C:\\vcpkg\\installed\\x64-windows\\lib" src/main.cpp -o bin/main -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio -lsfml-main
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\totalboy\AppData\Local\Temp\cclPlFnI.o:D:\C++ Projects\Asteroids/src/main.cpp:7: undefined reference to `__imp__ZN2sf6StringC1EPKcRKSt6locale'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\totalboy\AppData\Local\Temp\cclPlFnI.o: in function `main':
D:\C++ Projects\Asteroids/src/main.cpp:7: undefined reference to `__imp__ZN2sf9VideoModeC1Ejjj'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:\C++ Projects\Asteroids/src/main.cpp:7: undefined reference to `__imp__ZN2sf12RenderWindowC1ENS_9VideoModeERKNS_6StringEjRKNS_15ContextSettingsE'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:\C++ Projects\Asteroids/src/main.cpp:7: undefined reference to `__imp__ZN2sf12RenderWindowD1Ev'
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:23: bin/main] Error 1
Libs:
So, can somebody tell me what I do wrong?
The errors you receive can be attributed to the compilers you are using and used for compiling the SFML libraries you currently have. There are differences in the C++ ABI across compilers (and even across versions of the same compiler) [1]. When you want to link your code to a library, you have to make sure that the compiler you use and the one used with the library are the same, or are ABI-compatible.
When using vcpkg to download libraries, the source of those libraries are the ones that are actually downloaded and not the library itself. The source is then compiled "using the most recent version of Visual Studio that it could find [2]. Thus, if you want to use libraries downloaded via vcpkg in Windows, like in your case, you have to use Visual Studio, or, at least just the compiler, MSVC. So, a fix for your problem is to use MSVC (provided by Visual Studio), instead of the compiler in MinGW, which is usually GCC.
If you still want to use MinGW, there are two options:
The simplest option is to use MinGW-compatible SFML packages. There are official pre-built packages for MinGW over the SFML website. Note that these MinGW packages are only compatible with GCC 7.3.0 (at the time of writing). If you are using a different version or a different compiler, you have to resort to option 2.
Another option is to compile SFML on your own first. Once you have finished compiling, you can now link your code with the SFML libraries you have built. This option is also applicable when you are using compilers other than those used to compile the available pre-built SFML libraries.
References:
[1] https://stackoverflow.com/a/7119896/1116098
[2] https://learn.microsoft.com/en-us/cpp/build/vcpkg?view=vs-2019

Novice: How can I learn how to build GLEW with MinGW? [duplicate]

This question already has answers here:
Building glew on windows with mingw
(8 answers)
Closed 3 years ago.
I'm a daft C/C++ novice using Windows, building with MinGW through console. I have been looking for days on how to build GLEW so that I can statically link it with my incredibly simple SDL+OpenGL program. For static linking, GLEW supposedly requires a special lib apart from lglew32 called lglew32s, and this is what I cannot get my hands on.
I'm trying to learn to use gcc/g++ right now, and to understand the options and the whole preprocess/compile/link thing in general. I'm about 5% there. I found some GLEW building batch file examples around the net, most being pretty old, but even one of them that was new didn't compile lglew32s for me, so I can dynamically link but I can't statically link.
So because I can't find glew32s.lib anywhere online built with anything other than VS, I have to learn to understand what this means and somehow figure out how to compile glew32s with what I've learned from it:
gcc.exe -DGLEW_NO_GLU -O2 -Wall -W -Iinclude -DGLEW_BUILD -o src/glew.o -c src/glew.c
gcc.exe -fno-builtin -fno-stack-protector -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 -nostdlib
ar.exe cr lib/libglew32.a src/glew.o
gcc.exe -DGLEW_NO_GLU -DGLEW_MX -O2 -Wall -W -Iinclude -DGLEW_BUILD -o src/glew.mx.o -c src/glew.c
gcc.exe -fno-builtin -fno-stack-protector -shared -Wl,-soname,libglew32mx.dll -Wl,--out-implib,lib/libglew32mx.dll.a -o lib/glew32mx.dll src/glew.mx.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32 -nostdlib
ar.exe cr lib/libglew32mx.a src/glew.mx.o
I have learned to compile my own .cpp and .c projects using gcc/g++ (again I'm barely out of the "hello world" phase in terms of actual code), and also how to dynamically link them to the SDL and GLEW libraries. I understand very well now what this all means:
g++ sdlglew.cpp -o sdlglew -Wall -lmingw32 -lSDL2main -lSDL2 -lglew32 -lopengl32 -I "C:\SDL2-2.0.9\i686-w64-mingw32\include\SDL2" -L "C:\SDL2-2.0.9\i686-w64-mingw32\lib" -mwindows
(My SDL stuff is off in its own directory. GLEW's headers and libs are in MinGW's dir)
I think I need either -DGLEW_STATIC in my command OR #define GLEW_STATIC in my sdlglew.cpp to compile GLEW statically, but those options with lglew32 give me no errors upon compile and fail to start due to the missing glew32.dll. Compiler spits out errors with -static because SDL has not been set up for it yet.
Basically, if you have any resources on understanding what exactly the mentioned compile script is doing per line and how I could build glew32s, I'd be real happy :S I want to understand it, but it really seems like there's no documentation on it for us newbies
Can't you use the Makefile? (It should be included in the MinGW evironment, I think)
In which case I think you should just be able to do something along the lines of:
cd thefolderwithmakefile
make all GLEW_STATIC=1
Then you need to define GLEW_STATIC ( as you said by -DGLEW_STATIC or by #define GLEW_STATIC )when you are building your project files as well.

Mingw flag order [duplicate]

This question already has answers here:
Why does the order in which libraries are linked sometimes cause errors in GCC?
(9 answers)
Closed 4 years ago.
I use mingw32 to compile some C++ code. After trying some things and a lot of search I have a questions : The flags orders seems very important thought I found barely nothing that explain that on the internet. For exemple :
g++ main.cpp -L/lib -I/include -lmingw32 -lSDL2 -lSDL2main -Wall
-g -o main.exe -> Compile
g++ main.cpp -L/lib -I/include -lmingw32 -lSDL2main -lSDL2 -Wall
-g -o main.exe -> Not compile
g++ main.cpp -L/lib -I/include -lSDL2 -lSDL2main -lmingw32 -Wall
-g -o main.exe -> Compile
I can understand why -lSDL2main need -lSDL2 first but so why the place of -lmingw32 is not important ?
EDIT :
I explain : from what I know of compilation process .cpp come first, -l indicate clearly libraries (last step of compilation). So why if I put main.cpp to the end it's continue compilation process and finish with error from the library. What mingw use if he don't have any source file, he just compile lib ?
It's not the order of the fags, it's the order of the libraries. The last libraries should be the ones that everyone requires, then the second to last is the one that the last doesn't need, etc.
Why libmingw32 is not required is probably because the SDL libraries don't need it.

I cannot seem to get SDL to work with sublime text

I am making a simple game and wanted to use SDL for the graphics. I run linux Ubuntu, and use sublime text editor, g++ compiler, and I am coding in c++. I downloaded SDL and followed these steps.
After I followed those steps, all of the SDL error stopped appearing. However, the flag variables aren't working.
This is the code:
#include <SDL2/SDL.h>
Risk() {
SDL_Init(SDL_INIT_HAPTIC);
window = SDL_CreateWindow("Board",SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 500,500, SDL_WINDOW_RESIZABLE);
SDL_GetError();
}
The error appearing in my compiler is:
tom#TBT-XPS-13-9360:~/Documents/Subjects/CS/Fun/Risk$ g++ -std=c++14
Game.cpp -W/tmp/ccLwSxiL.o: In function `Risk::Risk()':
Game.cpp:(.text._ZN4RiskC2Ev[_ZN4RiskC5Ev]+0x1f): undefined reference
to `SDL_Init'
Game.cpp:(.text._ZN4RiskC2Ev[_ZN4RiskC5Ev]+0x44): undefined reference
to `SDL_CreateWindow'
Game.cpp:(.text._ZN4RiskC2Ev[_ZN4RiskC5Ev]+0x54): undefined reference
to `SDL_GetError'
collect2: error: ld returned 1 exit status
I think the error is the SDL libraries are in the wrong place, or Sublime doesn't know where they are.
The problem is that Sublime is not adding the required instruction to indicate that the executable should be linked to the SDL2 library.
You can indicate it with the parameter -lSDL2 on the command line, or use the sdl2-config program with sdl2-config --libs, something like this:
$ g++ -o executable-name source.cpp -lSDL2
or
$ g++ -o executable-name source.cpp $(sdl2-config --libs)
sdl2-config is just an utility that outputs appropriate configuration options for compiling and linking. You can see it by running it alone:
$ sdl2-config --libs
it should output something like:
-L/usr/lib -lSDL2
You can see the same -lSDL2 mentioned before, and also a -L/usr/lib instruction that indicates the linker to include libraries in the /usr/lib/ directory in its search path.
In general, you should use the sdl2-config for getting the required configuration options to pass to the compiler instead of indicating them by yourself, unless you know what you're doing, of course.
Instead of going to the command line to compile, you can use the Make build system in Sublime Text. Add a file named Makefile to your project directory with the following content:
# OBJS place here every file to compile as part of the project
OBJS = Game.cpp
# CC compiler to use
CC = g++
# COMPILER_FLAGS compilation options
COMPILER_FLAGS = -std=c++14 -Wall `sdl2-config --cflags`
# LINKER_FLAGS libraries to link
LINKER_FLAGS = `sdl2-config --libs`
# OBJ_NAME executable
OBJ_NAME = mygame
all : $(OBJS)
$(CC) $(OBJS) $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $(OBJ_NAME)
Then go to menu Tools -> Build System and select Make. Now try building your project, if successful, a mygame executable should have been created.

Linking QX11Info

I'm porting an application qt3 -> qt5. As part of that I have in a .cpp file changed (Qt3)
mySystemstruct.display = theWidget->x11Display();
into (Qt5)
mySystemstruct.display = QX11Info::display();
Include has been added in the file.
#include <QX11Info>
I am not using Qt Creator. The file in question is not been linked using qmake. (other files has)
I get this link errors:
/home/go/NetBeansProjects/Arbete_216/Ajourwork/Components/TheRealDeal/GUI/linuxobj//GO_C_QtGUI.o: In function `GO_C_QtGUI::initHistoryFilm(QWidget*, int, int)':
/home/go/NetBeansProjects/Arbete_216/Ajourwork/Modules/GUI/QtGUI/GO_C_QtGUI.cpp:668: undefined reference to `QX11Info::display()'
using this compile command:
clang++ -o gvs_GUI linuxobj/*.o linuxobj/libQtSpecific.a -DLINUX -I/include/ -g -I /opt/intel/composer_xe_2015.1.133/ipp/include/ -Wno-deprecated -D_GNU_SOURCE -D_REENTRANT -D__STDC_CONSTANT_MACROS -I/usr/include/postgresql/ -I/usr/local/Qt/5.2.1/gcc_64/include/QtX11Extras/ -I/usr/local/Qt/5.2.1/gcc_64/include/QtWidgets/ -I/usr/local/Qt/5.2.1/gcc_64/include/ -I/usr/local/Qt/5.2.1/gcc_64/include/QtGui/ -fPIC -fPIE -I/home/go/ffmpeg_build/include/ -I/usr/local/Qt/5.2.1/gcc_64/include/QtCore/ -fPIC -fPIE -I/home/go/ffmpeg_build/include/libavcodec -I/home/go/ffmpeg_build/include/libavformat/ -lpq -lippi -lipps -lippcore -lpthread -lgcrypt -lippvm -lippcv -lippcc -L/opt/intel/composer_xe_2015.1.133/ipp/lib/intel64 -L/usr/local/Qt/5.2.1/gcc_64/lib/ -L/usr/X11R6/lib/ -lXv -lX11 -lXext -ltar -lavformat -lavcodec -lavfilter
Is it not possible to build using Qt libs not using qmake? My code has been built that way with earlier versions of Qt so it seems it should work.(?)
Since not using qmake for linking, I use -I/usr/local/Qt/5.2.1/gcc_64/include/QtX11Extras/ -L/usr/local/Qt/5.2.1/gcc_64/lib/ but it doesn't seem to work.
The QtX11-lib seems to be in place:
locate libQt5X11Extras.so
/usr/local/Qt/5.2.1/gcc_64/lib/libQt5X11Extras.so
/usr/local/Qt/5.2.1/gcc_64/lib/libQt5X11Extras.so.5
/usr/local/Qt/5.2.1/gcc_64/lib/libQt5X11Extras.so.5.2
/usr/local/Qt/5.2.1/gcc_64/lib/libQt5X11Extras.so.5.2.1
What am I doing wrong here?
-L/usr/local/Qt/5.2.1/gcc_64/lib/ only tells the linker where to find the libraries.
You must then add -lQt5X11Extras to ask to link to the Qt5X11 library.