70

我试图按照本指南在我的 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编译器建议的那样重新编译它,但我不知道怎么做。任何帮助表示赞赏。

4

8 回答 8

81

简而言之,该错误意味着您不能使用静态库与动态库进行链接。正确的方法是将 alibavcodec编译成 a.so而不是,因此您尝试构建.a的其他库将链接良好。.so

最简单的方法是添加--enable-sharedat./configure选项。甚至您可能会尝试完全禁用共享(或静态)库......您选择适合您的!

于 2012-12-11T01:47:36.737 回答
25

看看这个页面。

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

于 2012-12-11T01:39:06.867 回答
7

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

于 2012-12-11T01:36:31.977 回答
5

在为 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.asm)使用了一些在与 x86-64 位目标库静态链接时不兼容的 x86(32 位)汇编命令,因为它们不支持所需的重定位类型。

可能的解决方案

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

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

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

于 2019-08-29T10:09:00.150 回答
2

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

-Wl,-Bsymbolic

在 cmake 的情况下:

set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
于 2021-07-15T13:20:38.567 回答
1

我在尝试在 Centos 7 上安装 Dashcast 时遇到了同样的问题。修复是-fPIC在 x264 Makefile 中每个 CFLAGS 的末尾添加的。然后我不得不同时运行make distcleanx264 和 ffmpeg 并重建。

于 2019-05-02T13:20:48.267 回答
0

除了这里的好答案,特别是 Robert Lujo 的。

我想说就我而言,我一直在故意尝试静态编译一个 ffmpeg 版本。所有必需的依赖项以及迄今为止所需的其他内容,我已经完成了静态编译。

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

于 2020-06-20T00:26:09.777 回答
-1

在编译之前,请确保“rules.mk”文件正确包含在 Makefile 中或通过以下方式显式包含它:

“源规则.mk”

于 2015-11-26T05:13:55.977 回答