There are multiple ways to compile VLC for Windows. All of them involve gcc
or llvm
with mingw-w64
.
Compilation with MSVC or clang-cl is currently not supported.
You will also need a UNIX shell to run the build process. On Windows you can either use Windows Subsystem for Linux (WSL) (recommended) or msys2. You may also build inside a Docker on Linux or on Windows.
The choice of which is best depends on your goals. In terms of build times, Docker is the fastest then WSL and msys2 is the slowest.
Unless you use a Docker image, you will need to install multiple development packages that VLC needs to build itself and its contribs.
- On Ubuntu/Debian (or WSL), they are the same tools installed in our Docker Images:
sudo apt-get update -qq
sudo apt-get install -qqy \
git wget bzip2 file libwine-dev unzip libtool libtool-bin libltdl-dev pkg-config ant \
build-essential automake texinfo ragel yasm p7zip-full autopoint \
gettext cmake zip wine nsis g++-mingw-w64-i686 curl gperf flex bison \
libcurl4-gnutls-dev python3 python3-setuptools python3-mako python3-requests \
gcc make procps ca-certificates \
openjdk-11-jdk-headless nasm jq gnupg \
meson autoconf
- On msys2 you should install similar packages:
pacman -Syu
pacman -S --needed git wget bzip2 file unzip libtool pkg-config \
automake autoconf texinfo yasm p7zip \
gettext cmake zip curl gperf flex bison \
python3 python3-setuptools python3-mako \
gcc make ca-certificates nasm gnupg patch help2man \
ragel python3 meson
There are 2 toolchains supported to build VLC for Windows:
- mingw-w64 with gcc
- mingw-w64 with llvm
The gcc
is the most common one as it comes as packages in Linux distributions and msys2.
The problem with the gcc toolchain is that if you need to debug your build with gdb
.
It is very slow when you use breakpoints because for each of the 200+ DLLs loaded
during the VLC launch, it looks for your breakpoints.
The 'llvm' toolchain solves this issue by producing .pdb files. You then debug your code with the Windows Debugger, even within Visual Studio.
The 'llvm' toolchain is normally not found in Linux or msys2. You will need to install it yourself.
You can download prebuilt packages from https://github.com/mstorsjo/llvm-mingw. And then add the
place where you decompressed it, followed by /bin
, in your PATH
.
You also have a choice between ucrt
and msvcrt
. ucrt
is the one you should use if you don't care about
support on Windows versions older than Windows 10. If you need to support older Windows versions you
should go with the msvcrt
version. The official VLC builds use msvcrt
for desktop builds, and
ucrt
for Universal Windows Platform (UWP) builds.
- On Linux:
wget https://github.com/mstorsjo/llvm-mingw/releases/download/20220906/llvm-mingw-20220906-msvcrt-ubuntu-18.04-x86_64.tar.xz
tar xvf llvm-mingw-20220906-msvcrt-ubuntu-18.04-x86_64.tar.xz -C /opt
export PATH=/opt/llvm-mingw-20220906-msvcrt-ubuntu-18.04-x86_64/bin:$PATH
- On msys2, use the mingw64 (blue) environment (ie not msys (purple) the or mingw32 (grey) environments):
wget https://github.com/mstorsjo/llvm-mingw/releases/download/20220906/llvm-mingw-20220906-msvcrt-x86_64.zip
unzip llvm-mingw-20220906-msvcrt-x86_64.zip -d /opt
export PATH=/opt/llvm-mingw-20220906-msvcrt-x86_64/bin:$PATH
Every time you build VLC, you will need to have the toolchain in your PATH. A convenient way to setup your environment is to set command in a file and call it when you start your build sesson:
Create toolchain.sh:
cat export PATH=/opt/llvm-mingw-20220906-msvcrt-x86_64/bin:$PATH > toolchain.sh
Use toolchain.sh to set the path to your compiler:
source toolchain.sh
-
On Docker, you can use these 2 images:
- msvcrt:
registry.videolan.org/vlc-debian-llvm-msvcrt:20221011232542
- ucrt:
registry.videolan.org/vlc-debian-llvm-ucrt:20221012005047
- msvcrt:
You can find the latest Docker images we use in extras/ci/gitlab-ci.yml
This is the default build environment of VLC when cross-compiling. This is also the environment used to produce the official builds that everyone uses. The mingw-w64 toolchain is usually found in all Linux distributions and in msys2. You can install it this way:
- On Linux:
sudo apt-get install -qqy \
gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 mingw-w64-tools
- On msys2:
pacman -S mingw-w64-x86_64-toolchain
> :: Repository mingw64
1) mingw-w64-x86_64-binutils 2) mingw-w64-x86_64-crt-git 3) mingw-w64-x86_64-gcc 4) mingw-w64-x86_64-gcc-ada 5) mingw-w64-x86_64-gcc-fortran 6) mingw-w64-x86_64-gcc-libgfortran 7) mingw-w64-x86_64-gcc-libs 8) mingw-w64-x86_64-gcc-objc
9) mingw-w64-x86_64-gdb 10) mingw-w64-x86_64-gdb-multiarch 11) mingw-w64-x86_64-headers-git 12) mingw-w64-x86_64-libgccjit 13) mingw-w64-x86_64-libmangle-git 14) mingw-w64-x86_64-libwinpthread-git 15) mingw-w64-x86_64-make 16) mingw-w64-x86_64-pkgconf
17) mingw-w64-x86_64-tools-git 18) mingw-w64-x86_64-winpthreads-git 19) mingw-w64-x86_64-winstorecompat-git
> Enter a selection (default=all):
Type enter to select "all"
- On Docker, you can use the
registry.videolan.org/vlc-debian-win64:20221011230137
image.
You can find the latest Docker images we use in extras/ci/gitlab-ci.yml
This is the easy part. In your UNIX Shell type:
git config --global core.autocrlf false
git clone https://code.videolan.org/videolan/vlc.git
This will download the VLC source code into the vlc
folder, in your current directory.
Fully build in a separate folder build
:
mkdir build
cd build
../vlc/extras/package/win32/build.sh -a x86_64
This will build
- VLC "extra tools" in case you are missing some in your environment.
- VLC "contribs", a hundred different libraries that VLC uses like FFmpeg, Qt, etc.
- VLC "core" (libvlccore.dll) the heart of VLC.
- VLC "modules" which contains all the possible extensions to add functionality to VLC.
- libvlc.dll a DLL to use VLC from external code with a stable API.
You may not want to spend one or two hours building all the contribs if you're never going to want to touch any of them. In that case you may want to reuse prebuilt binaries and save some time. To build with prebuilt contribs you need to have a matching compiler and especially a matching C++ compiler. So the ones available may not match your environment. In that case you still need to build the contribs yourself.
The choice of compiler may depend on how you plan to debug your code. See the Debugging section below for more information.
If your mingw-w64 compiler/toolchain is gcc 11 you can use these commands to build VLC and reuse prebuilt contribs:
mkdir build
cd build
export VLC_CONTRIB_SHA="$(cd ../vlc; extras/ci/get-contrib-sha.sh)"
export VLC_PREBUILT_CONTRIBS_URL="https://artifacts.videolan.org/vlc/win64/vlc-contrib-x86_64-w64-mingw32-${VLC_CONTRIB_SHA}.tar.bz2"
../vlc/extras/package/win32/build.sh -a x86_64 -p
If your mingw-w64 compiler/toolchain is LLVM 13 you can use these commands to build VLC and reuse prebuilt contribs. The name of the prebuilt tarball is the same, but the folder is different:
mkdir build
cd build
export VLC_CONTRIB_SHA="$(cd ../vlc; extras/ci/get-contrib-sha.sh)"
export VLC_PREBUILT_CONTRIBS_URL="https://artifacts.videolan.org/vlc/win64-llvm/vlc-contrib-x86_64-w64-mingw32-$VLC_CONTRIB_SHA.tar.bz2"
time ../vlc/extras/package/win32/build.sh -a x86_64 -p
You may be interested in just building libvlc without the desktop app. In that case
you can add -z
to you build.sh call. It will save you some building time, especially
if you build contribs. And it will also avoid creating the Qt gui plugins you will never use.
mkdir build
cd build
../vlc/extras/package/win32/build.sh -a x86_64 -z
You may want to reduce the load on your CPU, and thus your memory, when building.
You can control the number of maximum threads used during compilation with the JOBS
environment variable.
Due to a missing feature in ninja, contribs built from Meson will use all your CPU's
regardless of the JOBS
value. You can reduce the problem by allocating a single
CPU thread to each Meson contrib with the MESON_BUILD
environment variable.
Here is an example limit the build to 8 threads and 1 per Meson/ninja contrib.
JOBS=8 MESON_BUILD="-j 1" ../vlc/extras/package/win32/build.sh -a x86_64
When building VLC manually, it's possible to enable/disable certain features of VLC or select/unselect some compilation configurations. You can find the list of options when running :
../vlc/configure -h
You can pass all these options to build.sh
using the CONFIGFLAGS
environment
variable.
For example you can enable the address sanitizer with:
CONFIGFLAGS="--with-sanitizer=address" ../vlc/extras/package/win32/build.sh -a x86_64
When building VLC manually, it's possible to select/unselect certain contribs or enable/disable some features. You can find the list of options when running:
../vlc/contribs/bootstrap -h
You can pass all these options to build.sh
using the CONTRIBFLAGS
environment
variable.
For example you can disable bluray building with:
CONTRIBFLAGS="--disable-bluray" ../vlc/extras/package/win32/build.sh -a x86_64
Most of the time, if you need to build VLC yourself, you will also need to debug it.
The way to debug VLC on Windows depends on the toolchain you are using. When building
with gcc you need to use gdb
. When building with LLVM, you can use gdb
or
the Windows Debugger
.
The latter is much faster than gdb which is very slow to pick breakpoints in the hundred of VLC DLL's.
By default VLC is built with debug symbols. But if you want to use the Windows Debugger
with LLVM, you need to build with .pdb
files. You can do that by adding -d
to
the build.sh
call.
../vlc/extras/package/win32/build.sh -a x86_64 -d
This will create PDB files, but since we are building in a UNIX environment, the paths written in the PDB are UNIX files. The debugger will fail to find the proper source files when you are debugging. There are different ways to fix this. Both involve mapping the UNIX paths to paths in your Windows machine. That also means if you want to debug properly the code you are editing, it needs to be visible in Windows. It's always the case in msys2. It can be the case with WSL also it's faster in a WSL1 environment than in WSL2. In Docker it's also possible by mapping a Windows folder to make it accessible in your Docker. In the end your VLC source code should be on a partition/drive that Windows can see, and thus the Windows Debugger.
You can set the UNIX to Windows mapping when enabling PDB's in build.sh
. You need
to set the Windows path where the VLC sources are this way:
../vlc/extras/package/win32/build.sh -a x86_64 -D "c:/path/to/sources/vlc"
You can also set it in your environment CFLAGS
and CXXFLAGS
which you can also add
in your toolchain.sh
described above:
CFLAGS="-fdebug-prefix-map='/mnt/c/'='c:/'" CXXFLAGS="-fdebug-prefix-map='/mnt/c/'='c:/'" ../vlc/extras/package/win32/build.sh -a x86_64 -d
The VLC you download has all plugins structured in different folders, all in a "plugins"
folder.
But when you build VLC this is not the case. VLC cannot be used that way. It needs to be
either installed with the following command:
cd win64; make package-win-common
You will end up with a vlc-4.0.0-dev
folder with the vlc EXE's and DLL's in the
proper place. You can debug from there. But this way of building is much slower than
just building the files that have been modified.
A faster way to debug is to just build with build.sh
or even just calling make
in the win64
folder. In that case you need to setup your debugging environment to
pick libvlccore.dll
, libvlc.dll
and plugins that you built. libvlccore.dll
is
found in win64/src/.libs
and libvlc.dll
is found in win64/lib/.libs
. You need to
add these paths to your PATH
.
PATH="c:\path\to\sources\vlc\win64\lib\.libs;c:\path\to\sources\vlc\win64\src\.libs;C:\Windows\System32;C:\Windows;C:\Windows\System32\downlevel"
And when you run vlc.exe, you also need to set the VLC_PLUGIN_PATH
environment variable
to the folder with all the plugins you built:
VLC_PLUGIN_PATH=c:\path\to\sources\vlc\win64\modules
In the future it might be possible to build VLC with Meson. With a native Windows toolchain it might be possible to have proper Windows paths when compiling, which makes it even easier to develop (click on the file path on compilation error). It will also avoid mapping the PDB paths of UNIX paths to Windows paths.