如何用 -fPIC 重新编译

我试图在我的 ARM Ubuntu 机器上重新安装我的 ffmpeg,跟随这个 向导。不幸的是,当我编译一个使用这个库的程序时,我会遇到以下的失败:

/usr/bin/ld: /usr/local/lib/libavcodec.a(amrnbdec.o): relocation R_ARM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libavcodec.a: could not read symbols: Bad value
collect2: ld returned 1 exit status

现在我想像编译器建议的那样用 -fPIC重新编译它,但是我不知道怎么做。感谢你的帮助。

123909 次浏览

在配置步骤之后,您可能有一个 makefile。在这个 makefile 中寻找 CFLAGS (或类似的)。然后运行 make。换句话说—— fPIC 是一个必须传递给编译器的编译器选项。

看看 这一页。

您可以尝试使用 export CXXFLAGS="$CXXFLAGS -fPIC"在全局范围内添加标志

简而言之,该错误意味着您 不能使用静态库链接动态库。 正确的方法是将 libavcodec编译成 .so而不是 .a,这样您正在尝试构建的其他 .so库就可以很好地链接。

最简单的方法是在 ./configure选项处添加 --enable-shared。或者甚至可以尝试禁用共享(或静态)库... ... 您可以选择适合您的!

在编译前,确保“ rules. mk”文件在 Makefile 正确地包含在内,或者通过以下方式明确地包含在内:

“源规则”

我试图在 Centos 7上安装 Dashcast 时遇到了同样的问题。补丁是在 x264 Makefile 中的每个 CFLAGS 的末尾添加 -fPIC。然后,我必须为 x264和 ffmpeg 运行 make distclean并重新构建。

我在为 Android x86 _ 64目标平台(使用 Android NDK clang)构建 FFMPEG 静态库(例如 libavcodec.a)时遇到了这个问题。当静态链接到我的库时,虽然所有的 FFMPEG C-> 对象文件(* 。O)使用 -fPIC 编译选项编译:

x86_64/libavcodec.a(h264_qpel_10bit.o):
requires dynamic R_X86_64_PC32 reloc against 'ff_pw_1023'
which may overflow at runtime; recompile with -fPIC

问题只出现在 libavcodec.a 和 libswscale.a 上。

这个问题的根源在于 FFMPEG 为 x86 * 平台提供了汇编程序优化,例如报告的问题原因在 Libavcodec/h264 _ qpel _ 10bit. asm-> h264 _ qpel _ 10bit.o。

当生成 X86-64位静态库(例如 libavcodec.a)时,它看起来像汇编程序文件(例如 libavcodec/h264 _ qpel _ 10bit)。因为它们不支持所需的重定位类型。

可能的解决方案 :

  1. 编译所有的 ffmpeg 文件,没有汇编程序优化(对于 ffmpeg,这是配置选项: —— disable-asm)
  2. 生成动态库(例如 libavcodec.so)并在最终库中动态链接它们

我选择了1) ,它解决了问题。

参考资料: https://tecnocode.co.uk/2014/10/01/dynamic-relocs-runtime-overflows-and-fpic/

除了这里的正确答案,特别是罗伯特 · 卢霍的。

在我的例子中,我一直有意尝试静态编译一个 ffmpeg 版本。所有需要的依赖项和以前需要的其他东西,我都做了静态编译。

当我为 ffmpeg 进程运行 ./configure时,我没有注意到 --enable-shared在命令行上。只有删除它并运行 ./configure,我才能正确编译(ffmpeg 二进制文件的所有56mbs)。如果您的意图是静态编译,那么也要检查这一点

如果您正在构建一个共享库,但需要与 静态 libavcodec链接,请添加链接器标志:

-Wl,-Bsymbolic

以 cmake 为例:

set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")