24th of March 2022
**
Introduction**
This document describes how to build and install Darling, a MacOS emulator for Linux, on OpenSUSE Leap 15.4 Beta. Darling can be considered to be the ‘Wine’ for MacOS applications. The current build instructions are only for OpenSUSE Tumbleweed, but I wanted to try it for a different version. Ideally, I would have liked to use the current stable version of Leap, which is 15.3, but I ran into some build issues that I could not resolve, and that did not occur after I switched over to Leap 15.4. I decided that Leap 15.4 was the best compromise I could make at this point, because I wanted to avoid the frequent, large, and usually daily updates one has with Tumbleweed, on the machine I am using for this.
These instructions could potentially be useful for other RPM-based Linux distros as well.
Note that this is a long exercise, and even though at the end of it I did manage to get a successful build and install, and was able to run the Darling shell and load the Darling kernel module, I ran into a known bug that prevented me from installing any MacOS applications. (More information about this later in this document.) This for me was a blocker, and I hope that it gets fixed soon. This kind of thing is only to be expected of Alpha software that is still at version 0.1.
Regardless, the advice I have seen online is that previous versions of Darling were working, and one should just build an older version. I would need some guidance as to which branch I should check out to do that. I initially just followed the build instructions and cloned the latest version of the master branch.**
What Doesn’t Work**
The first thing I would advise you not to do, and the first thing I tried, is to try building Darling from source on Leap 15.3. After I had resolved and installed the dependencies, I ran into a linker error where the linker was finding a 64-bit library instead of the 32-bit version, even though both were present. I am not sure what was wrong, but fixing this would probably require modifications to the Makefile, which is tricky to do, and I didn’t have the time to do it. As I was doing this on a relatively fresh install of Leap 15.3, I decided to switch over to Leap 15.4 and try again, and if that still didn’t work, I would just revert back to 15.3. Fortunately, this problem didn’t appear under 15.4, and I had a lot more success with that version.
The next thing I tried was to install Darling from the .deb files, even though OpenSUSE is an RPM-based distro. To do that, I needed to install two tools:
sudo zypper in dpkg dkms
You can download these here, if you wish:
https://github.com/darlinghq/darling/releases
Then I tried:
sudo dpkg --force-all -i darling-dkms_0.1.20220125.focal_amd64.deb
And got the following build error:
In file included from /var/lib/dkms/darling-mach/0.1/build/lkm/osfmk/mach/vm_param.h:79:0,
from /var/lib/dkms/darling-mach/0.1/build/lkm/osfmk/mach/mach_types.h:115,
from /var/lib/dkms/darling-mach/0.1/build/lkm/osfmk/kern/clock.h:38,
from /var/lib/dkms/darling-mach/0.1/build/lkm/osfmk/kern/sched_prim.h:72,
from /var/lib/dkms/darling-mach/0.1/build/lkm/osfmk/ipc/ipc_entry.c:76:
/var/lib/dkms/darling-mach/0.1/build/lkm/libkern/os/overflow.h:66:3: error: #error os_overflow expects type-generic builtins
# error os_overflow expects type-generic builtins
^~~~~
This error is apparently caused by an incorrect version (too old) of glibc. (I actually tried running this again after I had the correct version installed – see the next section - but I still got the same error message.)
Then I tried this:
sudo dpkg --force-all -i darling_0.1.20220125.focal_amd64.deb
And I got this:
(Reading database ... 46105 files and directories currently installed.)
Preparing to unpack darling_0.1.20220125.focal_amd64.deb ...
>>> Shutting down old instances of Darling
Seeing if Darling is currently running
No instances running now
Unpacking darling (0.1.20220125~focal) over (0.1.20220125~focal) ...
dpkg: darling: dependency problems, but configuring anyway as you requested:
darling depends on libc6 (>= 2.14); however:
Package libc6 is not installed.
darling depends on libc6-i386 (>= 2.3); however:
Package libc6-i386 is not installed.
darling depends on libavcodec58; however:
Package libavcodec58 is not installed.
darling depends on libavformat58; however:
Package libavformat58 is not installed.
darling depends on libavutil56; however:
Package libavutil56 is not installed.
darling depends on libcairo2 (>= 1.2.4); however:
Package libcairo2 is not installed.
darling depends on libdbus-1-3 (>= 1.9.14); however:
Package libdbus-1-3 is not installed.
darling depends on libegl1; however:
Package libegl1 is not installed.
darling depends on libfontconfig1 (>= 2.12.6); however:
Package libfontconfig1 is not installed.
darling depends on libfreetype6 (>= 2.2.1); however:
Package libfreetype6 is not installed.
darling depends on libfuse2 (>= 2.2); however:
Package libfuse2 is not installed.
darling depends on libgif7 (>= 5.1); however:
Package libgif7 is not installed.
darling depends on libgl1; however:
Package libgl1 is not installed.
darling depends on libglu1-mesa | libglu1; however:
Package libglu1-mesa is not installed.
Package libglu1 is not installed.
darling depends on libjpeg8 (>= 2.0); however:
Package libjpeg8 is not installed.
darling depends on libpng16-16 (>= 1.6.2-1); however:
Package libpng16-16 is not installed.
darling depends on libpulse0 (>= 0.99.1); however:
Package libpulse0 is not installed.
darling depends on libswresample3 (>= 7:4.0); however:
Package libswresample3 is not installed.
darling depends on libtiff5 (>= 4.0.3); however:
Package libtiff5 is not installed.
darling depends on libx11-6; however:
Package libx11-6 is not installed.
darling depends on libxcursor1 (>> 1.1.2); however:
Package libxcursor1 is not installed.
darling depends on libxext6; however:
Package libxext6 is not installed.
darling depends on libxkbfile1 (>= 1:1.1.0); however:
Package libxkbfile1 is not installed.
darling depends on libxrandr2; however:
Package libxrandr2 is not installed.
darling depends on fuse; however:
Package fuse is not installed.
darling depends on darling-dkms; however:
Package darling-dkms is not configured yet.
Setting up darling (0.1.20220125~focal) ...
>>> Shutting down old instances of Darling
Seeing if Darling is currently running
No instances running now
But I couldn’t run ‘darling’, it didn’t install. This was highly useful information though; it gave me a list of all of the dependencies!
You can also run:
dpkg -I darling_0.1.20220125.focal_amd64.deb
Which gives:
Depends: libc6 (>= 2.14), libc6-i386 (>= 2.3), libavcodec58, libavformat58, libavutil56, libcairo2 (>= 1.2.4), libdbus-1-3 (>= 1.9.14), libegl1, libfontconfig1 (>= 2.12.6), libfreetype6 (>= 2.2.1), libfuse2 (>= 2.2), libgif7 (>= 5.1), libgl1, libglu1-mesa | libglu1, libjpeg8 (>= 2.0), libpng16-16 (>= 1.6.2-1), libpulse0 (>= 0.99.1), libswresample3 (>= 7:4.0), libtiff5 (>= 4.0.3), libx11-6, libxcursor1 (>> 1.1.2), libxext6, libxkbfile1 (>= 1:1.1.0), libxrandr2, fuse, darling-dkms
Just a note about the dpkg –force-all switch, from the man page:
Warning: These options are mostly intended to be used by experts only. Using them without fully understanding their effects may break your whole system.
So, be warned about that! I had no problems, but, before trying that, as this was a relatively fresh installation of OpenSUSE, I thought that if the worst came to the worst, I would just reinstall the OS from my boot stick.
Prerequisites
On OpenSUSE, first ensure that you have the following patterns installed: Base Development Pattern, C++ Development Pattern, as well as the Linux Kernel Development Pattern, the latter is mostly for the kernel-source package, which you will need to build the Linux kernel module. Probably the easiest way to do this is from the Patterns section of the YaST Software manager.
You can find some of the prerequisites here:
https://docs.darlinghq.org/build-instructions.html
Install all of the Tumbleweed dependencies.
There are more here:
But note that, even if you use both of these, you still won’t get all of the dependencies. Darling emulates both 64-bit and 32-bit MacOS applications, and so, you need to install both the 64-bit and the 32-bit versions of all of the libraries. I used the list of dependencies in the previous section, together with the YaST Software manager, to search for and manually check that all of the dependencies were installed, and install the ones that weren’t. A complication is that Debian packages have different naming conventions than RPM-based ones; for example, ‘libc6’ is ‘glibc’ in OpenSUSE. You will also find packages with ‘i386’ in the name which means you need to install the 32-bit package.
The final dependency you need to build manually. Leap 15.4 ships with version 2.13 of glibc, (and that’s not likely to change), but the minimum requirement for the Linux kernel module is version 2.14. It is possible to have more than one version of glibc installed and working on the same operating system at the same time.
So, from:
https://www.gnu.org/software/libc/sources.html
https://www.gnu.org/software/libc/manual/html_node/Configuring-and-compiling.html
Do the following:
git clone https://sourceware.org/git/glibc.git
cd glibc
git checkout release/2.32/master
Make a new directory to install this version of glibc, for example:
sudo mkdir /usr/local/libcompat
Then:
mkdir build
cd build
../configure --prefix=/usr/local/libcompat
make
sudo make install
Then, create a new file in etc/ld.so.conf.d/, for example:
sudo vi /etc/ld.so.conf.d/glibc.conf
Containing the path to the new directory above, like so:
/usr/local/libcompat
Save the file, then run:
sudo ldconfig
This tells the linker where to find your new glibc library.
Build and Install Procedure
The entire build and install process is a long one. On an Intel Core i5 processor with four cores running at 2.4Ghz, it took longer than twenty-four hours. So, be prepared for that!
Cloning the Repo
According to the build instructions, you should do it this way:
git clone --recursive https://github.com/darlinghq/darling.git
However, be aware that this is a very large repo, and your clone process may time out because of that. If a git clone operation times out, there is no way to resume it from where it left off. You have to run the whole clone process again. So, before you do that, I advise you to first set the following environment variables:
export GIT_HTTP_LOW_SPEED_LIMIT=0
export GIT_HTTP_LOW_SPEED_TIME=1000
If you frequently clone very large repos, it might be a good idea to set these in your .bash_rc as well.
Source Code Changes
In the file: darling/src/external/lkm/libkern/os/overflow.h
Locate the following code:
#if __has_builtin(__builtin_add_overflow) && \
__has_builtin(__builtin_sub_overflow) && \
__has_builtin(__builtin_mul_overflow)
Delete it, and replace it with:
#if true
This issue was reported here:
https://github.com/darlinghq/darling/issues/1012
Then, in the file darling/src/external/lkm/osfmk/duct/duct_kern_thread_call.c
Locate the following code:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
if (atomic_long_read(&call->tc_work.work.data) & (WORK_STRUCT_PENDING | WORK_STRUCT_INACTIVE))
#else
if (atomic_long_read(&call->tc_work.work.data) & (WORK_STRUCT_PENDING | WORK_STRUCT_DELAYED))
#endif
Delete the first line, and replace it with:
#if true
There is something funny with this kernel version check, because WORK_STRUCT_DELAYED is not defined in my kernel headers.
The kernel I am running at the moment is:
uname -a
Linux localhost.localdomain 5.14.21-150400.11-default #1 SMP PREEMPT_DYNAMIC Wed Mar 2 08:27:22 UTC 2022 (0cc030f) x86_64 x86_64 x86_64 GNU/Linux
The Build and Install
Then, assuming that I have documented this correctly, and also that I haven’t missed any necessary steps, and you have followed all of my instructions correctly; you should now be ready for a problem-free build and installation process.
According to the build instructions:
# Move into the cloned sources
$ cd darling
# Make a build directory
$ mkdir build && cd build
# Configure the build
$ cmake ..
# Build and install Darling
$ make
$ sudo make install
And then, to build and install the Linux kernel module:
$ make lkm
$ sudo make lkm_install
A problem I encountered is that after every kernel upgrade, you will have to run the:
$ sudo make lkm_install
step again. So, be aware of that!
You should now be able to play around a bit, according to these instructions: