Emscripten SDL 编译失败

Posted

技术标签:

【中文标题】Emscripten SDL 编译失败【英文标题】:Emscripten SDL Compilation faliure 【发布时间】:2018-05-04 07:05:20 【问题描述】:

我是 emscripten 的新手;几天前我下载了它,只是为了尝试将游戏移植到 JS。

无论如何,经过一些步骤,我现在遇到了这个问题(在 Ubuntu 16.04 STL 上)。 按照构建步骤here,首先,我设置了环境变量 source ./emsdk_env.sh 然后我尝试在项目目录中使用emconfigure ./configure 配置项目。在检查 emscripten 需要的工具时,我遇到了这个错误:

checking for SDL... no
configure: error: Package requirements (sdl2 >= 2.0.1) were not met:

No package 'sdl2' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables SDL_CFLAGS
and SDL_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
ERROR:root:Configure step failed with non-zero return code 1! Command line: ['./configure'] at ...

所以我尝试使用以下命令设置该变量: export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig/ 这实际上是sdl2.pc 在我的机器上的位置,但它没有帮助。

那么我设置了emconfigure 需要的以下变量:

export SDL_PATH=/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/system/include/SDL/SDL.h
export SDL_LIBS=/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/system/include/SDL/SDL.h
export SDL_CFLAGS=/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/system/include/SDL/SDL.h
export SDLNET_LIBS=/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/system/include/SDL/SDL.h
export SDLNET_CFLAGS=/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/system/include/SDL/SDL.h
export SDLMIXER_LIBS=/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/system/include/SDL/SDL.h
export SDLMIXER_CFLAGS=/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/system/include/SDL/SDL.h

并重新启动emconfigure ./configure,它已完成良好。 所以下一步是emmake make,这给了我以下错误:

make  all-recursive
make[1]: Entering directory '/home/ustym/Documents/Projects/chocolate-doom-3.0.0'
Making all in textscreen
make[2]: Entering directory '/home/ustym/Documents/Projects/chocolate-doom-3.0.0/textscreen'
Making all in fonts
make[3]: Entering directory '/home/ustym/Documents/Projects/chocolate-doom-3.0.0/textscreen/fonts'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/home/ustym/Documents/Projects/chocolate-doom-3.0.0/textscreen/fonts'
Making all in .
make[3]: Entering directory '/home/ustym/Documents/Projects/chocolate-doom-3.0.0/textscreen'
  CC       txt_conditional.o
Traceback (most recent call last):
  File "/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/emcc", line 11, in <module>
    python_selector.run(__file__)
  File "/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/tools/python_selector.py", line 38, in run
    sys.exit(run_by_import(filename, main) if on_allowed_version() else run_by_subprocess(filename))
  File "/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/tools/python_selector.py", line 13, in run_by_import
    return getattr(importlib.import_module(os.path.basename(filename)), main)()
  File "/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/emcc.py", line 1345, in run
    assert header.endswith(HEADER_ENDINGS), 'if you have one header input, we assume you want to precompile headers, and cannot have source files or other inputs as well: ' + str(headers) + ' : ' + header
AssertionError: if you have one header input, we assume you want to precompile headers, and cannot have source files or other inputs as well: ['/home/ustym/Documents/Projects/emsdk/emscripten/1.37.38/system/include/SDL/SDL.h', 'txt_conditional.c'] : txt_conditional.c
Makefile:447: recipe for target 'txt_conditional.o' failed
make[3]: *** [txt_conditional.o] Error 1
make[3]: Leaving directory '/home/ustym/Documents/Projects/chocolate-doom-3.0.0/textscreen'
Makefile:467: recipe for target 'all-recursive' failed
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory '/home/ustym/Documents/Projects/chocolate-doom-3.0.0/textscreen'
Makefile:585: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/ustym/Documents/Projects/chocolate-doom-3.0.0'
Makefile:438: recipe for target 'all' failed
make: *** [all] Error 2

这意味着,我认为,SDL_PATHSDL_LIBSSDL_CFLAGS... 变量设置不正确。或者我只需要在 SDL 目录中预编译该头文件。

最后一件事:如果我跳过设置 SDL 变量和配置步骤而只启动 emmake make,编译会顺利进行,但随后,emcc 命令给了我 WARNING:root: .o is not valid LLVM bitcode 对于所有生成的.o 文件。这实际上是有道理的。

所以我被困在这里了。有人可以告诉我如何为 emscripten 正确设置 PKG_CONFIG_PATH,或者我是否真的需要在 SDL 目录中预编译这些头文件?谢谢!

【问题讨论】:

【参考方案1】:

首先,将PKG_CONFIG_PATH 设置为托管库的目录(-I-L)对我来说是个糟糕的主意:Emscripten 目标文件包含 LLVM 位码(而不是主机代码),其.so AFAIK 文件也包含位码。是被翻译成 JS 的位码,而不是主机代码。因此,您需要自己使用 Emscripten 构建程序的依赖项(并且很可能不应该将它们安装到主机系统)。幸运的是,有一些官方的Emscripten 端口(请参阅here)了解详情。

Emscripten 有自己的 SDL v1 实现(您可能尝试手动使用),但您的程序似乎需要 SDL2。好消息:您可能只需要在configureing 时将-s USE_SDL=2 传递给CFLAGSLDFLAGS(有关SDL2 端口的信息,请参见上面的链接)。坏消息:某些东西可能没有完全移植。但我在某种程度上成功地使用了它。

当您在主机上有configured 并使用emmake 进行制作时,您可能有编译器路径以及由emconfigureemmake 调整的其他参数已经被./configure 烘焙到生成的Makefile 中,不受emconfigure 控制,所以主机gcc/clang刚刚生成机器码。

【讨论】:

以上是关于Emscripten SDL 编译失败的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Emscripten + SDL 中禁用窗口事件捕获?

如何在 cmake 中使用 emscripten 端口(SDL2 和 Freetype)

将 SDL2 RenderDraw 函数与 Emscripten 一起使用

带有 SDL 音频的 Emscripten 工作模型

emscripten + sdl = 抛出异常:TypeError:无法设置未定义的属性“widthNative”

在 Edge 和 Safari (emscripten) 中使用 SDL_mixer 播放 .ogg 文件