为第三方使用编译FFmpeg库:Elixir绑定依赖打包问题
问题描述
我正在尝试为Elixir编程语言创建FFmpeg绑定,希望让我的库用户无需安装任何原生依赖即可使用。整体流程为:
- 编写Elixir函数定义;
- 使用FFmpeg库用C实现功能;
- 将C代码编译为共享库;
- 应用运行时由Erlang虚拟机加载该动态库。
我尝试了两种方案但均遇问题:
- 编译FFmpeg为共享库:在Elixir库编译时下载预编译FFmpeg归档并链接,但发现FFmpeg共享库依赖其他需用户自行安装的共享库,无法满足需求。
- 编译FFmpeg为静态库:通过
--whole-archive链接器选项将其包含到我的共享库中,却出现链接错误:
/usr/bin/ld: ffmpeg_build/lib/libavcodec.a(vp9lpf_16bpp.o): warning: relocation against
ff_pw_1' in read-only section.text'
/usr/bin/ld: ffmpeg_build/lib/libavcodec.a(cavsdsp.o): relocation R_X86_64_PC32 against symbol `ff_pw_5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
使用的编译命令:
cc -fPIC -I/home/michal/.asdf/installs/erlang/25.1/erts-13.1/include -Iffmpeg_build/include -Ic_src/xav -shared -DXAV_DEBUG=1 c_src/xav/xav_nif.c c_src/xav/reader.c c_src/xav/utils.c -o /home/michal/Repos/xav/_build/test/lib/xav/priv/libxav.so -Lffmpeg_build/lib -Wl,--whole-archive -lavcodec -lswscale -lavutil -lavformat -Wl,--no-whole-archive
FFmpeg配置:
./configure \ --prefix="$PWD/ffmpeg_build" \ --extra-cflags="-fPIC -I$PWD/ffmpeg_build/include" \ --extra-ldflags="-L$PWD/ffmpeg_build/lib" \ --enable-pic --disable-programs
我希望实现无需用户安装依赖的自包含FFmpeg构建,请问我的尝试是否可行?该如何解决链接错误?
解决方案
可行性说明
你的方案完全可行,将FFmpeg静态库打包进自定义共享库的方式,能实现用户无需额外安装原生依赖的目标,这也是多数跨语言FFmpeg绑定库的常用实现思路。
链接错误解决步骤
修正FFmpeg配置语法
原配置命令中--enable-pic后缺少反斜杠,导致--disable-programs未被正确识别,且未明确指定只生成静态库。修正后的配置命令:./configure \ --prefix="$PWD/ffmpeg_build" \ --extra-cflags="-fPIC -I$PWD/ffmpeg_build/include" \ --extra-ldflags="-L$PWD/ffmpeg_build/lib" \ --enable-pic \ --disable-programs \ --disable-shared \ --enable-static新增
--disable-shared --enable-static确保只生成静态库,避免混入动态依赖。清理并重新编译FFmpeg
删除旧编译产物后重新执行配置与编译:make clean && make distclean # 执行上述修正后的configure命令 make -j$(nproc) make install调整共享库编译命令
链接时添加-Wl,-Bstatic强制优先使用静态库,同时保留--whole-archive确保静态库符号被完整打包:cc -fPIC -I/home/michal/.asdf/installs/erlang/25.1/erts-13.1/include -Iffmpeg_build/include -Ic_src/xav -shared -DXAV_DEBUG=1 c_src/xav/xav_nif.c c_src/xav/reader.c c_src/xav/utils.c -o /home/michal/Repos/xav/_build/test/lib/xav/priv/libxav.so -Lffmpeg_build/lib -Wl,-Bstatic -Wl,--whole-archive -lavcodec -lswscale -lavutil -lavformat -Wl,--no-whole-archive -Wl,-Bdynamic-Wl,-Bdynamic用于恢复后续链接的默认动态库行为(若有其他需动态链接的系统库)。验证最终共享库依赖
编译完成后用ldd检查产物,确认无FFmpeg相关动态依赖:ldd /home/michal/Repos/xav/_build/test/lib/xav/priv/libxav.so仅显示系统基础库(如
libc.so)即为成功。
内容的提问来源于stack exchange,提问作者mikeProgrammer

