WineHQ

Pop! os: Difference between revisions

(Created page with "= Building Wine in Pop!_OS = While Pop!_OS, like Ubuntu, has support for multi-arch libraries, some i386 packages that are required to build a 32-bit version of Wine may conf...")
 
No edit summary
Line 7: Line 7:
We start by creating a working directory:
We start by creating a working directory:


<syntaxhighlight>
  mkdir $HOME/wine-dir
mkdir $HOME/wine-dir
  cd $HOME/wine-dir
cd $HOME/wine-dir
 
</syntaxhighlight>


== Setting up an LXC container ==
== Setting up an LXC container ==
Line 20: Line 19:
Install LXD through snap:
Install LXD through snap:


<syntaxhighlight>
  $ sudo apt install snapd
$ sudo apt install snapd
  $ snap install lxd
$ snap install lxd
 
</syntaxhighlight>


Add your current user to the lxd group so that it has the correct permissions to use the application:
Add your current user to the lxd group so that it has the correct permissions to use the application:


<syntaxhighlight>
  $ sudo usermod -aG lxd $USER
$ sudo usermod -aG lxd $USER
  $ reboot # to apply permissions.
$ reboot # to apply permissions.
</syntaxhighlight>


Initialize LXD:
Initialize LXD:
<syntaxhighlight>
 
$ lxd init
  $ lxd init
</syntaxhighlight>
 


If you don't want containers to automatically start on boot:
If you don't want containers to automatically start on boot:
<syntaxhighlight>
 
$ lxc profile set default boot.autostart false
  $ lxc profile set default boot.autostart false
</syntaxhighlight>
 


Launch an Ubuntu container:
Launch an Ubuntu container:
<syntaxhighlight>
 
$ lxc launch ubuntu:20.04 wine-container
  $ lxc launch ubuntu:20.04 wine-container
</syntaxhighlight>
 


Start the container:
Start the container:
<syntaxhighlight>
 
$ lxc list
  $ lxc list
$ lxc start wine-container
  $ lxc start wine-container
</syntaxhighlight>
 
and update:
and update:
<syntaxhighlight>
 
$ lxc exec wine-container -- apt update
  $ lxc exec wine-container -- apt update
</syntaxhighlight>
 


To enter container, use the following command:
To enter container, use the following command:
<syntaxhighlight>
 
$ lxc exec wine-container -- /bin/bash
  $ lxc exec wine-container -- /bin/bash
</syntaxhighlight>
 


In order to share files between the host and the container, we have two options:
In order to share files between the host and the container, we have two options:
Line 81: Line 77:
First, we need to know our user id in the host, for that purpose we can use the <code>id</code> command:
First, we need to know our user id in the host, for that purpose we can use the <code>id</code> command:


<syntaxhighlight>
  $ id
$ id
</syntaxhighlight>


This is an example output:
This is an example output:
<syntaxhighlight>
 
uid=1000(alice) gid=1000(alice) groups=1000(alice),4(adm),27(sudo),121(lpadmin),999(lxd)
  uid=1000(alice) gid=1000(alice) groups=1000(alice),4(adm),27(sudo),121(lpadmin),999(lxd)
</syntaxhighlight>


We see that our user (alice in this example) has user id (uid) 1000, and group id (gid) 1000.
We see that our user (alice in this example) has user id (uid) 1000, and group id (gid) 1000.
Line 96: Line 89:
We do that by adding new lines to the <code>/etc/subuid</code> and <code>/etc/subgid</code> files, respectively:
We do that by adding new lines to the <code>/etc/subuid</code> and <code>/etc/subgid</code> files, respectively:


<syntaxhighlight>
  $ echo "root:1000:1" | sudo tee -a /etc/subuid
$ echo "root:1000:1" | sudo tee -a /etc/subuid
  $ echo "root:1000:1" | sudo tee -a /etc/subgid
$ echo "root:1000:1" | sudo tee -a /etc/subgid
</syntaxhighlight>


