Once I had compiled FFmpeg for 32bit Windows, I discovered that it’s probably ten times more difficult to find information about doing the same with free tools on 64bit editions of Windows. A perfect topic for PCLOADLETTER then!
For building FFmpeg we must use the build environment MinGW-w64 which is a separate version of MinGW. The complication is that even when compiling natively you need to use configuration options as if you’re cross compiling (for host type x86_64-w64-mingw32). It’s not strictly necessary with all packages, but some will fail to build without these parameters. As a result you have to search around trying to find all the necessary configure commands for each package, and they’re not always identical. It’s a slow and frustrating process. What’s even more confusing, is that some builds of MinGW-w64 are targetted at 32bit, some 64bit, and some both. What is more, I had to try three different ones before I found one that could compile LAME without errors (though that could be LAME’s fault).
Most people will want a toolchain with the flexibility to create both x64 and x86 binaries, so that is what I shall describe in this guide.
On the MinGW-w64 downloads site browse to the Multilib Toolchains (Targetting Win32 and Win64) section, and download the latest megasoft78 binary build prefixed with mingw-w64-bin_x86_64-mingw. Extract the contents of this archive to the root of your C: drive (which at time of writing will create a folder named mingw64_4.5.2_multilib).
There is no installer – it’s not as automated as the 32bit distribution of MinGW. I spent a long time trying to compile LAME with the official MSYS build and eventually gave up, chosing instead to use a working one made by a third party. Download MSYS_MinGW_GCC_460_x86-x64_Full.7z from xhmikosr.1f0.de. Extract that archive into C:\mingw64_4.5.2_multilib so you have a subfolder in there named MSYS.
Update – I now realise that this archive also includes the whole GCC toolchain as well, but by then I’d already written the guide :)
Download the latest DirectX SDK. Install it, but only select the following component:
This document provides useful background information to the uninitiated. Crucially it explains that when you compile with a particular host type defined, most configure scripts will look for a compiler whose filename is prefixed with that host type. So gcc.exe might be present in the toolchain distro as x86_64-w64-mingw32-gcc.exe. The toolchain I just recommended you download does not contain prefixes, but we shall need them since FFmpeg’s configure script expects them. On Windows Vista or later (which should cover most 64bit Windows systems) we can use mklink.exe to create symbolic links. We’ll also copy some missing DirectX headers into the toolchain and configure MSYS.
Start a Command Prompt as Administrator:
cd \mingw64_4.5.2_multilib\bin\ for %i in (*.exe) do mklink x86_64-w64-mingw32-%i %i copy /y "%DXSDK_DIR%\Include\*.*" C:\mingw64_4.5.2_multilib\x86_64-w64-mingw32\include\ cd \mingw64_4.5.2_multilib\msys\postinstall pi
This will launch the post-install script which will configure a filesystem mount for /mingw. When asked, enter your mingw installation path as c:/mingw64_4.5.2_multilib
Once that’s complete, launch the MSYS shell from your Administrator command prompt:
Download the source .tar.gz files of:
Copy those downloaded files to C:\mingw64_4.5.2_multilib\msys\home\administrator (since you’re running in the Administrator user context). In the MSYS shell this is your home directory (cd ~).
In the MSYS shell, run:
tar xvfz faac-1.28.tar.gz tar xvfz lame-3.98.4.tar.gz tar xvfz ffmpeg-HEAD-6fd00e9.tar.gz
For a 64bit compile of FFmpeg with libfaac and libmp3lame:
cd ~/faac-1.28 ./configure --prefix=/usr/local/x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-static --disable-shared --with-mp4v2=no make clean && make make install cd .. cd lame-3.98.4 ./configure --prefix=/usr/local/x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-static --disable-shared --disable-decoder --enable-nasm make clean && make make install cd .. cd ffmpeg-HEAD-6fd00e9 CPPFLAGS="$CPPFLAGS -I/usr/local/x86_64-w64-mingw32/include" ./configure --extra-ldflags='-L/usr/local/x86_64-w64-mingw32/lib' --prefix=/usr/local/x86_64-w64-mingw32 --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-memalign-hack --enable-libmp3lame --enable-nonfree --enable-libfaac --arch=x86_64 --enable-runtime-cpudetect --enable-w32threads --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32 make clean && make make install
The compiled ffmpeg.exe will be in C:\mingw64_4.5.2_multilib\MSYS\local\x86_64-w64-mingw32\bin.
In summary what’s happening is we’re compiling FAAC without MP4v2 support (compilation halts if that’s enabled), and we’re making sure the binaries are stored in /usr/local/x86_64-w64-mingw32. Likewise for LAME. FFmpeg needs to be told where to find these new libraries (and headers too). We’re also installing it to /usr/local/x86_64-w64-mingw32, so as to keep x64 and x86 binaries separated.
For a 32bit compile of FFmpeg with libfaac and libmp3lame:
cd ~/faac-1.28 CFLAGS="-m32" CXXFLAGS="-m32" ./configure --prefix=/usr/local/i686-pc-mingw32 --host=x86_64-w64-mingw32 --enable-static --disable-shared --with-mp4v2=no make clean && make make install cd .. cd lame-3.98.4 CFLAGS="-m32" CXXFLAGS="-m32" ./configure --prefix=/usr/local/i686-pc-mingw32 --host=x86_64-w64-mingw32 --enable-static --disable-shared --disable-decoder --enable-nasm make clean && make make install cd .. cd ffmpeg-HEAD-6fd00e9 CPPFLAGS="$CPPFLAGS -I/usr/local/i686-pc-mingw32/include" ./configure --extra-cflags=-m32 --extra-ldflags='-m32 -L/usr/local/i686-pc-mingw32/lib' --prefix=/usr/local/i686-pc-mingw32 --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-memalign-hack --enable-libmp3lame --enable-nonfree --enable-libfaac --arch=x86_32 --enable-runtime-cpudetect --enable-w32threads --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32 make clean && make make install
The compiled ffmpeg.exe will be in C:\mingw64_4.5.2_multilib\MSYS\local\i686-pc-mingw32\bin.
This is pretty much the same as before, but CFLAGS=”-m32″ and CXXFLAGS=”-m32″ force the 64bit-native C and C++ compilers to produce 32bit binaries. I found that useful option at the bottom of this FFmpeg wiki page. As usual, FFmpeg has its own way of specifying most of these settings (except CPPFLAGS). It is also instructed to use 32bit libraries via –extra-ldflags=’-m32′.
Until I gave up and used the MSYS distro from xhmikosr.1f0.de, LAME persistently failed to compile with the error undefined reference to `init_xrpow_core_sse’. I tried a newer version of NASM than 2.09.08, replacing nasm.exe with yasm.exe, using LAME 3.98.2 instead of 3.98.4, disabling NASM in the configure, using the Unix makefile, all to no avail. Apart from a problem someone had compiling a Mac universal binary (fixed by using compiler options I could not use with MinGW), the only other link I could find about this is here, and that’s also unsolved. Even taking the nasm.exe (which I notice is 32bit) from the working MSYS bundle and trying it with the SourceForge ‘official’ MSYS bundle, I cannot get LAME to compile. I had no such problem when using the normal MinGW on my 32bit PC from my previous post on this subject, despite compiling my own nasm.exe. If you have any insight into why this might be, please leave a comment!