i had made a game on C using SDL2, SDL2_image, SDL2_mixer and SDL2_ttf libraries installed on Linux (Ubuntu) by sudo apt-get install libsdl2-dev (for example), and i wanted to improve it so it will be compileable on Linux, macOS and Windows (with MinGW) without pre-installing required libraries.
i downloaded libraries' sourse code from SDL Github (for example SDL2) and compiled them on Ubuntu and macOS using ../configure --prefix=/some/path; make; make install in "build" folder that i had created in folder with source code after unzipping downloaded archive. as for Windows, i downloaded SDL2-devel-2.32.0-mingw.zip (as for SDL2) from the same source and just extracted "i686-w64-mingw32" folder from it.
after that i uploaded obtained folders (i686-w64-mingw32 for Windows and that plased in /some/path from --prefix for Linux and macOS) on my game's Github repository renamed them like "SDL2", "SDL2_image", etc. respectively and at the end deleted that folders where i compiled libraries.
so the structure of my project is something like that:
- game_dir
- inc/header.h
- resources
- frameworks
- linux
- SDL2
- bin/sdl-config
- include/SDL2/.h files
- lib
- cmake/SDL2
- sdl2-config.cmake
- sdl2-config-version.cmake
- pkgconfig/sdl2.pc
- libSDL2.a libSDL2.la
- libSDL2_test.a libSDL2_test.la
- libSDL2-2.0.so.0.3200.0
- libSDL2main.a libSDL2main.la
- cmake/SDL2
- share/aclocal/sdl2.m4
- SDL2_image this three have
- SDL2_mixer "include" and "lib" folders
- SDL2_ttf (same as in "SDL2" folder)
- SDL2
- macos the same structure with "linux" folder (but instead .so files there are .dylib files)
- windows there are also bin/.dll files and .dll.a files in "lib"
- linux
- folders with images, music, etc.
- frameworks
- src/.c files
- Makefile
- .dll files for Windows
then i cloned my repository and tried to compile the code with such Makefile:
executable:=mygame
inc_dir:=inc
src_dir:=src
obj_dir:=obj
lib_dir:=resources/frameworks/
src_files:=$(wildcard $(src_dir)/*.c)
obj_files:=$(src_files:$(src_dir)/%.c=$(obj_dir)/%.o)
compiler:=gcc
cc_flags:=-std=c11 -Wall -Wextra -Werror -Wpedantic
inc_flags=-I$(inc_dir) \
-I$(lib_dir)/SDL2/include/SDL2 \
-I$(lib_dir)/SDL2_image/include/SDL2 \
-I$(lib_dir)/SDL2_mixer/include/SDL2 \
-I$(lib_dir)/SDL2_ttf/include/SDL2
lib_flags=-L$(lib_dir)/SDL2/lib -lSDL2main -lSDL2 \
-L$(lib_dir)/SDL2_image/lib -lSDL2_image \
-L$(lib_dir)/SDL2_mixer/lib -lSDL2_mixer \
-L$(lib_dir)/SDL2_ttf/lib -lSDL2_ttf
newdir:=mkdir
removedir:=rm
removefile:=rm
ifeq ($(OS),Windows_NT)
lib_dir:=$(lib_dir)windows
lib_flags:=$(lib_flags) -lmingw32 -mwindows
removedir:=rmdir /s /q
removefile:=del
else
newdir:=mkdir -p
removedir:=rm -rf
removefile:=rm -f
ifeq ($(shell uname),Darwin)
lib_dir:=$(lib_dir)macos
else
lib_dir:=$(lib_dir)linux
endif
endif
all: $(executable)
$(executable): $(obj_files)
$(compiler) $(cc_flags) $^ -o $@ $(inc_flags) $(lib_flags)
$(obj_dir)/%.o: $(src_dir)/%.c | $(obj_dir)
$(compiler) $(cc_flags) -c $< -o $@ $(inc_flags)
$(obj_dir):
$(newdir) $(obj_dir)
clean:
$(removedir) $(obj_dir)
uninstall: clean
$(removefile) $(executable)
reinstall: uninstall all
.PHONY: all clean uninstall reinstall
it works perfectly on Windows, but on Linux and macOS when it comes to compile executable file, such errors occur:
- on Linux:
/usr/bin/ld: resources/frameworks/linux/SDL2/lib/libSDL2.a(SDL_stdlib.o): In function «SDL_fmod_REAL»:
/path/to/directory/where/i/compiled/library/(that_does_not_exist_now)/src/stdlib/SDL_stdlib.c:279:(.text+0x35d): undefined reference to `fmod'
...
collect2: error: ld returned 1 exit status
make: *** [Makefile:46: mygame] Error 1
- on macOS:
Undefined symbols for architecture x86_64:
"_CFArrayAppendValue", referenced from:
_GetDisplayMode in libSDL2.a(SDL_cocoamodes.o)
...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mygame] Error 1
there are a lot of errors on every of that os, they just have the same syntax so i gave only one of them for each os for example. also problems are not only with SDL2 but with other libraries too.
actually, when i use frameworks (that things like SDL2.framework) on macOS (of cource with a bit different Makefile), it works too, but i want everything to be "in one style" with "include" and "lib" folders for each os. can it be possible?
i thought adding -static or -Wl,-Bstatic to lib_flags or using -l: instead of -l or specifying the path to library like for example $(lib_dir)/SDL2/lib/libSDL2.a can solve that problems, but it still doesn't work.
maybe i need to compile libraries with some extra flags or upload dependency libraries like freetype2 for SDL2_ttf or just somehow improve my Makefile?
thank you in advance!
versions of operating systems on which i worked: Ubuntu 24.04, macOS 11.1.0 installed on VirtualBox.
(also sorry if i have some mistakes in my english, it's not my native language)