where we need to replace the <code>1000</code> with our uid in the first line, and to replace the <code>1000</code> with our gid in the second line.
where we need to replace the <code>1000</code> with our uid in the first line, and to replace the <code>1000</code> with our gid in the second line.
Line 107: Line 98:
The next step is to remap the user ID inside the container, so we need to enter it, with the aforementioned command:
The next step is to remap the user ID inside the container, so we need to enter it, with the aforementioned command:


<syntaxhighlight>
  $ lxc exec wine-container -- /bin/bash
$ lxc exec wine-container -- /bin/bash
</syntaxhighlight>


After entering the container, we need to know if our user is already present inside:
After entering the container, we need to know if our user is already present inside:


<syntaxhighlight>
  # grep '^alice' /etc/passwd
# grep '^alice' /etc/passwd
</syntaxhighlight>


If no line appears, we need to create it:
If no line appears, we need to create it:


<syntaxhighlight>
  # adduser alice
# adduser alice
</syntaxhighlight>


We now need the uid and gid our user inside the container:
We now need the uid and gid our user inside the container:


<syntaxhighlight>
  # id alice
# id alice
</syntaxhighlight>


This is an example output:
This is an example output:
<syntaxhighlight>
 
uid=1001(alice) gid=1001(alice) groups=1001(alice)
  uid=1001(alice) gid=1001(alice) groups=1001(alice)
</syntaxhighlight>


in this case the uid and the gid are 1001.
in this case the uid and the gid are 1001.
Line 138: Line 120:
Now we go back to the host, and map both the uid and gid from our user in the host to our user in the container:
Now we go back to the host, and map both the uid and gid from our user in the host to our user in the container:


<syntaxhighlight>
  $ lxc config set wine-container raw.idmap "both 1000 1001"
$ lxc config set wine-container raw.idmap "both 1000 1001"
</syntaxhighlight>


where we replace the 1000 and 1001 accordingly.
where we replace the 1000 and 1001 accordingly.
Line 146: Line 126:
And we restart the container:
And we restart the container:


<syntaxhighlight>
  $ lxc restart wine-container
$ lxc restart wine-container
</syntaxhighlight>


Finally, we can mount the directory:
Finally, we can mount the directory:


<syntaxhighlight>
  $ lxc config device add wine-container wine-dir disk source=$HOME/wine-dir path=/root/wine-dir
$ lxc config device add wine-container wine-dir disk source=$HOME/wine-dir path=/root/wine-dir
</syntaxhighlight>


== Download the wine source code ==
== Download the wine source code ==


We clone the wine repo inside the wine-dir directory, in the host system:
We clone the wine repo inside the wine-dir directory, in the host system:
<syntaxhighlight>
 
$ cd $HOME/wine-dir
  $ cd $HOME/wine-dir
$ git clone https://gitlab.winehq.org/wine/wine.git wine-source
  $ git clone https://gitlab.winehq.org/wine/wine.git wine-source
</syntaxhighlight>


We can then select a specific branch or tag:
We can then select a specific branch or tag:
<syntaxhighlight>
 
$ cd wine-source
  $ cd wine-source
$ git checkout stable
  $ git checkout stable
</syntaxhighlight>


== Install wine dependencies in the container ==
== Install wine dependencies in the container ==


We need access to the source code repositories inside the container, so we enter the container again:
We need access to the source code repositories inside the container, so we enter the container again:
<syntaxhighlight>
 
$ lxc exec wine-container -- /bin/bash
  $ lxc exec wine-container -- /bin/bash
</syntaxhighlight>


Uncomment all <code>deb-src</code> lines after uncommented <code>dev</code> lines in <code>/etc/apt/sources.list</code> using <code>nano</code> or <code>vim</code>:
Uncomment all <code>deb-src</code> lines after uncommented <code>dev</code> lines in <code>/etc/apt/sources.list</code> using <code>nano</code> or <code>vim</code>:
<syntaxhighlight>
 
# nano /etc/apt/sources.list
  # nano /etc/apt/sources.list
</syntaxhighlight>


