如何使用-fPIC重新编译

use*_*085 56 c++ gcc ffmpeg compilation fpic

我试图在我的ARM Ubuntu机器上按照本指南重新安装我的ffmpeg .不幸的是,当我编译一个使用这个lib的程序时,我得到以下失败:

/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
Run Code Online (Sandbox Code Playgroud)

现在我想像-fPIC编译器建议的那样重新编译它,但我不知道如何.任何帮助表示赞赏.

zau*_*ufi 62

简而言之,错误意味着您无法使用静态库与动态库进行链接.正确的方法是将libavcodec编译成.so而不是.a,因此您尝试构建的另一个.so库将很好地链接.

这样做的最简单的办法是添加--enable-shared./configure选项.甚至你可能会尝试禁用共享(或静态)库...你选择适合你的库!

  • 谢谢你!我还想补充一点,在重新运行make时,还必须执行make distclean来摆脱一些已经以静态方式编译的文件。 (3认同)

Kra*_*den 16

看看这个页面.

你可以尝试使用以下方法全局添加标志: export CXXFLAGS="$CXXFLAGS -fPIC"


Rob*_*ujo 8

我在为 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
Run Code Online (Sandbox Code Playgroud)

仅 libavcodec.a 和 libswscale.a 出现此问题。

此问题的根源在于FFMPEG 针对 x86* 平台进行了汇编程序优化,例如报告的问题原因位于libavcodec/h264_qpel_10bit.asm -> h264_qpel_10bit.o 中。

当生成 X86-64 位静态库(例如 libavcodec.a)时,看起来汇编程序文件(例如 libavcodec/h264_qpel_10bit.asm)使用了一些 x86(32 位)汇编程序命令,这些命令在与 x86-64 位目标库静态链接时不兼容,因为它们不支持所需的重定位类型。

可能的解决方案

  1. 编译所有 ffmpeg 文件,不进行汇编器优化(对于 ffmpeg,这是配置选项:--disable-asm)
  2. 生成动态库(例如 libavcodec.so)并将它们动态链接到最终库中

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

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


小智 6

在配置步骤之后,您可能有一个makefile.在这个makefile里面寻找CFLAGS(或类似的).puf -fPIC结束并再次运行make.换句话说-fPIC是一个编译器选项,必须在某处传递给编译器.


Bar*_*ski 5

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

-Wl,-Bsymbolic
Run Code Online (Sandbox Code Playgroud)

如果是 cmake:

set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
Run Code Online (Sandbox Code Playgroud)