跨平台静态链接SDL2

4
我正在编写一个SDL2/C++程序,需要在没有安装SDL的Windows、Mac和Linux机器上进行移植。
我了解到静态链接是解决方案,但我不擅长编译,也不知道如何进行静态链接。
我的程序仅依赖于SDL2、GLU和OpenGL。我使用MinGW(在Windows 8.1上)或gcc(在Ubuntu 14.04上)编译C++——这两个操作系统都已经本地安装了SDL。
这是我的当前makefile,是从我的一位教授给我的示例makefile中修改得来的:
# Executable/file name
EXE=experiment

#  MinGW
ifeq "$(OS)" "Windows_NT"
CFLG=-O3 -Wall -DUSEGLEW
LIBS= -lSDL2 -lglu32 -lopengl32
CLEAN=del *.exe *.o *.a
else
#  OSX
ifeq "$(shell uname)" "Darwin"
CFLG=-O3 -Wall -Wno-deprecated-declarations
LIBS=-framework SDL2 -framework OpenGL
#  Linux\Unix\Solaris
else
CFLG=-O3 -Wall
LIBS= `sdl2-config --cflags --libs` -lGLU -lGL -lm
endif
#  OSX\Linux\Unix\Solaris
CLEAN=rm -f $(EXE) *.o *.a
endif

# Dependencies
$(EXE).o: $(EXE).cpp FORCE


.c.o:
    gcc -c -o $@ $(CFLG) $<
.cpp.o:
    g++ -std=c++11 -c -o $@ $(CFLG) $<

#  Link
$(EXE):$(EXE).o
    g++ -std=c++11 -O3 -o $@ $^   $(LIBS)

#  Clean
clean:
    $(CLEAN)

# Force
FORCE:

3
这个问题已经被问了很多次,但没有一个人能成功地回答它。+1。 - Owl
2个回答

1
要链接静态库,您可以指定库文件的路径: gcc -o out_bin your_object_files.o path/to/lib.a -lfoo 或者使用-Bstatic链接器标志请求链接器使用静态版本。通常,您会想要将链接重置为动态链接其余库,例如对于静态SDL2和GLU但是动态GL: gcc -o out_bin your_object_files -Wl,-Bstatic -lSDL2 -lGLU -Wl,-Bdynamic -lGL 当然,这意味着库的静态版本存在于库搜索路径列表中(在所有指定平台上使用gcc的.a libs,尽管MSVC使用.lib用于静态库)。
然而,您通常根本不想这样做。软件通常依赖于某些库(在Linux上广泛使用,具有软件包和依赖项列表),或者将所需库与之一起提供。您可以将SDL动态库与程序一起分发,并使用LD_LIBRARY_PATH或相对rpath加载它。
还请注意,较新的SDL2实现了动态加载函数,从而提供了一种方法来使用用户指定的动态库覆盖SDL,即使是静态链接的。

谢谢!但是似乎-Bstatic没有产生预期的效果(它仍然在运行时寻找SDL2.dll)。删除“B”和逗号似乎可以解决这个问题,但是接着会出现大量未定义的引用。我看到另一个解决方案是,在静态链接时,需要手动链接到SDL引用的所有内容(-lmingw32 -lSDL2main -lSDL2 -mwindows -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc)。这样编译没有错误,但程序无法工作。 - lcdavis13
它只是在后台静默运行,而不打开窗口。这些新库中是否有一些需要动态链接?我将它们全部静态链接,除了-opengl32和-lm。 - lcdavis13
静态链接某些库与创建静态二进制文件相比,是否有优势?目前,-static版本能够在另一台机器上运行,而-Bstatic版本仍然抱怨缺少DLL。它们都无法与stdio交互 :/ - lcdavis13
我的程序出现了问题,每当我运行静态版本时,cin返回失败。不确定如何解决它。但我确实找到了其他DLL所需的内容,因此现在-static版本和-Bstatic版本正在完全相同的操作。非常感谢迄今为止提供的帮助! - lcdavis13
这与静态链接没有直接关系。在进行静态链接时,我不得不包含所有SDL的依赖库。结果发现,使用-mwindows会导致控制台通信失败。 - lcdavis13
显示剩余3条评论

1
这与静态链接无直接关系。在进行静态链接时,我必须包含所有SDL依赖库。结果发现,使用-mwindows会导致控制台通信失败。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接