Reputation: 9967
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
Upvotes: 1
Views: 2485
Reputation: 17021
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.
Upvotes: 3
Reputation: 9967
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:
yasm.exe
, and place it in the MSYS directory, under bin
.cd
to wherever the libav sources are../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
).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
Upvotes: 1