Wednesday 11 December 2013

Compiling LibVPX 1.3.0 using MinGW

Recently Ive been building a script to compile ffmpeg (in interesting ways). As part of that I have been generating ffmpeg libraries using MinGW from within MSYS. As anyone who has tried to do this before will know that this is not exactly the quickest and simplest of tasks. Part of my ffmpeg build uses the libvpx library for VP8/VP9 encoding. Libvpx has a pretty good set of build scripts but I found that I had to change a few things in order to get it to work in my MinGW build chain.

Firstly I was getting errors during compilation related to the 'strip' command. The error I was getting was from strip complaining that passed parameters where to long. While other people have run into a similar error where strip was failing due to a "Bad file number" error. Luckily the fix is the same for both problems (and is a rather simple one). Just disable strip from running. This can be done by modifying the Makefile after running configure.

The offending line is in 'libs-x86-win32-gcc.mk' (or libs-x86_64-**** depending on whether your building 32/64 bit).

HAVE_GNU_STRIP=yes

Just change the 'yes' to a 'no' and your golden. For those who dont want to have to do this manually here is a bash script that will do it for you.

#There is a bug that causes compilation to fail due to an error in strip
if !( sed -i -e 's/HAVE_GNU_STRIP=yes/HAVE_GNU_STRIP=no/g' $VPXFOLDER/libs-$LOCALTARGET.mk ); then
    echo "    Error: libvpx make update failed"
    exit 1
fi

Where '$VPXFOLDER' is the location of your vpx source and '$LOCALTARGET' is either 'x86-win32-gcc' or 'x86_64-win64-gcc' depending on if you are compiling 32 or 64 bit respectively.

This fixes most common MinGW errors associated with libVPX but I was also getting a linker error about missing 'strtok_r'. This was due to an inconsistency in my MinGW build with the use of 'MINGW_HAS_SECURE_API'. 
The fix was just a simple edit in the file 'svc_encodeframe.c':

@@ -23,7 +23,7 @@
 #include "vpx/vp8cx.h"
 #include "vpx/vpx_encoder.h"
-#if defined(__MINGW32__) && !defined(MINGW_HAS_SECURE_API)
+#if defined(__MINGW32__)
 #define strtok_r strtok_s
 // proto from /usr/x86_64-w64-mingw32/include/sec_api/string_s.h
 _CRTIMP char *__cdecl strtok_s(char *str, const char *delim, char **context);

Lastly there was an error when generating a 64bit version using experimental mingw-w64. This was due to an incompatible pthread implementation that caused errors when building the libvpx tests. This error is easiest to avoid by just turning of the generation of the tests.

For those interested the final configure parameters looked like this:
./configure --disable-shared --enable-static --target=$LOCALTARGET --disable-unit-tests --disable-install-bins --disable-examples --disable-docs --enable-vp8 --enable-vp9

Just like before the '$LOCALTARGET' variable should be set to either 'x86-win32-gcc' or 'x86_64-win64-gcc' for 32 or 64 bit compilation respectively. The above builds static libraries, if you want to generate a dll just swap the 'enable'/'disable' bits for the shared and static parameters (i.e. --enable-shared --disable-static)

No comments:

Post a Comment