如何使用 -fPIC 重新编译

Posted

技术标签:

【中文标题】如何使用 -fPIC 重新编译【英文标题】:How to recompile with -fPIC 【发布时间】:2012-11-28 12:42:31 【问题描述】:

我试图在我的 ARM Ubuntu 机器上按照guide 重新安装我的 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 重新编译它,就像编译器建议的那样,但我不知道怎么做。任何帮助表示赞赏。

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

看看this page.

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

【讨论】:

这修复了使用 node-gyp 并产生相同错误的节点包安装程序(用于 node-swipl)。谢谢:) 我在 archive.org 中添加了一个替换死链接【参考方案3】:

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

这样做的最短方法是在./configure 选项中添加--enable-shared。甚至您也可以尝试禁用共享(或静态)库……您可以选择适合自己的!

【讨论】:

你刚刚用--enable-shared 让我免于严重头痛。谢谢! 谢谢!我还想补充一点,在重新运行 make 时我还必须做make distclean 以摆脱一些已经以静态方式编译的文件。【参考方案4】:

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

“源规则.mk”

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

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

可能的解决方案

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

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

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

【讨论】:

【参考方案7】:

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

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

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

【讨论】:

【参考方案8】:

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

-Wl,-Bsymbolic

在 cmake 的情况下:

set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")

【讨论】:

以上是关于如何使用 -fPIC 重新编译的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有 gprof 的 makefile 重新编译依赖项?

如何避免每次重新编译所有文件?

使用 javadecompilers.com 后重新编译 apk

如何重新编译 Ionic 1.x 应用程序?

如何正确重新编译apk文件?

如何使用 -Xlint:unchecked 重新编译?