How to recompile with -fPIC

116,649

Solution 1

Briefly, the error means that you can't use a static library to be linked w/ a dynamic one. The correct way is to have a libavcodec compiled into a .so instead of .a, so the other .so library you are trying to build will link well.

The shortest way to do so is to add --enable-shared at ./configure options. Or even you may try to disable shared (or static) libraries at all... you choose what is suitable for you!

Solution 2

Have a look at this page.

you can try globally adding the flag using: export CXXFLAGS="$CXXFLAGS -fPIC"

Solution 3

After the configure step you probably have a makefile. Inside this makefile look for CFLAGS (or similar). puf -fPIC at the end and run make again. In other words -fPIC is a compiler option that has to be passed to the compiler somewhere.

Solution 4

I had this problem when building FFMPEG static libraries (e.g. libavcodec.a) for Android x86_64 target platform (using Android NDK clang). When statically linking with my library the problem occured although all FFMPEG C -> object files (*.o) were compiled with -fPIC compile option:

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

The problem occured only for libavcodec.a and libswscale.a.

Source of this problem is that FFMPEG has assembler optimizations for x86* platforms e.g. the reported problem cause is in libavcodec/h264_qpel_10bit.asm -> h264_qpel_10bit.o.

When producing X86-64 bit static library (e.g. libavcodec.a) it looks like assembler files (e.g. libavcodec/h264_qpel_10bit.asm) uses some x86 (32bit) assembler commands which are incompatible when statically linking with x86-64 bit target library since they don't support required relocation type.

Possible solutions:

  1. compile all ffmpeg files with no assembler optimizations (for ffmpeg this is configure option: --disable-asm)
  2. produce dynamic libraries (e.g. libavcodec.so) and link them in your final library dynamically

I chose 1) and it solved the problem.

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

Solution 5

If you're building a shared library but need to link with static libavcodec add linker flags:

-Wl,-Bsymbolic

In case of cmake:

set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
Share:
116,649
user1455085
Author by

user1455085

Updated on July 13, 2022

Comments

  • user1455085
    user1455085 almost 2 years

    I was trying to reinstall my ffmpeg, following this guide, on my ARM Ubuntu machine. Unfortunately, when I compile a program which uses this lib I get the following failure:

    /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
    

    Now I would like to recompile it with -fPIC like the compiler is suggesting but I have no idea how. Any help is appreciated.

  • Admin
    Admin over 9 years
    This fixed a node package installer (for node-swipl) that was using node-gyp and had been producing the same error. Thanks :)
  • rubo77
    rubo77 over 8 years
    I added a replacement for the dead link into archive.org
  • BenMorel
    BenMorel about 8 years
    You just saved me from a severe headache with --enable-shared. Thank you!
  • Harald Nordgren
    Harald Nordgren about 8 years
    Thanks for this! I also want to add that I also had to do make distclean when re-running make to get rid of some files that had already been compiled in a static manner.