Changes
Page history
Import vkd3d pages from MediaWiki.
authored
Sep 02, 2024
by
Alexandre Julliard
Hide whitespace changes
Inline
Side-by-side
Building-a-MinGW-WoW64-Wine-with-a-custom-vkd3d-build.md
0 → 100644
View page @
52846c72
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
](
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
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:
```
sh
$
mkdir
-p
$HOME
/wine-dirs
```
## Cloning `wine` and `vkd3d` repositories
First, we clone the
`wine`
repository if we haven't already:
```
sh
$
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:
```
sh
$
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:
```
sh
$
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:
```
sh
$
cd
$HOME
/wine-dirs
$
mkdir
wine64p
```
We run the Wine
`configure`
script from the installation folder
```
sh
$
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:
```
sh
$
../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`
<n>
to use
<n>
threads.
```
sh
$
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
](
https://vulkan.lunarg.com
)
.
Alternativelly, you can get them from the official
[
Vulkan-Headers
](
https://github.com/KhronosGroup/Vulkan-Headers
)
and
[
SPIRV-Headers
](
https://github.com/KhronosGroup/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:
```
sh
$
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
```
sh
$
cd
$HOME
/wine-dirs/vkd3d-git
$
./autogen.sh
```
Now we create a folder for the 64-bit vkd3d build
```
sh
$
cd
$HOME
/wine-dirs
$
mkdir
vkd3d64
```
We run the configure script in the installation folder:
```
sh
$
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 inside
`wine-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 the
`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
result in incorrect detection of headers like
`dlfcn.h`
. You will need
to copy or link host headers to a separate directory.
-
We use
`LDFLAGS="-static-libgcc"`
because MinGW gcc depends on
`libgcc_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
```
sh
$
make
```
Append
`-j$(nproc)`
to parallelize.
And if the build succeeds, then we run
```
sh
$
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:
```
sh
$
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:
```
sh
$
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`
and
`VKD3D_PE_LIBS`
to indicate that we will
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
vkd3d's dynamic libraries.
-
Alternatively, you can install MinGW pkg-config, and pass
`PKG_CONFIG_PATH="$HOME/wine-dirs/vkd3d64-prefix/lib/pkgconfig"`
.
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:
```
sh
$
make dlls/ntdll/clean
$
make
```
Append "-j
\$
(nproc)" to make commands to parallelize.
## Build a 32-bit vkd3d installation
```
sh
$
cd
$HOME
/wine-dirs
$
mkdir
vkd3d32
```
```
sh
$
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 of
`vkd3d64-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:
```
sh
$
make
$
make
install
```
## Build 32-bit Wine
We can now build our 32-bit Wine, linking it to our 32-bit vkd3d.
```
sh
$
cd
$HOME
/wine-dirs
$
mkdir
wine32
```
```
sh
$
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`
and
`VKD3D_PE_LIBS`
to the
directories inside
`vkd3d32-prefix`
.
As above, clean ntdll to make sure that the new system DLL path is
picked up, and then rebuild wine:
```
sh
$
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.
```
sh
# 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
```