• Uncategorized

About c++ : How-to-recompile-with–fPIC

Question Detail

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.

Question Answer

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!

Have a look at this page.

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

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.

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:

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/

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


In case of cmake:


I hit this same issue trying to install Dashcast on Centos 7. The fix was adding -fPIC at the end of each of the CFLAGS in the x264 Makefile. Then I had to run make distclean for both x264 and ffmpeg and rebuild.

In addirion to the good answers here, specifically Robert Lujo’s.

I want to say in my case I’ve been deliberately trying to statically compile a version of ffmpeg. All the required dependencies and what else heretofore required, I’ve done static compilation.

When I ran ./configure for the ffmpeg process I didnt notice --enable-shared was on the commandline. Removing it and running ./configure is only then I was able to compile correctly (All 56 mbs of an ffmpeg binary). Check that out as well if your intention is static compilation

Before compiling make sure that “rules.mk” file is included properly in Makefile or include it explicitly by:

“source rules.mk”

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.