Emscripten:将库链接到项目
Emscripten: Linking library to project
我正在尝试使用 Emscripten 构建一个使用 ffmpeg 库到 WebAssembly 的小项目。在那之前,我通过将一些简单的程序从 C 编译成 Wasm 来尝试它,它运行良好,但那次我没有使用任何额外的库。
对于 C++,我正在使用 Visual Studio 和 FFmpeg 我在项目的“属性”中链接如下:
我将所有 .h 头文件放在“include”目录中,并将其添加为“C/C++”部分中的“附加包含目录”
所有 .lib 和 .dll.a(例如 avcodec.lib 或 libavcodec.dll.a)我放在“lib”中并添加为“附加库”的文件“链接器”部分中的“目录”
所有包含并且程序本身运行良好,所以现在我正在尝试使用我之前使用的相同命令使用 Emscripten 准备一个 Wasm 模块,但我已经知道这是行不通的:
em++ cut_video.cpp -Os -g1 -L lib -I include -s WASM=1 -s FORCE_FILESYSTEM=1 -s ALLOW_MEMORY_GROWTH=1 -s EXPORT_ES6=1 -s MODULARIZE=1 -s "EXPORT_NAME='Editor'" -s "ENVIRONMENT='web'" -s EXPORTED_FUNCTIONS="['_doubler', '_cut_video', '_cut_video1']" -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s ASSERTIONS=1 --bind -o cutter.js
我添加了“-I include”参数,它应该指向我上面提到的相同的头文件,它似乎对 Emscripten 没问题,因为它解决了初始错误。
Emscripten 已经从 ffmpeg 库中发现了函数的问题,所以我添加了“ERROR_ON_UNDEFINED_SYMBOLS=0”只是为了看看当我将这个模块添加到前端应用程序时会发生什么。显然它以错误“缺少函数:av_register_all”结束,这是我代码中的第一个 ffmpeg 函数。
我发现所有可能有用的解释对我来说真的不清楚,因为通常我不使用 C++ 或 Linux 环境,所以我不熟悉 Makefile 等。
有没有办法,根据我所描述的以及我的项目是如何用 Visual Studio 准备的,告诉 Emscripten 使用 FFmpeg 的预构建 .dll.a 或 .lib 文件对于我的应用程序?或者我应该如何修改我的项目以使其被 Emscripten 接受?
编辑:由于 cut_video.cpp 文件很大,也许最好在这里粘贴 link to this file on github 而不是大块代码.
FFmpeg 和 Emscripten
使用 Emscripten 构建 FFmpeg 库并非易事,但您可以按照 ffmpeg.wasm 教程进行操作:
仔细阅读所有教程,直到最后,因为可能会出现很多问题。
备注
我建议你从教程中使用的FFmpeg和Emscripten版本开始,看看build-ffmpeg.sh脚本。脚本本身导出一个带有主要功能的 wasm 文件
-s EXPORTED_FUNCTIONS="[_main, _proxy_main]" # export main and proxy_main funcs
即fftools/ffmpeg.c中的main函数。这将对你有很大帮助。
有用的资源
请注意,在 Emscripten 文档中有一个 C/C++ libraries/project 移植到 WASM/Javascript 的列表,有一些 FFmpeg 项目见 utilities
编码愉快!
选项 returns 链接错误:
emcc:错误:未定义的导出符号:“_proxy_main”[-Wundefined] [-Werror]
USE_PTHREAD 选项是否生成 proxy_main(...) 函数来抽象 main(...) ?
-s USE_PTHREADS=1 # 启用 pthreads 支持
-s PROXY_TO_PTHREAD=1 # 从 browser/UI 主线程分离 main()
-s INVOKE_RUN=0 # 不要在开头 运行 main()
-s EXIT_RUNTIME=1 # 执行后退出运行time
-s EXPORTED_FUNCTIONS="[_main, _proxy_main]" # 导出 main 和 proxy_main funcs
我正在尝试使用 Emscripten 构建一个使用 ffmpeg 库到 WebAssembly 的小项目。在那之前,我通过将一些简单的程序从 C 编译成 Wasm 来尝试它,它运行良好,但那次我没有使用任何额外的库。
对于 C++,我正在使用 Visual Studio 和 FFmpeg 我在项目的“属性”中链接如下:
我将所有 .h 头文件放在“include”目录中,并将其添加为“C/C++”部分中的“附加包含目录”
所有 .lib 和 .dll.a(例如 avcodec.lib 或 libavcodec.dll.a)我放在“lib”中并添加为“附加库”的文件“链接器”部分中的“目录”
所有包含并且程序本身运行良好,所以现在我正在尝试使用我之前使用的相同命令使用 Emscripten 准备一个 Wasm 模块,但我已经知道这是行不通的:
em++ cut_video.cpp -Os -g1 -L lib -I include -s WASM=1 -s FORCE_FILESYSTEM=1 -s ALLOW_MEMORY_GROWTH=1 -s EXPORT_ES6=1 -s MODULARIZE=1 -s "EXPORT_NAME='Editor'" -s "ENVIRONMENT='web'" -s EXPORTED_FUNCTIONS="['_doubler', '_cut_video', '_cut_video1']" -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s ASSERTIONS=1 --bind -o cutter.js
我添加了“-I include”参数,它应该指向我上面提到的相同的头文件,它似乎对 Emscripten 没问题,因为它解决了初始错误。 Emscripten 已经从 ffmpeg 库中发现了函数的问题,所以我添加了“ERROR_ON_UNDEFINED_SYMBOLS=0”只是为了看看当我将这个模块添加到前端应用程序时会发生什么。显然它以错误“缺少函数:av_register_all”结束,这是我代码中的第一个 ffmpeg 函数。
我发现所有可能有用的解释对我来说真的不清楚,因为通常我不使用 C++ 或 Linux 环境,所以我不熟悉 Makefile 等。
有没有办法,根据我所描述的以及我的项目是如何用 Visual Studio 准备的,告诉 Emscripten 使用 FFmpeg 的预构建 .dll.a 或 .lib 文件对于我的应用程序?或者我应该如何修改我的项目以使其被 Emscripten 接受?
编辑:由于 cut_video.cpp 文件很大,也许最好在这里粘贴 link to this file on github 而不是大块代码.
FFmpeg 和 Emscripten
使用 Emscripten 构建 FFmpeg 库并非易事,但您可以按照 ffmpeg.wasm 教程进行操作:
仔细阅读所有教程,直到最后,因为可能会出现很多问题。
备注
我建议你从教程中使用的FFmpeg和Emscripten版本开始,看看build-ffmpeg.sh脚本。脚本本身导出一个带有主要功能的 wasm 文件
-s EXPORTED_FUNCTIONS="[_main, _proxy_main]" # export main and proxy_main funcs
即fftools/ffmpeg.c中的main函数。这将对你有很大帮助。
有用的资源
请注意,在 Emscripten 文档中有一个 C/C++ libraries/project 移植到 WASM/Javascript 的列表,有一些 FFmpeg 项目见 utilities
编码愉快!
选项 returns 链接错误: emcc:错误:未定义的导出符号:“_proxy_main”[-Wundefined] [-Werror] USE_PTHREAD 选项是否生成 proxy_main(...) 函数来抽象 main(...) ?
-s USE_PTHREADS=1 # 启用 pthreads 支持 -s PROXY_TO_PTHREAD=1 # 从 browser/UI 主线程分离 main() -s INVOKE_RUN=0 # 不要在开头 运行 main() -s EXIT_RUNTIME=1 # 执行后退出运行time -s EXPORTED_FUNCTIONS="[_main, _proxy_main]" # 导出 main 和 proxy_main funcs