如何使用 -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 重新编译依赖项?