Compiling Wine 1.9 from scratch on macOS with Retina mode

Posted

Updated

28 Oct 2016

I have been using WineBottler to run my favorite Windows applications in macOS. Here, I describe how I compiled Wine from scratch and configure for my MacBook Pro's Retina Display.

Wine, starting from version 1.9.10 (May 17, 2016), has a new, experimental option for macOS Retina displays. This may not work that well yet, as more work in needed for Wine to support DPI Scaling like in Windows 8.1+

So, I wanted to:

  • Compile the latest Wine 1.9.21 (WineBottler is on Wine 1.8).
  • Compile without X11 (or the XQuartz implementation).
  • Enable Wine's "Retina Mode".
  • Use the latest Xcode 8.0 (8A218a) on macOS Sierra 11.2.
  • Do it all from scratch without Homebrew
  • Configure Wine without resorting to WineTricks
  • Run Microsoft Word 2010 32-bit to test it all.

Updated 26 Oct:

This took me weeks to figure out, since I'm no UNIX or macOS expert and could not find any tutorials to help me. But I found the WineBottler source code, specifically the build_wine.sh file to be a great starting point.

I have to commend and thank the creator of WineBottler, portions of the code below (especially for Samba) are based on or directly copied from, his code.

To summarize, my motivation is to test Wine's "Retina Mode" without X11, by minimally running MS Word 2010 and Notepad++. I don't know, but it's possible that more that that maynot work!

Environment setup

First, you'll need to install Xcode (free on the Mac App Store) and set up the environment to compile source code. If you've never run Xcode before, then you must run it once to accept the license agreement. Or, just run this in shell (i.e. Terminal):

sudo xcodebuild -license

I created a directory, ~/Downloads/wine, to compile and run Wine and its dependencies, without installing or touching any files outside this folder. The compiled files are in ~/Downloads/wine/usr:`` sd sdf sdf

mkdir ~/Downloads/wine
cd ~/Downloads/wine
mkdir usr
mkdir usr/lib
mkdir usr/bin
mkdir usr/include
export TARGET=$(PWD)
export CPPFLAGS="-I$TARGET/usr/include"
export CFLAGS="-O2 -arch i386 -m32 -I$TARGET/usr/include"
export CXXFLAGS="$CFLAGS "
export LDFLAGS=" -arch i386 -L$TARGET/usr/lib"
export PATH="$TARGET/usr/bin:$PATH"
export PKG_CONFIG_PATH="$TARGET/usr/lib/pkgconfig"
Compile dependencies

Then, download and compile the required library libpng and freetype. I didn't bother with harfbuzz, which has acyclic dependency with freetype itself:

curl -L http://ijg.org/files/jpegsrc.v9b.tar.gz -o jpegsrc.v9b.tar.gz
tar xf jpegsrc.v9b.tar.gz
cd jpeg-9b
./configure --prefix=$TARGET/usr
make install
cd ..

curl -L http://downloads.sourceforge.net/project/libpng/libpng16/1.6.25/libpng-1.6.25.tar.gz -o libpng-1.6.25.tar.gz
tar xf libpng-1.6.25.tar.gz
cd libpng-1.6.25
./configure --prefix=$TARGET/usr
make install
cd ..

curl -L http://download.savannah.gnu.org/releases/freetype/freetype-2.7.tar.gz -o freetype-2.7.tar.gz
tar xf freetype-2.7.tar.gz
cd freetype-2.7
./configure --prefix=$TARGET/usr
make install
cd ..
Compile Samba

Compiling Samba is a bit of a pain:

  • I'm not sure what I'm doing wrong, but it compiles to expect libraries in bin folder relative to where you are running the prgorams from. So a few steps are needed to re-point the libraries to the correct aboslute folder.
  • Plus, macOS does not honor LD_LIBRARY_PATH and DYLD_FALLBACK_LIBRARY_PATH environment variables.
  • And, the latest version Samba has changed quite a bit and I can't be bothered to figure it out, so I'll use 3.6 instead.
