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