Skip to content

Building a development version of the LibVLC.UWP nuget

JohannesKauffmann edited this page Nov 22, 2021 · 17 revisions

Building LibVLC for UWP

This page will documentate the process of building your own LibVLC.UWP nuget package for Windows.

Getting the Docker image up and running

First, make sure you have a PC or VM running Linux with about 10-20 GB free disk space.

Install docker for your distro using the instructions and make sure to add your user to the docker group. Next, pull the (at the time of writing) latest Debian image from Videolan, which includes the LLVM compiler:

IMAGE="vlc-debian-llvm-uwp"
curl https://registry.videolan.org/v2/$IMAGE/tags/list | jq '.tags |= sort_by(.)'
docker image pull registry.videolan.org/vlc-debian-llvm-uwp:20211020111246

This will take a while. Now, create a new directory, note it's location and change ownership to the videolan docker user:

cd ~/
mkdir vlc-uwp-volume
sudo chown -R 499:499 vlc-uwp-volume

Start the container, bind the volume and exec into it:

docker run -it -v ~/vlc-uwp-volume:/home/videolan/vlc-uwp-volume registry.videolan.org/vlc-debian-llvm-uwp:20211020111246 bash

Now you should be in the container at /build as the videolan user.

Building LibVLC

Switch to home, checkout the vlc-3.0 and vlc-winrt repo's and apply WinRT specific patches:

cd ~/
git clone https://code.videolan.org/videolan/vlc-3.0.git
git clone https://code.videolan.org/videolan/vlc-winrt.git
cd vlc-3.0
git config --global user.email "[email protected]"
git config --local user.name "Cony Cone"
git am -3 ../vlc-winrt/libvlc/patches/*.patch

Pick one of the HOST_ARCH variables, depending on the architecture:

export HOST_ARCH=i686
export HOST_ARCH=x86_64

Note: The compiler can build for armv7 and aarch64 as well, but this is not tested.

Now set the other environment variables:

export TRIPLET=$HOST_ARCH-w64-mingw32
export LIBVLC_EXTRA_BUILD_FLAGS=-z
export UWP_EXTRA_BUILD_FLAGS="-u -w"

This will set our host triplet to be used by the compiler, and some extra flags for the VLC build script specifically.

Finally, we are ready to build:

extras/package/win32/build.sh -c -a $HOST_ARCH $LIBVLC_EXTRA_BUILD_FLAGS $UWP_EXTRA_BUILD_FLAGS -D c:/sources/vlc-3.0 -o /home/videolan/vlc-uwp-volume/

This will instruct the build script to create a debug build, install it in /home/videolan/vlc-uwp-volume/ and map PDB symbol locations to C:\sources\vlc-3.0\. For a release build, -r should be added.

It also downloads all the third-party dependencies (called contrib) and creates a new contrib package in the contrib folder for each architecture, based on the current sources and with various VLC-specific patches applied. It is (at the time of writing) only possible on x86_64 to use a prebuilt contrib package. Again, see the VLC build script for instructions.

Export package files

After building the package on Linux you need to export the files to Windows. We will be creating a tar.gz out of the files by using the following command.

sudo tar -czvf ~/LibVLC-UWP.tar.gz ~/vlc-uwp-volume/

VirtualBox 6 on Windows 10 running Ubuntu 20.04:

We will use the shared folder functionality of VirtualBox to extract the file from the virtual machine.

  • First, go to Devices->Shared Folders->Shared Folders Settings...
  • Press the Add Share button. This will open the Add Share window.
  • For the Folder Path field you need to choose a destination on the Windows host from where you will access the mount in the virtual machine, for example: C:\Users\Tim\Desktop\VM_Mount.
  • Check the Auto-mount checkbox.
  • As for the Mount point field, you have to give the path of the location where the directory will be mounted to inside the virtual machine. However, we do recommend making use of the /mnt directory, like: /mnt/VM_Mount.
  • Press the OK button in both the Settings window and the Add Share window when done.
  • Check inside the virtual machine if the the mount got created.
    • You can check this by executing the path of the mount in the terminal. An example would be /mnt/VM_Mount/ which results, if the mount exists, in the following message being displayed: bash: /mnt/VM_Mount/: Is a directory. If the mount didn't get created try restarting the virtual machine. Don't forget marking the mount as permanent in the Add Share window before restarting.
  • Now that we are done setting up the mount we can move the LibVLC-UWP.tar.gz file to the mounted directory. Change the destination path when needed.
sudo mv ~/LibVLC-UWP.tar.gz /mnt/VM_Mount/

If everything worked correctly you can now access LibVLC-UWP.tar.gz inside the directory on Windows. In my case the file resides inside C:\Users\Tim\Desktop\VM_Mount.

Building libaccess_winrt_plugin.dll

The build process on Linux should include everything needed to create a nuget package, except libaccess_winrt_plugin.dll. This needs to be build on Windows using MSVC. Clone vlc-winrt on Windows (Git for Windows recommended) to get started:

cd $HOME && cd source/repos
git clone https://code.videolan.org/videolan/vlc-winrt

This will clone the repository in the vlc-winrt directory. Now, going forward, it is assumed that Visual Studio 2019 is used. Inside the repository, navigate to the modules/libaccess_winrt_plugin.UWP folder and open libaccess_winrt_plugin.UWP.vcxproj with Visual Studio 2019. Once opened, rightclick the project (not the solution) and choose Retarget Projects. This will open a new dialog. Choose No Upgrade for every entry except the platform toolset, which should be upgraded to v142.

Next, rightclick the project again and choose properties. When the Project Property Pages dialog appears on screen, navigate to Configuration Properties -> C/C++ -> General and look for Additional Include Directories. This will open a new dialog where the specified, to be included, directories are evaluated. In my case, this path evaluates to C:\Users\Johannes\source\repos\vlc-winrt\modules\libaccess_winrt_plugin.UWP\..\libvlc\Universal\vlc-x86\Debug\include\vlc\plugins, which in turn means C:\Users\Johannes\source\repos\vlc-winrt\modules\libvlc\Universal\vlc-x86\Debug\include\vlc\plugins is the path for the Debug x86 configuration. For every configuration (Debug / Release) and architecture (vlc-x86 / vlc-amd64 / vlc-arm), copy the include directory built earlier to C:\Users\Johannes\source\repos\vlc-winrt\modules\libvlc\Universal\vlc-x86\Debug\ while modifying the path as necessary.

Finally, open libaccess_winrt_plugin.cpp. If the above steps were followed correctly, there should be no include errors. Now the project can be build by selecting Build -> Build Solution. This will always fail except when the output file path is created. If you do not wish to go to such lengths, the build output can also be retreived by navigating to modules/libaccess_winrt_plugin.UWP/{Debug.Release}/libaccess_winrt_plugin.UWP, where the built dll and pdb are located. They will, however, be overwritten for every sequential build, even if the build is for another target architecture. libaccess_winrt_plugin.dll and optionally libaccess_winrt_plugin.pdb should be copied to the built libvlc package in plugins/access for every respective architecture and Debug / Release configuration.

//TODO: use vlc-winrt script to get patches and reduce size, instead of using vlc build script directly. Also research how to get PDB's using this script

//TODO: (nuget) packaging instructions

Clone this wiki locally