This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
As of version 7.4, Wine comes with a bundled version of vkd3d.
However, if you want to use a more modern version of vkd3d, apply certain patches to it, or test fixes of your own, you will need Wine to work with a custom version of vkd3d.
For this purpose, it is necessary to build both projects and link them correctly.
Compiling a Windows on Windows (WoW) version of Wine, so that it supports both 32-bits and 64-bits Windows applications – which is often desired – adds a layer of complexity to the build process.
Furthermore, you may want to use MinGW to cross-compile the Wine executables and DLLs in the Windows PE format. This is because various programs expect the on-disk DLLs to look like real PE DLLs.
This guide aims to help you through that process.
Preliminaries
Install Wine dependencies
First, install the dependencies listed in the Building Wine article.
Remember to install the :i386
version of the required packages too (if
your system has multi-lib support).
The mingw and vulkan packages are of particular importance.
It is also recommended that you install ccache
, as it may save us a
considerable amount of time during the builds.
If you have a system-wide installation of vkd3d, it may be good to
uninstall it using make uninstall
. To ensure that the correct version
of vkd3d is linked in this tutorial.
Directory organization
For this tutorial we will need to create several build directories and have several git repositories. For this reason, we will start by creating a common directory for them:
$ mkdir -p $HOME/wine-dirs
Cloning wine
and vkd3d
repositories
First, we clone the wine
repository if we haven't already:
$ git clone https://gitlab.winehq.org/wine/wine.git $HOME/wine-dirs/wine-git
We also need to clone vkd3d
repository if we haven't already:
$ git clone https://gitlab.winehq.org/wine/vkd3d.git $HOME/wine-dirs/vkd3d-git
In case you already have these repositories somewhere else, you can
create symbolic links inside wine-dirs
instead:
$ cd $HOME/wine-dirs
$ ln -s <relative-path-to-wine-repo> wine-git
$ ln -s <relative-path-to-vkd3d-repo> vkd3d-git
Now it is a good time to pick a particular branch or apply the desired patches to these repositories.
Building
Build WIDL
If the distribution provides a recent enough version (3.21 or later as
of this writing) of WIDL, we can skip this step. On Debian that's
provided by the mingw-w64-tools
package. We can also skip this step if
we already have 64-bit Wine available and built.
Vkd3d uses WIDL to compile its IDL files, and if the distribution doesn't provide a package, we'll have to build it from the Wine repository to get it. We start by creating the build directory:
$ cd $HOME/wine-dirs
$ mkdir wine64p
We run the Wine configure
script from the installation folder
$ cd wine64p
$ ../wine-git/configure --enable-win64 CC='ccache gcc' x86_64_CC='ccache x86_64-w64-mingw32-gcc'
Note that we use x86_64_CC
to indicate the compiler used for
cross-compilation, in this case we need the 64-bit mingw32 compiler. We
prepend ccache
which works as a wrapper for the compiler. The same is
done for the regular C compiler, gcc
, passed with the CC
variable.
Note that to know about other parameters for the configure
script we
can use:
$ ../wine-git/configure --help
Also, if something from the configure command fails, it is useful to
search in config.log
for the line that contains the pertinent error,
and the lines before and after it.
Once the configure script has finished, we use make tools/widl/widl
to
only compile WIDL. We can pass -j
to use threads.
$ make -j8 tools/widl/widl
Build a 64-bit vkd3d installation
Now we need to build 64-bit vkd3d. For that purpose we will also need the Vulkan and SPIR-V headers. One way of getting them is downloading the Vulkan SDK.
Alternativelly, you can get them from the official Vulkan-Headers and SPIRV-Headers repositories.
Another alternative is to copy them from your distribution. Usually the
host headers will be installed in /usr/include/vulkan/
and
/usr/include/spirv/
.
Assuming you downloaded and extracted the SDK, move it to the common directory:
$ mv <vulkan sdk path> $HOME/wine-dirs/vulkan-sdk
You must change the first argument of the mv
command depending on
where you downloaded and extracted the SDK. e.g.
~/Downloads/vulkansdk-linux-x86_64-1.3.204.1/1.3.204.1
.
We have to run autogen.sh
in vkd3d-git
to generate vkd3d's
configure
script
$ cd $HOME/wine-dirs/vkd3d-git
$ ./autogen.sh
Now we create a folder for the 64-bit vkd3d build
$ cd $HOME/wine-dirs
$ mkdir vkd3d64
We run the configure script in the installation folder:
$ cd vkd3d64
$ ../vkd3d-git/configure \
--host=x86_64-w64-mingw32 \
--prefix="$HOME/wine-dirs/vkd3d64-prefix" \
WIDL="$HOME/wine-dirs/wine64p/tools/widl/widl" \
SONAME_LIBVULKAN="vulkan-1.dll" \
CPPFLAGS="-I$HOME/wine-dirs/vulkan-sdk/x86_64/include" \
LDFLAGS="-static-libgcc"
--host=x86_64-w64-mingw32
indicates that we want to cross-compile the programs and libraries using the 64-bit MinGW compiler.--prefix="$HOME/wine-dirs/vkd3d64-prefix"
is used to set this build's installation directory. In this case, we will create a new folder insidewine-dirs
. We have to keep in mind that the other programs will expect the vkd3d libraries to be in this directory at run-time.- We set the
WIDL
variable to point to our provisional 64-bit Wine's WIDL. When using the distribution's WIDL,configure
should generally be able to find WIDL on its own and this variable can be omitted; if not, point it to the location of the distribution's WIDL. SONAME_LIBVULKAN
indicates the name of the Vulkan library to load at run-time.- We use
CPPFLAGS
so that the compiler knows to search in thevulkan-sdk
folder for the vulkan headers (-I
flag). Note that you cannot pass-I/usr/include/
here to use the host headers; this will result in incorrect detection of headers likedlfcn.h
. You will need to copy or link host headers to a separate directory. - We use
LDFLAGS="-static-libgcc"
because MinGW gcc depends onlibgcc_s_sjlj-1.dll
; this links a static version. Alternatively, you can add the correct path to--with-system-dllpath
as described below.
Then we run
$ make
Append -j$(nproc)
to parallelize.
And if the build succeeds, then we run
$ make install
to install 64-bit vkd3d in $HOME/wine-dirs/vkd3d64-prefix
.
Build 64-bit wine
Now with the 64-bit vkd3d
installation, we can compile a 64-bit Wine
linked to it.
If you do not have a 64-bit wine tree already, create a new one:
$ cd $HOME/wine-dirs
$ mkdir wine64
Alternatively, you can reuse the same "provisional" Wine tree.
We run the Wine configure
script again, but now specifying the
parameters to link Wine to the 64-bit vkd3d prefix we just created. We
will also need to include the vulkan headers:
$ cd wine64
$ ../wine-git/configure --enable-win64 \
CC='ccache gcc' x86_64_CC='ccache x86_64-w64-mingw32-gcc' \
--with-system-dllpath="$HOME/wine-dirs/vkd3d64-prefix/bin:<mingw 64-bit gcc dynamic dependencies>" \
VKD3D_PE_CFLAGS="-I$HOME/wine-dirs/vulkan-sdk/x86_64/include -I$HOME/wine-dirs/vkd3d64-prefix/include/vkd3d" \
VKD3D_PE_LIBS="-L$HOME/wine-dirs/vkd3d64-prefix/lib -lvkd3d -lvkd3d-shader"
- We use
--with-system-dllpath
so that wine knows to search our vkd3d prefix for the vkd3d DLLs. If you did not use-static-libgcc
to compile vkd3d, you should also add the libgcc path here. Depending on distribution it may be/usr/x86_64-w64-mingw32/bin/
(Arch),/usr/x86_64-w64-mingw32/sys-root/mingw/bin/
(Fedora), or/usr/lib/gcc/x86_64-w64-mingw32/##-win32/
, where##
depends on the gcc version (Debian).- Notice that multiple paths should be separated with a colon.
- We set
VKD3D_PE_CFLAGS
andVKD3D_PE_LIBS
to indicate that we will use a custom version of vkd3d. We useVKD3D_PE_CFLAGS
to include the vulkan headers and the vkd3d headers andVKD3D_PE_LIBS
to load vkd3d's dynamic libraries.- Alternatively, you can install MinGW pkg-config, and pass
PKG_CONFIG_PATH="$HOME/wine-dirs/vkd3d64-prefix/lib/pkgconfig"
.
- Alternatively, you can install MinGW pkg-config, and pass
If you get the following message around the last lines:
configure: libvkd3d 64-bit MinGW development files not found; using bundled version.
Wine was not correctly linked to your custom version of vkd3d. Check
the config.log
.
Clean ntdll to make sure that the new system DLL path is picked up, and then rebuild wine:
$ make dlls/ntdll/clean
$ make
Append "-j$(nproc)" to make commands to parallelize.
Build a 32-bit vkd3d installation
$ cd $HOME/wine-dirs
$ mkdir vkd3d32
$ cd vkd3d32
$ ../vkd3d-git/configure \
--host=i686-w64-mingw32 \
--prefix="$HOME/wine-dirs/vkd3d32-prefix" \
WIDL="$HOME/wine-dirs/wine64p/tools/widl/widl" \
SONAME_LIBVULKAN="vulkan-1.dll" \
CPPFLAGS="-I$HOME/wine-dirs/vulkan-sdk/x86_64/include" \
LDFLAGS="-static-libgcc"
- We now use
--host=i686-w64-mingw32
to indicate that we will use the 32-bit MinGW compiler. - We are changing the prefix so that this 32-bit vkd3d is installed in
the
vkd3d32-prefix
folder instead ofvkd3d64-prefix
. - We're using 64-bit WIDL like before; this is fine.
- We can also still use the Vulkan headers from our 64-bit vulkan-sdk.
We then run:
$ make
$ make install
Build 32-bit Wine
We can now build our 32-bit Wine, linking it to our 32-bit vkd3d.
$ cd $HOME/wine-dirs
$ mkdir wine32
$ cd wine32
$ ../wine-git/configure --with-wine64=../wine64/ \
CC='ccache gcc' i386_CC='ccache i686-w64-mingw32-gcc' \
--with-system-dllpath="$HOME/wine-dirs/vkd3d32-prefix/bin:<mingw 32-bit dynamic dependencies>" \
VKD3D_PE_CFLAGS="-I$HOME/wine-dirs/vulkan-sdk/x86_64/include -I$HOME/wine-dirs/vkd3d32-prefix/include/vkd3d" \
VKD3D_PE_LIBS="-L$HOME/wine-dirs/vkd3d32-prefix/lib -lvkd3d -lvkd3d-shader"
- We now point
--with-system-dllpath
andVKD3D_PE_LIBS
to the directories insidevkd3d32-prefix
.
As above, clean ntdll to make sure that the new system DLL path is picked up, and then rebuild wine:
$ make dlls/ntdll/clean
$ make
Updating your build
If you want to update either wine or vkd3d's source code, we can execute
the following commands in order. ccache
should help reducing the
compilations times.
# Recompile 64-bit vkd3d
cd $HOME/wine-dirs/vkd3d64
make
make install
# Recompile 64-bit wine
cd $HOME/wine-dirs/wine64
make
# Recompile 32-bit vkd3d
cd $HOME/wine-dirs/vkd3d32
make
make install
# Recompile 32-bit wine
cd $HOME/wine-dirs/wine32
make