Search code examples
c++linuxffmpegdebian

Unable to link against FFmpeg libaries


I tried to build this, but always got link-time error.

#include <libavutil/log.h>    
int main(int argc, char *argv[])
{
    ::av_log_set_flags(AV_LOG_SKIP_REPEATED);
    return 0;
}

My distro is Debian GNU/Linux 8 (jessie). The FFmpeg was built by myself, and the configure command was...

$ ./configure --prefix=/usr/local --disable-static --enable-shared \
> --extra-ldflags='-Wl,-rpath=/usr/local/lib'

The link-error is as follows.

$ g++ foo.cpp -D__STDC_CONSTANT_MACROS -Wall \
> -Wl,-rpath=/usr/local/lib \
> $(pkg-config --cflags --libs libavutil)
/tmp/ccKzgEFb.o: In function `main':
foo.cpp:(.text+0x17): undefined reference to `av_log_set_flags(int)'
collect2: error: ld returned 1 exit status

where the output of pkg-config is...

$ pkg-config --cflags --libs libavutil
-I/usr/local/include -L/usr/local/lib -lavutil

The objdump shows that the shared object libavutil.so does have av_log_set_flogs inside.

$ objdump --dynamic-syms /usr/local/lib/libavutil.so | grep 'av_log_set_flags'
000260f0 g    DF .text  0000000a  LIBAVUTIL_54 av_log_set_flags

Please note that the g++ command used to build the above application had a linker option -Wl,-rpath=/usr/local/lib, though it still doesn't work. Also, I've tried to monitor with inotifywait if the other version provided by the distro were called. They were not, and the one being opened during execution of g++ was /usr/local/lib/libavutil.so.

Summary:

  1. /usr/local/lib/libavutil.so does have the symbol.

  2. -rpath was used to force to link against the shared library.

  3. Why link-time error? T_T

Any suggestion or information would be highly appreciated! Thanks!

REEDIT: ffplay works fine and ldd shows it use /usr/local/lib/libavutil.so. So, the libraries seems not broken, and the problem becomes how to build my own codes to use the libraries.


Solution

  • This had me baffled too for a while. I managed to google this: http://soledadpenades.com/posts/2009/linking-with-ffmpegs-libav/

    It turns out FFMPEG don't make their header files C++ aware.

    Here is the fix:

    extern "C"
    {
    #include <libavutil/log.h>
    }
    
    int main(int argc, char *argv[])
    {
        ::av_log_set_flags(AV_LOG_SKIP_REPEATED);
        return 0;
    }
    

    You need to wrap all ffmpeg header includes with extern "C" linkage.