FFmpeg can be built on Windows with Visual Studio. The official guide is quite clear, but a little bit out-of-date.
FFmpeg can be built with MSVC 2012 or earlier using a C99-to-C89 conversion utility and wrapper, or with MSVC 2013 or later natively.
You will need the following prerequisites:
- C99-to-C89 Converter & Wrapper if using MSVC 2012 or earlier.
- msinttypes if using MSVC 2012 or earlier.
- MSYS
- YASM
First, you need to unzip and copy the prerequisites into a folder, for example, c:\c99
.
Then, you need to add the folder c:\c99
into your PATH
environment variable.
Rename the yasm executable you will use to yasm.exe
.
Finally, create an INCLUDE
environment variable, and point it to c:\c99
; this is the location where the compiler will find inttypes.h
.
Note: If it complains of MSVCR100.dll not found
when running yasm, install the Microsoft 2010 VC redistributable.
Setting the environment
In order to build a program with the VisualStudio tools, you need to setup a proper environment in order to make sure that the configure and build system will be able to find the tools.
In particular, the build system will use the cl
compiler and the link
linker bundled with the employed version of VisualStudio. In order to setup the enviroment it is so necessary to set the PATH
, LIB
, and INCLUDE
variables to appropriate values.
This can be done by launching a cmd.exe
native shell from the VisualStudio GUI. This can be done for example adding a tool from the Tools menu:
Tools -> External tools... -> Add
To build 64bit you need to run this command to enable the 64bit compiler and linker:
vcvarsall.bat amd64
Installed in the Visual Studio VC
directory (for example: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC
).
Depending on the system the argument might be x86_amd64
or similar.
See the following link for details: https://msdn.microsoft.com/en-us/library/x4d2c09s.aspx
Finally, to set up a proper MSYS environment, you need to run msys.bat
(or the equivalent mingw32_shell.bat
) from the command prompt.
Now, make sure that the cl
and link
program are not override by other programs with the same name from MSYS/MinGW (in particular, note that MinGW provides a program named link
). In order to do so, you can set the MSYS path so that the VisualStudio tools are used instead, for example with the command:
export PATH="/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/":$PATH
or when building for 64bit
export PATH="/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/amd64/":$PATH
or removing or renaming the link
binary provided by MSYS.
Next, make sure any other headers and libs you want to use, such as zlib, are located in a location that the compiler can see. Do so by modifying the LIB
and INCLUDE
environment variables to include the Windows-style paths to these directories. Alternatively, you can try and use the --extra-cflags
/--extra-ldflags
configure options.
Build
Finally, run: For MSVC:
./configure --toolchain=msvc make make install
For 64 bit builds specify target and architecture:
./configure --target-os=win64 --arch=x86_64 --toolchain=msvc
More info in the thread here https://trac.ffmpeg.org/ticket/5546
or the following:
./configure --enable-asm --enable-yasm --arch=i386 --disable-ffserver --disable-avdevice --disable-swscale --disable-doc --disable-ffplay --disable-ffprobe --disable-ffmpeg --enable-shared --disable-static --disable-bzlib --disable-libopenjpeg --disable-iconv --disable-zlib --prefix=/c/ffmpeg --toolchain=msvc
--enable-shared
will generate the dynamic linked lib (dlls)
Note: You might see an error saying cl can't generate executable; this is because you installed the link.exe
from MSYS. It conflicts with the link.exe
of Visual Studio. This can also indicate that you are mixing 64bit and 32bit versions of cl.exe
and link.exe
.
cl is unable to create an executable file. If cl is a cross-compiler, use the --enable-cross-compile option. Only do this if you know what cross compiling means. C compiler test failed.
You can try which link.exe
to verify if it is the case. If you see /bin/link.exe
, then you can simply rm /bin/link.exe
. For more info see #3203 Windows MSVC configure failed.
The right link.exe
should come from this location:
/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/link.exe
or in the case of 64bit builds
/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/amd64/link.exe
Problem solving
You might see three problems when building ffmpeg
:
pr
command not found:
A solution is posted at MSYS pr not found. Basically, pr.exe
is removed from MSYS. You need to download it and copy pr.exe
to the msys/bin
folder.
- The compiler might complain about redefinition issues of
stdint.h
, because both msinttypes and Visual Studio havestdint.h
. I removedstdint.h
fromc:\c99
to let the compiler uses the one provided by Visual Studio.
In the end of configuration, you might also see pkg-config
not found issue. That won't affect compilation, you can ignore it. It is said that installing pkg-config
to MSYS is kinda tiresome.
common.mak:140: *** missing separator. Stop.
This can happen if you try to build from a cloned git repository and have git configured to replace line endings in your local working copy. Be sure that you have the git option core.autocrlf
set to false
when cloning the git repo.
- zlib not found:
Some information can be found here https://ffmpeg.org/platform.html#Microsoft-Visual-C_002b_002b-or-Intel-C_002b_002b-Compiler-for-Windows. For 64 bit zlib builds run nmake with the parameters
nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." OBJA="inffasx64.obj gvmat64.obj inffas8664.obj"
To make sure that MSVC finds the zlib files, add the include and lib path from the Visual Studio Command Line prior to launching MSYS2:
set include=%include%;[your absolute path to the zlib folder] set lib=%lib%;[your absolute path to the zlib folder] msys2_shell.cmd
Debug Builds
How to build debug version?
An example:
$ ./configure --enable-asm --enable-yasm --disable-ffserver --disable-avdevice --disable-doc --disable-ffplay --disable-ffprobe --disable-ffmpeg --enable-shared --disable-static --disable-bzlib --disable-libopenjpeg --disable-iconv --disable-zlib --prefix=/c/ffmpeg --toolchain=msvc --arch=amd64 --extra-cflags="-MDd" --extra-ldflags="/NODEFAULTLIB:libcmt" --enable-debug
Compiling FFmpeg with external libraries
In order to build FFmpeg with support to external libraries, you need to make sure that the libraries and headers are placed in a location specified by the INCLUDE and LIB directories referenced by the VC compiler and linker. In case multiple libraries are used, you could use a common prefix to install all the libraries, so that you have to specify a single location.
Also, you may need to compile the libraries themselves with VC in order to make it possible to link them when building the FFmpeg DLLs.
The following subsections document how you can build some of the external libraries employed by FFmpeg using VC. Note that the setup step is the same for all the libraries (so it can be done just once, then you can build several libraries using the same MSYS terminal session).
libx264
The following example command will configure libx264:
CC=cl ./configure --enable-shared --prefix=<PREFIX> make make install-lib-shared
libopenh264
libopenh264 now provide meson build system, you can use meson to build with MSVC:
meson setup --buildtype release --prefix=<PREFIX> --cmake-prefix-path=<PREFIX> . <PATH_TO_OPENH264> ninja ninja install