curl https://ftp.samba.org/pub/samba/samba-3.6.25.tar.gz -o samba-3.6.25.tar.gz
tar xvf samba-3.6.25.tar.gz
cd samba-3.6.25/source3
./configure --enable-shared --disable-static --disable-largefile --disable-swat --disable-smbtorture4 --disable-cups --disable-pie --disable-relro --disable-external-libtalloc --disable-external-libtdb --disable-fam --disable-dnssd --disable-avahi --without-dmapi --without-ldap --without-dnsupdate --without-pam --without-pam_smbpass --without-utmp --without-cluster-support --without-acl-support --without-sendfile-support --with-included-popt --with-included-iniparser --with-winbind --prefix=$TARGET/usr
make install
cd ..

You can look at the dependencies using the command otool -L bin\ntlm_auth and you'll see something like this:

ntlm_auth:
 /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)
 /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
 bin/libtalloc.dylib.2 (compatibility version 0.0.0, current version 0.0.0)
 bin/libtevent.dylib.0 (compatibility version 0.0.0, current version 0.0.0)
 bin/libtdb.dylib.1 (compatibility version 0.0.0, current version 0.0.0)
 bin/libwbclient.dylib.0 (compatibility version 0.0.0, current version  .0.0)
 /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)

So to change the relative paths:

cd bin
install_name_tool -change bin/libtalloc.dylib.2 @loader_path/../lib/libtalloc.dylib.2 ntlm_auth
install_name_tool -change bin/libtevent.dylib.0 @loader_path/../lib/libtevent.dylib.0 ntlm_auth
install_name_tool -change bin/libtdb.dylib.1 @loader_path/../lib/libtdb.dylib.1 ntlm_auth
install_name_tool -change bin/libwbclient.dylib.0 @loader_path/../lib/libwbclient.dylib.0 ntlm_auth
cd ../lib
install_name_tool -change bin/libtalloc.dylib.2 @loader_path/../lib/libtalloc.dylib.2 libtevent.dylib
install_name_tool -change bin/libtevent.dylib.0 @loader_path/../lib/libtevent.dylib.0 libtevent.dylib
cd ..

I'm only changing ntlm_auth because Word uses that to authenticate the activation license, but one should really fix all executables and libraries.

If you don't change the path correctly, you'll see errors like this if you run wine from the Terminal:

dyld: Library not loaded: bin/libtalloc.dylib.2
 Referenced from: /Users/[user]/Downloads/wine/usr/bin/ntlm_auth
 Reason: image not found
err:winediag:SECUR32_initNTLMSP ntlm_auth was not found or is outdated. Make sure that ntlm_auth >= 3.0.25 is in your path. Usually, you can find it in the winbind package of your distribution.
Complie Wine

Next, download and compile Wine (32-bit) itself:

curl http://dl.winehq.org/wine/source/1.9/wine-1.9.21.tar.bz2 -o wine-1.9.21.tar.bz2
tar xvf wine-1.9.21.tar.bz2
cd wine-1.9.21
./configure --prefix=$TARGET/usr --enable-win16 --disable-win64 --without-x 

At the end, you'll notice warnings because of missing but optional dependecies, e.g.:

configure: QuickTime 32-bit development files not found, video decoding won't be supported.
configure: libsane 32-bit development files not found, scanners won't be supported.
configure: libv4l 32-bit development files not found.
configure: libgphoto2 32-bit development files not found, digital cameras won't be supported.
configure: libgphoto2_port 32-bit development files not found, digital cameras won't be auto-detected.
configure: liblcms2 32-bit development files not found, Color Management won't be supported.
configure: libpulse 32-bit development files not found or too old, Pulse won't be supported.
configure: gstreamer-1.0 base plugins 32-bit development files not found, gstreamer support disabled
configure: OSS sound system found but too old (OSSv4 needed), OSS won't be supported.
configure: libudev 32-bit development files not found, plug and play won't be supported.
configure: libcapi20 32-bit development files not found, ISDN won't be supported.
configure: libgsm 32-bit development files not found, gsm 06.10 codec won't be supported.
configure: libtiff 32-bit development files not found, TIFF won't be supported.
configure: openal-soft 32-bit development files not found (or too old), XAudio2 won't be supported
configure: WARNING: gettext tools not found (or too old), translations won't be built.
configure: WARNING: libjpeg 32-bit development files not found, JPEG won't be supported.

