I'm trying to statically link sdl2 for windows and linux.

Here's my current makefile:

Code:

EXE_FILE = bin/MapJumper
OBJ_FILES = obj/main.o
FLAGS = --std=c++17 -w -fpermissive
CC = g++

exe : clean
exe : $(EXE_FILE)

debug: FLAGS += -ggdb
debug : exe

windows: EXE_FILE = bin/mapJumper.exe
windows: CC = x86_64-w64-mingw32-g++
windows: exe

$(EXE_FILE) : $(OBJ_FILES)
   $(CC) -o $(EXE_FILE) $(OBJ_FILES) $(FLAGS) `pkg-config --static --libs sdl2 SDL2_image SDL2_ttf SDL2_mixer` -lSDL2main

obj/main.o : src/main.cpp src/bounds.h src/player.h src/texture.h src/world.h
   $(CC) -c -o obj/main.o src/main.cpp $(FLAGS)
run : exe
   $(EXE_FILE) &

clean:
   rm -f *.o obj/main.o


When I make for linux everything works fine, but when i make for windows i get the following errors:

Code:

jc@jc-Inspiron-560:~/Desktop/c++Dev/Map Jumper$ make windows
rm -f *.o obj/main.o
x86_64-w64-mingw32-g++ -c -o obj/main.o src/main.cpp --std=c++17 -w -fpermissive
x86_64-w64-mingw32-g++ -o bin/mapJumper.exe obj/main.o --std=c++17 -w -fpermissive `pkg-config --static --libs sdl2 SDL2_image SDL2_ttf SDL2_mixer` -lSDL2main
/usr/bin/x86_64-w64-mingw32-ld: cannot find -ldl
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lasound
/usr/bin/x86_64-w64-mingw32-ld: cannot find -ldl
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lpulse-simple
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lpulse
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lX11
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lXext
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lXcursor
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lXinerama
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lXi
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lXrandr
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lXss
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lXxf86vm
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lwayland-egl
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lwayland-client
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lwayland-cursor
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lxkbcommon
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lrt
collect2: error: ld returned 1 exit status
make: *** [Makefile:17: bin/MapJumper] Error 1
jc@jc-Inspiron-560:~/Desktop/c++Dev/Map Jumper$


here's the github repo if it helps. I'm running linux mint

Any help is much appreciated!
While `pkg-config` appears to be generating the list of libraries that it should, that output suggests that your linker cannot find whatever folder those libraries are within.
You first will want to install the SDL2 development libraries with the below commands, and install a cross-compiler, which can build programs for other OSes and archetectures. In this case we want to use mingw. This can be accomplished via the below commands. You should definitely add a "building" section to your readme, as it is a pain for users to get started with it, which includes the packages they should install.


Code:
sudo apt install libsdl2-dev
sudo apt install libsdl2-image-dev
sudo apt install libsdl2-mixer-dev
sudo apt install libsdl2-ttf-dev
sudo apt install libglm-dev
sudo apt install mingw-w64
sudo apt install mingw-w64-tools


However, one of the main issues that we face is that while mingw provides many already cross-compiled libraries, the ones you want to use are not. So, we need to build static versions of each of these libraries. We'll start with the SDL2 one. Note that we "could" just install the already packaged one, but this is going to have to be done for each library, so may as well get used to it.
Download the SDL2 source, and run the following commands from inside of it:


Code:
mkdir build && cd build

PREFIX=/usr/local/win64
TOOLSET=x86_64-w64-mingw32
export CC="$TOOLSET-gcc -static-libgcc"

../configure --target=$TOOLSET --host=$TOOLSET --build=x86_64-linux --prefix=$PREFIX/$TOOLSET
make -j && sudo make install


Boom, we have a cross-compiled SDL2 library that we can use! It is installed into /usr/local/win64/.

Next, you'll want to properly set up your makefile. It's generally easier if you use variables rather than specifying targets when building, and in this case we can use the following makefile, where we can change the objects we want to generate and the headers needed quite easily:


