【问题标题】:Cross-platform static-linking SDL2跨平台静态链接 SDL2
【发布时间】:2015-08-05 15:58:37
【问题描述】:

我正在构建一个 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:

【问题讨论】:

  • 这个问题已经问了很多遍了,没有一个人能答对。 +1。

标签: static-linking sdl-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

这当然意味着库的静态版本存在于库搜索路径列表中(.a libs 用于所有指定平台上的 gcc,尽管 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)。这编译没有错误,但程序不工作。
  • 它只是在后台静默运行,无需打开窗口。这些新库中的一些是否需要动态链接?除了 -lopengl32 和 -lm 之外,我将它们全部静态链接。
  • 我发现程序在尝试使用 printf() 和 getline() 到 stdio 时挂起,而不是实际打印或接收。这仅在静态链接时发生。与 stdio 的静态链接有什么特别之处吗?
  • @user258887 不认为是这样,但是您的链接标志错误。 -static 要求编译器生成完全没有 dll 链接的静态二进制文件; -Bstatic linker 选项要求链接器使用后续库的静态版本,除非指定了 -Bdynamic-Wl 是 gcc 命令,用于将选项的其余部分直接传递给 likner(因此 -Wl,-Bstatic,没有空格!)。刚刚在windows虚拟机上检查了一下,它按预期工作(依赖于没有-Bstatic的SDL2.dll,没有它,二进制大小差异很大)
  • 某些库的静态链接与创建静态二进制文件相比是否有优势?现在 -static 版本能够在另一台机器上运行,而 -Bstatic 版本仍然抱怨缺少 DLL。他们都无法与 stdio 交互:/
【解决方案2】:

它与静态链接没有直接关系。静态链接时,我必须包含所有 SDL 的依赖库。事实证明,拥有 -mwindows 会导致控制台通信失败。

【讨论】:

    猜你喜欢
    • 2021-09-26
    • 2013-07-11
    • 2020-02-09
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    相关资源
    最近更新 更多