74

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.

jww
  • 97,681
  • 90
  • 411
  • 885
user1455085
  • 915
  • 1
  • 6
  • 10

9 Answers9

87

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!

zaufi
  • 6,811
  • 26
  • 34
  • 1
    You just saved me from a severe headache with `--enable-shared`. Thank you! – BenMorel Feb 05 '16 at 14:41
  • 7
    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. – Harald Nordgren Mar 25 '16 at 20:51
27

Have a look at this page.

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

Dmitry Fedorkov
  • 4,301
  • 1
  • 21
  • 30
Kraiden
  • 567
  • 3
  • 18
  • This fixed a node package installer (for node-swipl) that was using node-gyp and had been producing the same error. Thanks :) –  Oct 29 '14 at 01:37
  • I added a replacement for the dead link into archive.org – rubo77 Aug 08 '15 at 23:29
8

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/

Robert Lujo
  • 15,383
  • 5
  • 56
  • 73
7

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.

dmaij
  • 1,017
  • 7
  • 15
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")
1

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.

JJJ
  • 1,009
  • 6
  • 19
  • 31
0

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

LFMekz
  • 593
  • 8
  • 10
0

I'm building ffmpeg 5.1.2 on CentOS7 with gcc4.8.5.

As mentioned in ${ffmpegRoot}/doc/platform.texi:

1)configure with option

"--enable-pic"

2)add the following option to your project LDFLAGS

"-Wl,-Bsymbolic"

Xiang Xia
  • 1
  • 1
-1

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

"source rules.mk"

Dark Coder
  • 21
  • 6