Code:
ifeq ($(os),windows)
  TARGET ?= bin/MapJumper.exe

  CC := x86_64-w64-mingw32-g++
  CFLAGS := --std=c++17 -w -fpermissive -I/usr/local/win64/x86_64-w64-mingw32/include
  LDFLAGS := -static -static-libgcc
  LIBS := `/usr/local/win64/x86_64-w64-mingw32/bin/sdl2-config --static-libs`
else
  TARGET ?= bin/MapJumper

  CC := g++
  CFLAGS := --std=c++17 -w -fpermissive `pkg-config --cflags sdl2 SDL2_image SDL2_ttf SDL2_mixer`
  LDFLAGS :=
  LIBS := `pkg-config --libs sdl2 SDL2_image SDL2_ttf SDL2_mixer`
endif

OBJECTS := \
   obj/main.o

DEPS := \
   src/bounds.h \
   src/player.h \
   src/texture.h \
   src/world.h

$(TARGET): $(OBJECTS)
   $(CC) $(LDFLAGS) $^ -o $@ $(LIBS)

obj/%.o: src/%.cpp $(DEPS)
   $(CC) $(CFLAGS) $< -c -o $@

clean:
   rm -f $(OBJECTS) $(TARGET)

.PHONY: clean


Now we can run make os=linux to build for linux, and everything works as expected. When we do make os=windows however, we are met with the following error:


Code:
src/player.h:3:10: fatal error: SDL2/SDL_image.h: No such file or directory
    3 | #include <SDL2/SDL_image.h>


Surprise suprise, you aren't just asking how to compile and link against SDL2. You've got an array of other libraries that are used, namely SDL2_image, SDL2_mixer, SDL2_ttf, and glm. These libraries have to built statically for the cross compile now!

First let's set up some common variables so we don't need to do this before every execution. Note that this requires you to use the same terminal window the whole time! If you close the terminal window, just rerun these commands:


Code:
PREFIX=/usr/local/win64
TOOLSET=x86_64-w64-mingw32
CROSSPATH=$PREFIX/$TOOLSET


Let's start with SDL2_image. We just need PNG support, so it depends on zlib and libpng. Download the zlib source, and run the following commands within it:


Code:
make -f win32/Makefile.gcc PREFIX=x86_64-w64-mingw32-
sudo DESTDIR=$PREFIX/$TOOLSET/ INCLUDE_PATH=include LIBRARY_PATH=lib BINARY_PATH=bin make install -f win32/Makefile.gcc


Next, download the libpng source, and run the following commands within it:


Code:
export CFLAGS="-I${CROSSPATH}/include"
export CPPFLAGS="-I${CROSSPATH}/include"
export LDFLAGS="-L${CROSSPATH}/lib"
./configure --target=$TOOLSET --host=$TOOLSET --build=x86_64-linux --prefix=$CROSSPATH
make && sudo make install


Next, download the SDL2_image source, and run the following commands within it:


Code:
mkdir build && cd build
export CC="$TOOLSET-gcc -static-libgcc"
export PKG_CONFIG_PATH=${CROSSPATH}/lib/pkgconfig
export PATH=${CROSSPATH}/bin:$PATH
export CFLAGS="-I${CROSSPATH}/include"
export CPPFLAGS="-I${CROSSPATH}/include"
export LDFLAGS="-L${CROSSPATH}/lib"
../configure --target=$TOOLSET --host=$TOOLSET --build=x86_64-linux --prefix=$CROSSPATH --disable-shared --disable-webp --disable-jpg --disable-gif --disable-tif
make && sudo make install


You've now successfully built and installed the cross-compiled SDL2_image library. Now let's build the SDL_mixer library tomorrow. First though, be sure to change the following lines in your code; as this is not the correct include paths you should be using:


Code:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>

--- to ---

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_mixer.h>
Ok so I've followed all of your instructions, and got everything working up to the point you described. So how exactly do I build SDL_image and SDL_ttf and SDL_mixer? I downloaded the src for them, but it's not the same setup as the sdl2 source so I can't follow the same instructions as for SDL2.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement