Pergunta

Overview

I'm trying to build one of the example files from the ffmpeg src directory on Windows using mingw, but I get a ton of undefined references to a bunch of the libav* functions.

I've already looked at this question and several others, but none of them resolved my issue. Specifically, I am not building a C++ program, and I am not using g++, so the whole extern "C" thing does not apply (in fact I already tried it, and it didn't work).

Details

I've downloaded Zeranoe's 64-bit dev package, and unpacked it to C:\apps\pf\ffmpeg. Now I'm just trying to build the decoding_encoding.c file in doc/examples. My CWD is C:\apps\pf\ffmpeg\doc\examples, and my commands look like this (line-continuation and comments added):

#Compile
gcc -o decoding_encoding.obj -c -IC:\apps\pf\ffmpeg\include decoding_encoding.c

#Link
gcc -o decoding_encoding.exe decoding_encoding.obj \
    -LC:\apps\pf\ffmpeg\lib -lavformat -lavcodec -lavdevice \
    -lavfilter -lavutil -lswscale -lm

The compile works fine, but the link spits out these errors:

decoding_encoding.obj:decoding_encoding.c:(.text+0xca): undefined reference to `av_get_channel_layout_nb_channels'
decoding_encoding.obj:decoding_encoding.c:(.text+0x131): undefined reference to `avcodec_find_encoder'
decoding_encoding.obj:decoding_encoding.c:(.text+0x179): undefined reference to `avcodec_alloc_context3'
decoding_encoding.obj:decoding_encoding.c:(.text+0x1fa): undefined reference to `av_get_sample_fmt_name'
decoding_encoding.obj:decoding_encoding.c:(.text+0x26c): undefined reference to `av_get_channel_layout_nb_channels'
decoding_encoding.obj:decoding_encoding.c:(.text+0x28f): undefined reference to `avcodec_open2'
decoding_encoding.obj:decoding_encoding.c:(.text+0x313): undefined reference to `avcodec_alloc_frame'
decoding_encoding.obj:decoding_encoding.c:(.text+0x3c8): undefined reference to `av_samples_get_buffer_size'
decoding_encoding.obj:decoding_encoding.c:(.text+0x3d6): undefined reference to `av_malloc'
decoding_encoding.obj:decoding_encoding.c:(.text+0x44f): undefined reference to `avcodec_fill_audio_frame'
decoding_encoding.obj:decoding_encoding.c:(.text+0x4ce): undefined reference to `av_init_packet'
decoding_encoding.obj:decoding_encoding.c:(.text+0x5c2): undefined reference to `avcodec_encode_audio2'
decoding_encoding.obj:decoding_encoding.c:(.text+0x63a): undefined reference to `av_free_packet'
decoding_encoding.obj:decoding_encoding.c:(.text+0x680): undefined reference to `avcodec_encode_audio2'
decoding_encoding.obj:decoding_encoding.c:(.text+0x6f8): undefined reference to `av_free_packet'
decoding_encoding.obj:decoding_encoding.c:(.text+0x722): undefined reference to `av_freep'
decoding_encoding.obj:decoding_encoding.c:(.text+0x72d): undefined reference to `avcodec_free_frame'
decoding_encoding.obj:decoding_encoding.c:(.text+0x738): undefined reference to `avcodec_close'
decoding_encoding.obj:decoding_encoding.c:(.text+0x743): undefined reference to `av_free'
decoding_encoding.obj:decoding_encoding.c:(.text+0x77b): undefined reference to `av_init_packet'
decoding_encoding.obj:decoding_encoding.c:(.text+0x7a1): undefined reference to `avcodec_find_decoder'
decoding_encoding.obj:decoding_encoding.c:(.text+0x7e9): undefined reference to `avcodec_alloc_context3'
decoding_encoding.obj:decoding_encoding.c:(.text+0x840): undefined reference to `avcodec_open2'
decoding_encoding.obj:decoding_encoding.c:(.text+0x8e6): undefined reference to `av_free'
decoding_encoding.obj:decoding_encoding.c:(.text+0x947): undefined reference to `avcodec_alloc_frame'
decoding_encoding.obj:decoding_encoding.c:(.text+0x999): undefined reference to `avcodec_get_frame_defaults'
decoding_encoding.obj:decoding_encoding.c:(.text+0x9c2): undefined reference to `avcodec_decode_audio4'
decoding_encoding.obj:decoding_encoding.c:(.text+0xa44): undefined reference to `av_samples_get_buffer_size'
decoding_encoding.obj:decoding_encoding.c:(.text+0xb7d): undefined reference to `avcodec_close'
decoding_encoding.obj:decoding_encoding.c:(.text+0xb88): undefined reference to `av_free'
decoding_encoding.obj:decoding_encoding.c:(.text+0xb96): undefined reference to `avcodec_free_frame'
decoding_encoding.obj:decoding_encoding.c:(.text+0xbe4): undefined reference to `avcodec_find_encoder'
decoding_encoding.obj:decoding_encoding.c:(.text+0xc2c): undefined reference to `avcodec_alloc_context3'
decoding_encoding.obj:decoding_encoding.c:(.text+0xcee): undefined reference to `av_opt_set'
decoding_encoding.obj:decoding_encoding.c:(.text+0xd08): undefined reference to `avcodec_open2'
decoding_encoding.obj:decoding_encoding.c:(.text+0xd8c): undefined reference to `avcodec_alloc_frame'
decoding_encoding.obj:decoding_encoding.c:(.text+0xe2f): undefined reference to `av_image_alloc'
decoding_encoding.obj:decoding_encoding.c:(.text+0xe83): undefined reference to `av_init_packet'
decoding_encoding.obj:decoding_encoding.c:(.text+0xfd3): undefined reference to `avcodec_encode_video2'
decoding_encoding.obj:decoding_encoding.c:(.text+0x105f): undefined reference to `av_free_packet'
decoding_encoding.obj:decoding_encoding.c:(.text+0x10a9): undefined reference to `avcodec_encode_video2'
decoding_encoding.obj:decoding_encoding.c:(.text+0x1135): undefined reference to `av_free_packet'
decoding_encoding.obj:decoding_encoding.c:(.text+0x117e): undefined reference to `avcodec_close'
decoding_encoding.obj:decoding_encoding.c:(.text+0x1189): undefined reference to `av_free'
decoding_encoding.obj:decoding_encoding.c:(.text+0x1194): undefined reference to `av_freep'
decoding_encoding.obj:decoding_encoding.c:(.text+0x119f): undefined reference to `avcodec_free_frame'
decoding_encoding.obj:decoding_encoding.c:(.text+0x1272): undefined reference to `avcodec_decode_video2'
decoding_encoding.obj:decoding_encoding.c:(.text+0x13b1): undefined reference to `av_init_packet'
decoding_encoding.obj:decoding_encoding.c:(.text+0x13fa): undefined reference to `avcodec_find_decoder'
decoding_encoding.obj:decoding_encoding.c:(.text+0x1442): undefined reference to `avcodec_alloc_context3'
decoding_encoding.obj:decoding_encoding.c:(.text+0x14ba): undefined reference to `avcodec_open2'
decoding_encoding.obj:decoding_encoding.c:(.text+0x153e): undefined reference to `avcodec_alloc_frame'
decoding_encoding.obj:decoding_encoding.c:(.text+0x1674): undefined reference to `avcodec_close'
decoding_encoding.obj:decoding_encoding.c:(.text+0x167f): undefined reference to `av_free'
decoding_encoding.obj:decoding_encoding.c:(.text+0x168a): undefined reference to `avcodec_free_frame'
decoding_encoding.obj:decoding_encoding.c:(.text+0x16ab): undefined reference to `avcodec_register_all'
collect2.exe: error: ld returned 1 exit status
Foi útil?

Solução

I can already see in the README that this library was built with MinGW-w64 and is targeting 64-bit. Plain old MinGW does not support 64-bit targets. Therefore, if you are using MinGW, then of course it cannot link against 64-bit libraries, hence you experience these errors.

To solve your problem, simply install MinGW-w64. I highly recommend to download its distribution from here. There is no installation nightmare: just unpack, add bin to the PATH environment variable and you are good to go.

Finally, take a look at this post, it might be useful for you to understand who is who.

Outras dicas

Just to close the loop on this, I wasn't happy with mingw-w64 for my purposes, specifically because it lacks a useful implementation of libscrnsave. So instead I built libav from source using standard mingw.

Building libav was fairly simple, once I figured it all out. It goes like this:

  1. Download and install the mingw installer from http://www.mingw.org/.
  2. Use the mingw installer to install MSYS.
  3. Download yasm from http://yasm.tortall.net/Download.html
  4. Renamed the downloaded yasm executable to just yasm.exe, and place it in the MSYS directory, under bin.
  5. Download the libav sources from https://libav.org/download.html
  6. Unpack the libav sources.
  7. Open MSYS and cd to wherever the libav sources are.
  8. In MSYS, run ./configure --disable-pthreads --disable-w32threads --prefix=/c/apps/pf/libav (those are the options that worked for me, the --prefix option specifies where to install the libraries when you run make install, mine places them under C:\apps\pf\libav).
  9. Once that completes, run make, then make install.

Once the libraries were built, I was able to link against them building from the normal windows command line using standard mingw.

To use with pkg-config, you need to add the lib/pkgconfig directory under the installed location to the PKG_CONFIG_PATH env variable. To properly build, you should use pkg-config <LIBS> --cflags --libs to get the correct flags to pass to gcc, where <LIBS> is the list of libav libraries you need to build against. It doesn't do any harm to just include all of the libav libraries, but order matters. The following order seems to work for me: libavdevice libavformat libavcodec libavfilter libswscale libavresample libavutil.

Ultimately, the command line I used that worked looked like this (line continuation and comments added):

#Compile
gcc -o decoding_encoding.obj -c -IC:\apps\pf\libav\include decoding_encoding.c

#Link
gcc -o decoding_encoding.exe decoding_encoding.obj -LC:\apps\pf\libav\lib \
    -lavdevice -lavfilter -lavformat -lavcodec -lswscale -lavresample \
    -lavicap32 -lws2_32 -lpsapi -ladvapi32 -lshell32 -lavutil -lm
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top