Search code examples
c++makefileffmpegautomakelibtool

How to link libavcodec, libavformat in automake?


I am using the libavcodec and libavformat libraries from ffmpeg in a C++ project. Linking -lavcodec -lavformat with the g++ compiler works fine, but I'm not sure what goes wrong when I try to use the same code compiled in an automake project.

Working fine:

g++ -o test -D__STDC_CONSTANT_MACROS -lavcodec -lavformat test.cpp

Not working Makefile.am:

binaryname_LDFLAGS= -lavcodec -lavformat

Error:

....
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/libavformat.a(nut.o):function 
ff_nut_add_sp: error: undefined reference to 'av_tree_node_size'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/libavformat.a(nut.o):function 
ff_nut_add_sp: error: undefined reference to 'av_tree_insert'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/libavformat.a(nut.o):function 
ff_nut_free_sp: error: undefined reference to 'av_tree_enumerate'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/libavformat.a(nut.o):function 
ff_nut_free_sp: error: undefined reference to 'av_tree_destroy'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/libavformat.a(rtp.o):function 
ff_rtp_get_payload_type: error: undefined reference to 'av_opt_get_int'
...

also not working:

LDFLAGS=...-lavcodec -lavformat

Error:

src/dsp/audioDecoder.cpp:99: error: undefined reference to 'av_register_all'
src/dsp/audioDecoder.cpp:101: error: undefined reference to 'avcodec_find_decoder'
src/dsp/audioDecoder.cpp:109: error: undefined reference to 'avcodec_alloc_context'
src/dsp/audioDecoder.cpp:120: error: undefined reference to 'avcodec_open2'
src/dsp/audioDecoder.cpp:125: error: undefined reference to 'av_init_packet'
src/dsp/audioDecoder.cpp:188: error: undefined reference to 'avcodec_decode_audio3'

In the second case, if I don't set any linker, the include header cannot be found so the linker seems somehow recognized.

make V=1 returns:

make  all-am
make[1]: Go to '/path/to/trunk'
/bin/bash ./libtool --tag=CXX   --mode=link g++  -O2 -lrt -D__STDC_CONSTANT_MACROS   -o binaryname progsrc/binaryname/binaryname-binaryname.o    -lm  -lpthread -ldl -lmygeneratedlibrary
libtool: link: g++ -O2 -D__STDC_CONSTANT_MACROS -o binaryname progsrc/binaryname/binaryname-binaryname.o  -lm /path/to//trunk/.libs/lmygeneratedlibrary.a -lrt -lavutil -lavcodec -lavformat -lpthread -ldl
make[1]: Leave '/path/to/trunk'

What am I doing wrong here?


Solution

  • CPPFLAGS is for the C Pre-Processor. Not C++ flags. That's CXXFLAGS. For linker stuff, you want LDFLAGS.

    Your Makefile.am doesn't seem to follow canonical Makefile.am format. You probably want it more like (taken from here):

    # what flags you want to pass to the C compiler & linker
    CFLAGS = # C compiler flags
    LDFLAGS = # Linker flags
    
    # this lists the binaries to produce, the (non-PHONY, binary) targets in
    # the previous manual Makefile
    bin_PROGRAMS = targetbinary1 targetbinary2 [...] targetbinaryN
    targetbinary1_SOURCES = targetbinary1.c myheader.h [...]
    targetbinary2_SOURCES = targetbinary2.c
    .
    .
    targetbinaryN_SOURCES = targetbinaryN.c
    

    Also, make sure that when you include FFmpeg's headers, you surround them with extern "C". For example:

    extern "C" {
    #include <libavformat/avformat.h>
    }