You could compile all libraries for full functionality, search and download the libraries in the list above plus more, including:

  • mpg123
  • libusb and libusb-compat
  • unixODBC

Finally, build Wine. Sit back and wait, this will take a while:

make install
Start and Configure Wine

At this point you could start Wine by running the configuration tool. The first time wine is run it'll also prompt you to download and install:

  • Wine Gecko - implements "Internet Explorer" using Mozilla's Gecko engine (used in Firefox)
  • Wine Mono - .NET via the open-source, cross-platform Mono (although you could replace this with Microsoft .NET).

Wine Installing Gecko alternative to Internet Explorer

To run the configuration tool:

cd ~/Downloads/wine/usr/bin
./winecfg

You'll notice the text in the Wine Configuration tool is rather blurry. To improve on the blurry text, you could:

  • Enable Font Smoothing (a.k.a. ClearType in Windows), and
    • Replacing the default Tahoma font with a better font for small text under the Desktop Integration tab, or
    • Replacing the default Tahoma font with MS Sans Serif (which is better for small text IMHO) in the registry.
  • Enable Wine's "Retina Mode" which is my goal.
Enable Retina Mode

First, enable Font Smoothing, by run ./regedit to edit the following key:

[HKEY_CURRENT_USER\Control Panel\Desktop]
"FontSmoothing"="2"
"FontSmoothingType"=dword:00000002
"FontSmoothingGamma"=dword:00000578
"FontSmoothingOrientation"=dword:00000001

Where:

  • FontSmoothing - 0 = disabled, 2 = enabled
  • FontSmoothingType - 1 = regular, 2 = sub-pixel
  • FontSmoothingOrientation - 0 = BGR, 1 = RGB
  • FontSmoothingGamma - I'm not sure about this as I can't find it properly documented, could be 0 (heavier) to 2200 (finer)

Then, edit this key to enable "Retina Mode":

[HKEY_CURRENT_USER\Software\Wine\Mac Driver]
"RetinaMode"="y"

Now, run ./winecfg again and you'll see a super tiny window! Yup, we are now using retina mode!

Wine Configuration with Retina Mode enabled at 96 dpi

Go to the Graphics tab to set Screen resolution to 220 dpi. That's because my 13" MacBook Pro with Retina Display has a native resolution of 2560x1600, while a 15" model is 2880x1800 instead. In both cases, 220 DPI is about right.

Exit and run it again, you get reasonably sized text but notice some components like icons and the system menu aren't quite right.

Finally, start Word

I already had Word installed in a specific Wine folder. By default Wine will use ~/.wine to store it's settings, the Windows registry, and the contents of the virtual C: drive as seen by Windows.

You can change this to a different folder by setting the WINEPREFIX, which you can read about on the [Wine FAQ](https://wiki.winehq.org/FAQ#Wineprefixes.

So, to start Wine (assuming it's in your path, which was set up previously):

export WINEPREFIX=~/Downloads/wine/office
winefile

Then, I just ran Word, which was installed in C:\Program Files\Microsoft Office\Office14\winword.exe

Wow, it works and fonts look great, but icons look terrible! Plus, text does not render quite right and all icons including those in check boxes, tree views, etc. are tiny.

Here is word without retina mode (click for larger image):

Wine without Retina Mode running Word

And with Retina Mode (click for larger image):

Wine with Retina Mode running Word

If you run the Command Prompt (wineconsole), you'll also notice it's tiny. That can be fixed by right-clicking, selecting Properties > Font and changing the font Size to at least 28.

Wine Console Font Size for Retina Mode

Updated 26 Oct: Changed from @executable_path to @loader_path because a couple of libraries did not have enough header space for @executable_path, so swapped to @loader_path throughout. From what I've learnt, you have four options:

  • absolute paths - only for when the library is installed in a known location
  • @executable_path - relative to the calling executable itself
  • @loader_path (OS X 10.4+) - relative to the calling library or executable (in the latter case, will be same as @executable_path)
  • @rpath (OSX 10.5+) - searches in one or more paths as specified in the library or executable itself using the command install_name_tool -add_rpath (this is default for Wine)

Updated 28 Oct: Added libjpeg, think Word needs it, otherwise some Ribbon items are not displayed.