在Mac上用mingw32交叉编译Windows C++项目遇依赖及静态编译问题
跨平台编译SDL2 C++游戏到Windows的链接问题
我在macOS Big Sur系统上开发了一款基于SDL2和大量C11库的C游戏。使用x86_64-w64-mingw32-gcc可编译出Windows平台的.exe文件,但运行该文件时提示缺少libstdc++-6.dll——SDL相关DLL可通过下载解决,但下载libstdc++-6.dll后运行仍出现更多错误。尝试添加-static编译选项,却出现大量“undefined reference to”链接错误。本地使用g++-12编译该项目可正常运行,现寻求解决libstdc++依赖问题或实现正确静态链接的方案。
当前使用的Makefile
#OBJS specifies which files to compile as part of the project OBJS = strategy.cpp #CC specifies which compiler we're using x86_64-w64-mingw32-gcc CC = x86_64-w64-mingw32-gcc #INCLUDE_PATHS specifies the additional include paths we'll need INCLUDE_PATHS = -I /Users/jirnyak/Mirror/DND/mingw_dev_lib/include/SDL2 #LIBRARY_PATHS specifies the additional library paths we'll need LIBRARY_PATHS = -L /Users/jirnyak/Mirror/DND/mingw_dev_lib/lib #COMPILER_FLAGS specifies the additional compilation options we're using # -w suppresses all warnings # -Wl,-subsystem,windows gets rid of the console window COMPILER_FLAGS = -w -Wl,-subsystem,windows #LINKER_FLAGS specifies the libraries we're linking against LINKER_FLAGS = -lmingw32 -lSDL2main -lSDL2 -lSDL2_ttf -lSDL2_image -lstdc++ #OBJ_NAME specifies the name of our exectuable OBJ_NAME = dukalop_win #This is the target that compiles our executable all : $(OBJS) $(CC) $(OBJS) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(LINKER_FLAGS) `/Users/jirnyak/Mirror/DND/mingw_dev_lib/bin/sdl2-config --cflags` `/Users/jirnyak/Mirror/DND/mingw_dev_lib/bin/sdl2-config --libs` -static-libstdc++ -static -o $(OBJ_NAME)
已尝试的方案
- 下载
libstdc++-6.dll:运行.exe时出现更多未知错误 - 添加
-static编译选项:编译时出现大量链接错误,示例如下:
ld: /Users/jirnyak/Mirror/DND/mingw_dev_lib/lib/libSDL2.a(SDL_hidapi.o): in function `PLATFORM_hid_enumerate': /Users/valve/release/SDL2/SDL2-2.26.4-source/foo-x64/../src/hidapi/windows/hid.c:387: undefined reference to `__imp_SetupDiGetClassDevsA' ... **many similar errors** ... /opt/local/lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld: /Users/jirnyak/Mirror/DND/mingw_dev_lib/lib/libSDL2_ttf.a(libSDL2_ttf_la-hb-uniscribe.o): in function `_hb_generate_unique_face_name': /Users/valve/release/SDL_ttf/SDL2_ttf-2.20.2-source/foo-x64/../external/harfbuzz/src/hb-uniscribe.cc:306: undefined reference to `__imp_UuidCreate' collect2: error: ld returned 1 exit status make: *** [all] Error 1
Mac本地正常编译命令
g++-12 strategy.cpp -o strategy -I /Library/Frameworks/SDL2.framework/Headers -F /Library/Frameworks -framework SDL2 -I /Library/Frameworks/SDL2_image.framework/Headers -F /Library/Frameworks -framework SDL2_image -I /Library/Frameworks/SDL2_ttf.framework/Headers -F /Library/Frameworks -framework SDL2_ttf -fopenmp -std=c++11
解决方案
方案一:仅静态链接C++标准库(推荐)
无需全静态链接,仅静态链接C++和GCC运行时库,避免分发libstdc++-6.dll,SDL等库仍使用动态链接:
- 修改Makefile中的编译命令,移除
-static,保留-static-libstdc++并添加-static-libgcc,同时补全本地编译用到的-fopenmp和-std=c++11:
all : $(OBJS) $(CC) $(OBJS) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(LINKER_FLAGS) `/Users/jirnyak/Mirror/DND/mingw_dev_lib/bin/sdl2-config --cflags` `/Users/jirnyak/Mirror/DND/mingw_dev_lib/bin/sdl2-config --libs` -static-libstdc++ -static-libgcc -fopenmp -std=c++11 -o $(OBJ_NAME)
- 将以下文件与编译出的
dukalop_win.exe放在同一目录:SDL2.dll、SDL2_ttf.dll、SDL2_image.dll(从mingw_dev_lib的bin目录复制)- SDL_ttf依赖的
libfreetype-6.dll、SDL_image依赖的libpng16-16.dll/libjpeg-9.dll等(若有)
方案二:全静态链接(需补充系统依赖库)
若要实现完全静态链接,需补充SDL静态库依赖的Windows系统API库:
- 修改Makefile的
LINKER_FLAGS,添加缺失的系统库:
LINKER_FLAGS = -lmingw32 -lSDL2main -lSDL2 -lSDL2_ttf -lSDL2_image -lstdc++ -lsetupapi -lrpcrt4 -lole32 -limm32 -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid
- 确保编译命令中保留
-static,同时添加本地编译用的-fopenmp和-std=c++11:
all : $(OBJS) $(CC) $(OBJS) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(LINKER_FLAGS) `/Users/jirnyak/Mirror/DND/mingw_dev_lib/bin/sdl2-config --cflags` `/Users/jirnyak/Mirror/DND/mingw_dev_lib/bin/sdl2-config --libs` -static-libstdc++ -static -fopenmp -std=c++11 -o $(OBJ_NAME)
- 确认mingw_dev_lib中的SDL库为静态版本(
.a文件),而非动态导入库(.dll.a)
内容的提问来源于stack exchange,提问作者k-irsan_kaifatmailru
相关产品推荐
相关产品推荐

