gpt4 book ai didi

c++ - 如何在 Linux 上静态编译 SDL2 和 GLEW 应用程序?

转载 作者:行者123 更新时间:2023-11-28 00:00:09 25 4
gpt4 key购买 nike

我正在尝试编译一个使用 SDL2 和 GLEW 的 OpenGl 应用程序,以便它可以在它可能找到的任何版本的 Linux 上运行——而不仅仅是它最初编译的地方。为此,我尝试了几种方法,但均无效。

我尝试直接链接到 .a 文件,该文件是在从每个图书馆的网站下载的 GLEW 和 SDL 的解压根目录中运行 make 生成的。这会产生以下错误:

/usr/bin/ld: /opt/SDL2-2.0.4/build/.libs/libSDL2.a(SDL_syssem.o): undefined reference to symbol 'sem_getvalue@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line

我已经尝试像使用动态链接库一样构建,除了跨平台功能(使用 pkg-config --libs sdl2pkg-config --libs glew )外,它工作正常,但添加了 -static ,此时我收到以下错误:

/usr/bin/ld: cannot find -lGLEW
/usr/bin/ld: cannot find -lGL

当我将之前的场景更改为指向静态编译的 GLEW 库时,我收到了 OpenGl 函数的 undefined reference 错误以及许多 SDL 函数中的 undefined reference 错误,如下所示。添加 -lGL 不会改变任何内容。

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadObject_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadObject_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_UnloadObject_REAL':

当我尝试使用 pkg-config --libs --static <library name> 时对于所有库,我收到以下错误:

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/bin/ld: cannot find -lasound
/usr/bin/ld: cannot find -lpulse-simple
/usr/bin/ld: cannot find -lpulse
/usr/bin/ld: cannot find -lsndio
/usr/bin/ld: cannot find -lwayland-egl
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libwayland-cursor.a(libwayland_cursor_la-xcursor.o): In function `XcursorImagesDestroy':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libXcursor.a(file.o):(.text+0x7d0): first defined here
/usr/bin/ld: cannot find -lGLEW
/usr/bin/ld: cannot find -lGL
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(GetDflt.o): In function `GetHomeDir.part.0':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(GetDflt.o): In function `GetHomeDir.part.0':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(xim_trans.o): In function `_XimXTransSocketINETConnect':
collect2: error: ld returned 1 exit status

注意:以上所有输出均来自命令 g++ -o /path/to/outputExecutable <list of object files>.o <libraries as described above>

注意:我不认为这个问题与 Stack Exchange 网络上的任何其他问题重复,因为我已经尝试解决这个问题大约一个半月了,而且我已经看到了很多这样的问题并尝试了其中的所有方法,因此,即使症状相同,潜在的问题也不同。

注意:这是一个闭源应用程序,因此动态链接不是一个选项,因为它需要分发源代码以允许用户在他们自己的系统上构建二进制文件。

注意:我目前正在尝试通过 g++ 将其与 Linux 一起编译,但是,我也打算使用 mingw 为 Windows 分发此应用程序。任何可行的建议都比仅适用于 Linux 的建议更可取,但是,如果我无法从此处结束的内容中找出那部分,我可以问另一个问题。

注意:我正在使用 Ubuntu 16.04 LTS x64 进行编译。

在此先感谢您在这个问题上的进展。很抱歉文字墙,但是,我想提供尽可能多的信息。我期待任何答案!

最佳答案

较旧的 Loki 游戏采用全静态链接。可能不再值得了,如果您使用外部库,则困难得多。

库往往不能自给自足,需要其他库,....动态库内置了依赖信息,而静态库只是.o的归档。文件 - 它可能取决于某些东西,但没有专门的部分描述应该使用哪些额外的库。您的第一个错误表明 libSDL2.a 使用符号 sem_getvalue@@GLIBC_2.2.5 (sem_getvalue 函数,标有 glibc 版本)无法解决 - 很可能是因为您没有添加 -lpthread到您的链接器标志。 (libSDL.so 取决于某些版本的 pthrtead 等 - 这就是为什么如果您不直接使用它,则不需要手动链接它的原因)。

GLEW 应该没有静态链接问题。您需要更具体地说明您遇到的错误。也许您的库顺序错误,链接器无法解析 GL 函数。需要查看实际的链接行和一些“ undefined reference ”错误才能更具体。

pkg-config--static flag 应该给你依赖项列表(例如 -lpthread 应该在 sdl2-config --static-libs 的输出中等等),但它本身不会产生与给定库的静态链接。要请求静态链接,有-static生成静态可执行文件的 gcc 标志(很难!)和 -Bstatic linker 标记为在它之后指定的所有库使用静态版本(这样你就可以使用一些静态库和一些动态库)。 -Bdynamic是对口的,要求使用动态库。例如。使用静态 SDL 和 GLEW 但动态 GL 链接行应该类似于(如果您使用 gcc 链接,而不是直接使用 ld)gcc ${OBJECT_FILES} -Wl,-Bstatic -lSDL2 -lGLEW -Wl,-Bdynamic -lGL -lpthread -ldl -lm <everything else SDL2 requires - query with sdl2-config> .

你的 /usr/bin/ld: cannot find -lasound线路可能有两个原因 - 静态链接或与您没有安装开发库的事实有关(例如 libasound2-devlibpulse-dev ,... - 至少他们在 debian 上调用它,ubuntu 不太可能有不同名)。 “用户”库通常包含例如libasound.so.2但是链接器不会找到这个库,因为它有一个版本。开发包包含 header 和符号链接(symbolic link) libasound.so -> libasound.so.2 - 这样链接器就知道要使用什么。如果您通过 SDL2 间接使用它 - 您不需要它,共享的 SDL2 已经有一个指向版本化库的链接。

然而,这样做可能毫无意义。您可以随软件分发所需的共享库,并通过 rpath 使用它们。或 LD_LIBRARY_PATH环境变量(maya、steam 等... - 这些天几乎每个人都在这样做)。此外,即使使用静态 SDL2,最终用户也可以用自己的 SDL2 覆盖(这是 SDL2 中有意实现的功能)。如果存在错误(或只是非常不同的环境)并且您的软件不再获得更新 - 有可能通过更换共享库来解决问题。如果您的原始 SDL2 仅支持 X11,您真的介意人们在 wayland 或 mir 上运行您的程序吗?

in such a way that it will run on any version of Linux it may find itself -- not just where it was originally compiled复杂得多,老实说几乎是不现实的(除非你有相当小的程序并且只使用非常有限的一组具有良好前向/后向兼容性的库 - 但即使那样它也可能很难)。大问题之一是 glibc;通常最好使用尽可能低的 glibc 版本来编译您的程序。

综上所述,有可能,但帮助不大。

关于c++ - 如何在 Linux 上静态编译 SDL2 和 GLEW 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39782630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com