Also, add the i386 arch, and '''update''':
Also, add the i386 arch, and '''update''':
<syntaxhighlight>
 
# dpkg --add-architecture i386
  # dpkg --add-architecture i386
# apt update
  # apt update
</syntaxhighlight>


Install both x86-64 and i386 wine dependencies
Install both x86-64 and i386 wine dependencies
<syntaxhighlight>
# apt-cache depends wine # Just lists distro's wine package dependencies.
# apt build-dep wine64
# apt build-dep wine32:i386
# apt install gcc-multilib g++-multilib
# apt install libx11-dev:i386 libfreetype-dev:i386 libgnutls28-dev:i386 ocl-icd-opencl-dev:i386 libvulkan-dev:i386
# apt install gcc-mingw-w64
</syntaxhighlight>


You may need more, check the [[Building Wine#Satisfying_Build_Dependencies | Building Wine]] page.
  # apt-cache depends wine # Just lists distro's wine package dependencies.
  # apt build-dep wine64
  # apt build-dep wine32:i386
  # apt install gcc-multilib g++-multilib
  # apt install libx11-dev:i386 libfreetype-dev:i386 libgnutls28-dev:i386 ocl-icd-opencl-dev:i386 libvulkan-dev:i386
  # apt install gcc-mingw-w64
 
In case you need more, check the [[Building Wine#Satisfying_Build_Dependencies | Building Wine]] page.


This is a list of packages that works at the time of writing:
This is a list of packages that works at the time of writing:


<syntaxhighlight>
  # apt install libgl-dev libpulse-dev libdbus-1-dev libfontconfig-dev libxrender-dev gettext libxcursor-dev libxi-dev libxrandr-dev libxfixes-dev libxinerama-dev libxcomposite-dev libosmesa6-dev libpcap-dev libsane-dev libusb-1.0-0-dev libv4l-dev libgphoto2-dev libgphoto2-dev libudev-dev libsdl2-dev libcapi20-dev libkrb5-dev libopenal-dev libldap-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1.0-dev libpng-dev libjpeg-dev libtiff-dev
# apt install libgl-dev libpulse-dev libdbus-1-dev libfontconfig-dev libxrender-dev gettext libxcursor-dev libxi-dev libxrandr-dev libxfixes-dev libxinerama-dev libxcomposite-dev libosmesa6-dev libpcap-dev libsane-dev libusb-1.0-0-dev libv4l-dev libgphoto2-dev libgphoto2-dev libudev-dev libsdl2-dev libcapi20-dev libkrb5-dev libopenal-dev libldap-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1.0-dev libpng-dev libjpeg-dev libtiff-dev
</syntaxhighlight>


and their i386 versions:
and their i386 versions:


<syntaxhighlight>
  # apt install libgl-dev:i386 libpulse-dev:i386 libdbus-1-dev:i386 libfontconfig-dev:i386 libxrender-dev:i386 gettext:i386 libxcursor-dev:i386 libxi-dev:i386 libxrandr-dev:i386 libxfixes-dev:i386 libxinerama-dev:i386 libxcomposite-dev:i386 libosmesa6-dev:i386 libpcap-dev:i386 libsane-dev:i386 libusb-1.0-0-dev:i386 libv4l-dev:i386 libgphoto2-dev:i386 libgphoto2-dev:i386 libudev-dev:i386 libsdl2-dev:i386 libcapi20-dev:i386 libkrb5-dev:i386 libopenal-dev:i386 libldap-dev:i386 libgstreamer1.0-dev:i386 libgstreamer-plugins-base1.0-dev:i386 libgstreamer-plugins-good1.0-dev:i386 libpng-dev:i386 libjpeg-dev:i386 libtiff-dev:i386
# apt install libgl-dev:i386 libpulse-dev:i386 libdbus-1-dev:i386 libfontconfig-dev:i386 libxrender-dev:i386 gettext:i386 libxcursor-dev:i386 libxi-dev:i386 libxrandr-dev:i386 libxfixes-dev:i386 libxinerama-dev:i386 libxcomposite-dev:i386 libosmesa6-dev:i386 libpcap-dev:i386 libsane-dev:i386 libusb-1.0-0-dev:i386 libv4l-dev:i386 libgphoto2-dev:i386 libgphoto2-dev:i386 libudev-dev:i386 libsdl2-dev:i386 libcapi20-dev:i386 libkrb5-dev:i386 libopenal-dev:i386 libldap-dev:i386 libgstreamer1.0-dev:i386 libgstreamer-plugins-base1.0-dev:i386 libgstreamer-plugins-good1.0-dev:i386 libpng-dev:i386 libjpeg-dev:i386 libtiff-dev:i386
</syntaxhighlight>


We can also install ccache to lower our build times in case we need to build Wine many times:
We can also install ccache to lower our build times in case we need to build Wine many times:
<syntaxhighlight>
 
# apt install ccache
  # apt install ccache
</syntaxhighlight>


And other packages that you may want, such as <code>valgrind:i386</code>.
And other packages that you may want, such as <code>valgrind:i386</code>.
Line 223: Line 188:
Let's start by building a 64-bit version of Wine inside the container.
Let's start by building a 64-bit version of Wine inside the container.


<syntaxhighlight>
  # cd /root/wine-dir
# cd /root/wine-dir
  # mkdir wine64
# mkdir wine64
  # cd wine64
# cd wine64
  # ../wine-source/configure --enable-win64 CC="ccache gcc" CROSSCC="ccache x86_64-w64-mingw32-gcc"
# ../wine-source/configure --enable-win64 CC="ccache gcc" CROSSCC="ccache x86_64-w64-mingw32-gcc"
</syntaxhighlight>


Where the CROSSCC option allows cross compiling modules as PE.
Where the CROSSCC option allows cross compiling modules as PE.
Line 238: Line 201:
Run:
Run:


<syntaxhighlight>
  # make -j8 # or as many CPU threads you have available.
# make -j8 # or as many CPU threads you have available.
</syntaxhighlight>


== Building 32-bit wine-tools ==
== Building 32-bit wine-tools ==
Line 249: Line 210:
Before we build a 32-bit wine, we need the 32-bit wine-tools, so we make a provisional 32-bit version of Wine:
Before we build a 32-bit wine, we need the 32-bit wine-tools, so we make a provisional 32-bit version of Wine:


<syntaxhighlight>
  # cd /root/wine-dir
# cd /root/wine-dir
  # mkdir wine32-tools
# mkdir wine32-tools
  # cd wine32-tools
# cd wine32-tools
  # ../wine-source/configure CC="ccache gcc" CROSSCC="ccache i686-w64-mingw32-gcc"
# ../wine-source/configure CC="ccache gcc" CROSSCC="ccache i686-w64-mingw32-gcc"
  # make -j8 # or as many CPU threads you have available.
# make -j8 # or as many CPU threads you have available.
</syntaxhighlight>


If you don't use ccache, remove <code>ccache </code> from the options.
If you don't use ccache, remove <code>ccache </code> from the options.
Line 261: Line 220:
== Building 32-bit wine ==
== Building 32-bit wine ==


<syntaxhighlight>
  # cd /root/wine-dir
# cd /root/wine-dir
  # mkdir wine32
# mkdir wine32
  # cd wine32
# cd wine32
</syntaxhighlight>


Configure and make:
Configure and make:
<syntaxhighlight>
 
# ../wine-source/configure --with-wine64=../wine64 --with-wine-tools=../wine32-tools CC="ccache gcc" CROSSCC="ccache i686-w64-mingw32-gcc"
  # ../wine-source/configure --with-wine64=../wine64 --with-wine-tools=../wine32-tools CC="ccache gcc" CROSSCC="ccache i686-w64-mingw32-gcc"
# make -j8 # or as many threads you have available.
  # make -j8 # or as many threads you have available.
</syntaxhighlight>


Again, if you don't use ccache, remove <code>ccache </code> from the options.
Again, if you don't use ccache, remove <code>ccache </code> from the options.
Line 280: Line 236:


We can inspect all the symbolic links:
We can inspect all the symbolic links:
<syntaxhighlight>
 
$ cd $HOME/wine-dir
  $ cd $HOME/wine-dir
$ find wine32 wine64 wine32-tools -type l -ls
  $ find wine32 wine64 wine32-tools -type l -ls
</syntaxhighlight>
 


In particular the offending ones:
In particular the offending ones:
<syntaxhighlight>
 
$ find wine32 wine64 wine32-tools -type l -ls | grep '-> /root/'
  $ find wine32 wine64 wine32-tools -type l -ls | grep '-> /root/'
</syntaxhighlight>
 


At the moment of writing, there are two links that need to be changed, the ones that the 64-bit build uses to refer to the 32-bit build:
At the moment of writing, there are two links that need to be changed, the ones that the 64-bit build uses to refer to the 32-bit build:


<syntaxhighlight>
  wine64/loader/wine -> /root/wine-dir/wine32/loader/wine
... wine64/loader/wine -> /root/wine-dir/wine32/loader/wine
  wine64/loader/wine-preloader -> /root/wine-dir/wine32/loader/wine-preloader
... wine64/loader/wine-preloader -> /root/wine-dir/wine32/loader/wine-preloader
</syntaxhighlight>


We change them inside the container:
We change them inside the container:


<syntaxhighlight>
  # cd /root/wine-dir
# cd /root/wine-dir
  # rm wine64/loader/wine wine64/loader/wine-preloader
# rm wine64/loader/wine wine64/loader/wine-preloader
  # ln -s ../../wine32/loader/wine wine64/loader/wine
# ln -s ../../wine32/loader/wine wine64/loader/wine
  # ln -s ../../wine32/loader/wine-preloader wine64/loader/wine-preloader
# ln -s ../../wine32/loader/wine-preloader wine64/loader/wine-preloader
</syntaxhighlight>


== Install runtime dependencies in the host system ==
== Install runtime dependencies in the host system ==
Line 312: Line 264:
As mentioned in the [[Building_Wine#Runtime_Dependencies]] section of the Building Wine page, the easiest way to achieve this is to install the wine package provided by the distribution in the host system:
As mentioned in the [[Building_Wine#Runtime_Dependencies]] section of the Building Wine page, the easiest way to achieve this is to install the wine package provided by the distribution in the host system:


<syntaxhighlight>
  $ apt install wine
$ apt install wine
</syntaxhighlight>


Keep in mind that the <code>wine</code> command will execute the version of wine that this package installs, and not the one you build.
Keep in mind that the <code>wine</code> command will execute the version of wine that this package installs, and not the one you build.


You may also want to install optional runtime dependencies such as:
You may also want to install optional runtime dependencies such as:
<syntaxhighlight>
 
$ apt install corefonts
  $ apt install corefonts
</syntaxhighlight>


== Run wine ==
== Run wine ==
Line 327: Line 276:
You should be able to run wine from your build now, remember to use it with a prefix.
You should be able to run wine from your build now, remember to use it with a prefix.


<syntaxhighlight>
  $ PREFIX=$HOME/wine-dir/wine-prefix $HOME/wine-dir/wine64/wine --version
$ PREFIX=$HOME/wine-dir/wine-prefix $HOME/wine-dir/wine64/wine --version
</syntaxhighlight>


We can stop the container now
We can stop the container now


<syntaxhighlight>
  lxc stop wine-container
lxc stop wine-container
</syntaxhighlight>


== Pushing and pulling files from the container without a shared directory ==
== Pushing and pulling files from the container without a shared directory ==
Line 343: Line 288:
The syntax is:
The syntax is:


<syntaxhighlight>
  lxc file push -r <host-src-directory> wine-container/root/<container-dst-directory>
lxc file push -r <host-src-directory> wine-container/root/<container-dst-directory>
  lxc file pull -r wine-container/root/<container-dst-directory> <host-dst-directory>
lxc file pull -r wine-container/root/<container-dst-directory> <host-dst-directory>
</syntaxhighlight>


Keep in mind that symbolic links end up invalid in the host system after pulling, because <code>lxc file pull</code> makes their paths absolute and respective to the container filesystem. Check the symbolic links using:
Keep in mind that symbolic links end up invalid in the host system after pulling, because <code>lxc file pull</code> makes their paths absolute and respective to the container filesystem. Check the symbolic links using:


<syntaxhighlight>
  $ find <pulled-directory> -type l -ls
$ find <pulled-directory> -type l -ls
</syntaxhighlight>


We can fix them running the following <code>link_fixer.sh</code> script in the same folder we pulled the directory.
We can fix them running the following <code>link_fixer.sh</code> script in the same folder we pulled the directory.
Line 372: Line 313:
</syntaxhighlight>
</syntaxhighlight>


<syntaxhighlight>
  $ bash link_fixer.sh <host-dst-directory>
$ bash link_fixer.sh <host-dst-directory>
</syntaxhighlight>

Revision as of 00:53, 30 March 2023

Building Wine in Pop!_OS

While Pop!_OS, like Ubuntu, has support for multi-arch libraries, some i386 packages that are required to build a 32-bit version of Wine may conflict with pre-installed system packages, so you won't be able to install them.

For this reason, in this tutorial we will use LXD to create a 64-bit Ubuntu LXC container were we will install the required packages, build Wine with WoW64 support, and then use it to our host system.

We start by creating a working directory:

 mkdir $HOME/wine-dir
 cd $HOME/wine-dir


Setting up an LXC container

This Section is based on the official Pop!_OS documentation on containers.

We use LXD to create the Ubuntu container.

Install LXD through snap:

 $ sudo apt install snapd
 $ snap install lxd


Add your current user to the lxd group so that it has the correct permissions to use the application:

 $ sudo usermod -aG lxd $USER
 $ reboot # to apply permissions.

Initialize LXD:

 $ lxd init


If you don't want containers to automatically start on boot:

 $ lxc profile set default boot.autostart false


Launch an Ubuntu container:

 $ lxc launch ubuntu:20.04 wine-container


Start the container:

 $ lxc list
 $ lxc start wine-container

and update:

 $ lxc exec wine-container -- apt update


To enter container, use the following command:

 $ lxc exec wine-container -- /bin/bash


In order to share files between the host and the container, we have two options:

  • (a) Setup a shared host directory inside the LXC container in read-write mode.
  • (b) Pull and push directories every time we need to.

Option (a) is probably the most comfortable in the long run, if you need to compile wine many times, but it requires special permissions and a longer setup.

We will use Option (a) in this tutorial. For Option (b) see #Pushing and pulling files from the container without a shared directory.


Setup a shared host directory inside the LXC container

This Section is based on a tutorial from nixCraft.

Allow remaping the user ID in the host

First, we need to know our user id in the host, for that purpose we can use the id command:

 $ id

This is an example output:

 uid=1000(alice) gid=1000(alice) groups=1000(alice),4(adm),27(sudo),121(lpadmin),999(lxd)

We see that our user (alice in this example) has user id (uid) 1000, and group id (gid) 1000.

Now, we need to give permission to the root user (and thus, the LXD daemon) to remap the user id and the group id.

We do that by adding new lines to the /etc/subuid and /etc/subgid files, respectively:

 $ echo "root:1000:1" | sudo tee -a /etc/subuid
 $ echo "root:1000:1" | sudo tee -a /etc/subgid

where we need to replace the 1000 with our uid in the first line, and to replace the 1000 with our gid in the second line.

Remap user ID inside the container

The next step is to remap the user ID inside the container, so we need to enter it, with the aforementioned command:

 $ lxc exec wine-container -- /bin/bash

After entering the container, we need to know if our user is already present inside:

 # grep '^alice' /etc/passwd

If no line appears, we need to create it:

 # adduser alice

We now need the uid and gid our user inside the container:

 # id alice

This is an example output:

 uid=1001(alice) gid=1001(alice) groups=1001(alice)

in this case the uid and the gid are 1001.

Now we go back to the host, and map both the uid and gid from our user in the host to our user in the container:

 $ lxc config set wine-container raw.idmap "both 1000 1001"

where we replace the 1000 and 1001 accordingly.

And we restart the container:

 $ lxc restart wine-container

Finally, we can mount the directory:

 $ lxc config device add wine-container wine-dir disk source=$HOME/wine-dir path=/root/wine-dir

Download the wine source code

We clone the wine repo inside the wine-dir directory, in the host system:

 $ cd $HOME/wine-dir
 $ git clone https://gitlab.winehq.org/wine/wine.git wine-source

We can then select a specific branch or tag:

 $ cd wine-source
 $ git checkout stable

Install wine dependencies in the container

We need access to the source code repositories inside the container, so we enter the container again:

 $ lxc exec wine-container -- /bin/bash

Uncomment all deb-src lines after uncommented dev lines in /etc/apt/sources.list using nano or vim:

 # nano /etc/apt/sources.list

Also, add the i386 arch, and update:

 # dpkg --add-architecture i386
 # apt update

Install both x86-64 and i386 wine dependencies

 # apt-cache depends wine # Just lists distro's wine package dependencies.
 # apt build-dep wine64
 # apt build-dep wine32:i386
 # apt install gcc-multilib g++-multilib
 # apt install libx11-dev:i386 libfreetype-dev:i386 libgnutls28-dev:i386 ocl-icd-opencl-dev:i386 libvulkan-dev:i386
 # apt install gcc-mingw-w64

In case you need more, check the Building Wine page.

This is a list of packages that works at the time of writing:

 # apt install libgl-dev libpulse-dev libdbus-1-dev libfontconfig-dev libxrender-dev gettext libxcursor-dev libxi-dev libxrandr-dev libxfixes-dev libxinerama-dev libxcomposite-dev libosmesa6-dev libpcap-dev libsane-dev libusb-1.0-0-dev libv4l-dev libgphoto2-dev libgphoto2-dev libudev-dev libsdl2-dev libcapi20-dev libkrb5-dev libopenal-dev libldap-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1.0-dev libpng-dev libjpeg-dev libtiff-dev

and their i386 versions:

 # apt install libgl-dev:i386 libpulse-dev:i386 libdbus-1-dev:i386 libfontconfig-dev:i386 libxrender-dev:i386 gettext:i386 libxcursor-dev:i386 libxi-dev:i386 libxrandr-dev:i386 libxfixes-dev:i386 libxinerama-dev:i386 libxcomposite-dev:i386 libosmesa6-dev:i386 libpcap-dev:i386 libsane-dev:i386 libusb-1.0-0-dev:i386 libv4l-dev:i386 libgphoto2-dev:i386 libgphoto2-dev:i386 libudev-dev:i386 libsdl2-dev:i386 libcapi20-dev:i386 libkrb5-dev:i386 libopenal-dev:i386 libldap-dev:i386 libgstreamer1.0-dev:i386 libgstreamer-plugins-base1.0-dev:i386 libgstreamer-plugins-good1.0-dev:i386 libpng-dev:i386 libjpeg-dev:i386 libtiff-dev:i386

We can also install ccache to lower our build times in case we need to build Wine many times:

 # apt install ccache

And other packages that you may want, such as valgrind:i386.

Building 64-bit wine

Let's start by building a 64-bit version of Wine inside the container.

 # cd /root/wine-dir
 # mkdir wine64
 # cd wine64
 # ../wine-source/configure --enable-win64 CC="ccache gcc" CROSSCC="ccache x86_64-w64-mingw32-gcc"

Where the CROSSCC option allows cross compiling modules as PE.

If you don't use ccache, remove ccache in both arguments.

Read the configure script output. If you need more libraries, install them as in the previous step, otherwise continue.

Run:

 # make -j8 # or as many CPU threads you have available.

Building 32-bit wine-tools

Now we need to build a 32-bit version of Wine and inject it into our 64-bit Wine build to turn it into a WoW64 Wine, so that it supports 32-bit Windows applications, since most of them indeed are 32-bit.

Before we build a 32-bit wine, we need the 32-bit wine-tools, so we make a provisional 32-bit version of Wine:

 # cd /root/wine-dir
 # mkdir wine32-tools
 # cd wine32-tools
 # ../wine-source/configure CC="ccache gcc" CROSSCC="ccache i686-w64-mingw32-gcc"
 # make -j8 # or as many CPU threads you have available.

If you don't use ccache, remove ccache from the options.

Building 32-bit wine

 # cd /root/wine-dir
 # mkdir wine32
 # cd wine32

Configure and make:

 # ../wine-source/configure --with-wine64=../wine64 --with-wine-tools=../wine32-tools CC="ccache gcc" CROSSCC="ccache i686-w64-mingw32-gcc"
 # make -j8 # or as many threads you have available.

Again, if you don't use ccache, remove ccache from the options.

Fixing symbolic links

Some links may have absolute paths for within the container. These need to be fixed.

We can inspect all the symbolic links:

 $ cd $HOME/wine-dir
 $ find wine32 wine64 wine32-tools -type l -ls


In particular the offending ones:

 $ find wine32 wine64 wine32-tools -type l -ls | grep '-> /root/'


At the moment of writing, there are two links that need to be changed, the ones that the 64-bit build uses to refer to the 32-bit build:

 wine64/loader/wine -> /root/wine-dir/wine32/loader/wine
 wine64/loader/wine-preloader -> /root/wine-dir/wine32/loader/wine-preloader

We change them inside the container:

 # cd /root/wine-dir
 # rm wine64/loader/wine wine64/loader/wine-preloader
 # ln -s ../../wine32/loader/wine wine64/loader/wine
 # ln -s ../../wine32/loader/wine-preloader wine64/loader/wine-preloader

Install runtime dependencies in the host system

Wine requires access to some dynamic system libraries to run.

As mentioned in the Building_Wine#Runtime_Dependencies section of the Building Wine page, the easiest way to achieve this is to install the wine package provided by the distribution in the host system:

 $ apt install wine

Keep in mind that the wine command will execute the version of wine that this package installs, and not the one you build.

You may also want to install optional runtime dependencies such as:

 $ apt install corefonts

Run wine

You should be able to run wine from your build now, remember to use it with a prefix.

 $ PREFIX=$HOME/wine-dir/wine-prefix $HOME/wine-dir/wine64/wine --version

We can stop the container now

 lxc stop wine-container

Pushing and pulling files from the container without a shared directory

If you don't want to set up a shared directory between the host and the container, an alternative is to use the lxc file push and lxc file pull commands to send and retireve files from the container.

The syntax is:

 lxc file push -r <host-src-directory> wine-container/root/<container-dst-directory>
 lxc file pull -r wine-container/root/<container-dst-directory> <host-dst-directory>

Keep in mind that symbolic links end up invalid in the host system after pulling, because lxc file pull makes their paths absolute and respective to the container filesystem. Check the symbolic links using:

 $ find <pulled-directory> -type l -ls

We can fix them running the following link_fixer.sh script in the same folder we pulled the directory.

#!/bin/bash

PULLED_DIRECTORIES="$@"

find $PULLED_DIRECTORIES -type l | while read symlink; do
    if [ ! -e "$symlink" ]; then
        old_path=$(readlink "$symlink")
        # Remove the '/root/' prefix and change it with the current path ${PWD}
        new_path=${old_path/\/root\//${PWD}\/}
        new_path=$(realpath --relative-to="$(dirname "$symlink")" "$new_path")
        ( set -x; ln -f -s "$new_path" "$symlink")
    fi
done
 $ bash link_fixer.sh <host-dst-directory>
This page was last edited on 30 March 2023, at 00:53.