Build for Old Mac OSX Versions
Do you want to support Mac OSX? My recommendation: Don’t! It’s not worth the pain! Really! Apple is the worst shit in the world, especially from a developer’s point of view.
Still here? So you must support Mac, then let’s try to go through these shoals. You will see, there are many little problems to solve.
One typical problem: you cannot cross compile from Linux to MacOSX, Mac builds must be compiled on a native Apple device. So you start by buying a Mac, unless you manage to run it in a virtual machine.
You need an AppleID with developer account to install Xcode. Then you install the Linux- / GNU-Tools using Homebrew, so you can finally build using
./configure && make all install based on a GNU
gcc, as you are used to do. Creating and signing an app and a dmg-Installer is another pain in the ass, that I won’t describe here. Finally you have a binary that runs on your Mac and you give it away, what happens? Your friend got your program, starts it and only sees an error message, stating that the his OSX version is too old to be supported by your program. So you need explicitly to build for older versions of OSX. I am currently running a build server on OSX 10.13, but the result should run at least on OSX 10.11 too. This blog describes how to do it.
Copy SDK Into Xcode
Your first step will be to install an old SDK into your current Xcode. For this you must download a whole old Xcode image, extract the SDK and manually copy it into your current Xcode app. And since Apple is so smart, you need to repeat this everytime you update Xcode.
What Version of Xcode?
Your first problem is to find out, what version of Xcode you need. Fortunately there is a table in the Wikipedia article. This tells me, that OSX 10.11 is supported by Xcode 7.3.1. So I downloaded 7.3.1 dmg from https://developer.apple.com/download/more. If you trust user phracker, you can get the SDK directly from his github project. There is also a XCodeLegacy script, which did not work for me, it did not finde the SDK.
Install 10.11 SDK in Xcode
Provided you have the Xcode 7.3.1 dmg, open it, then right-click on the Xcode package to oopen the popup-menu and chose «Show Package Contents» instead of simply «Open» it. Then open Contents / Developer / Platforms /MacOSX.platform / Developer / SDKs here you find a folder MacOSX10.11.sdk. In another finder window open Applications, then also here right-click on Xcode to «Show Package Content» and head to Contents / Developer / Platforms /MacOSX.platform / Developer / SDKs. Here you only see MacOSX10.13.sdk. So copy MacOSX10.11.sdk using drag and drop.
Enforce the use of the correct SDK:
sudo rm -rf /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk sudo ln -s /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk \ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
Use Mac Ports Instead of Homebrew
Next problem: How to get Homebrew built for the old deployment-target? Answer: You can’t! So forget Homebrew and uninstall it! Use MacPorts, where you can set a target in macports.conf.
Install MacPorts. Run
xcode-select --install to install the Xcode commandline tools and
sudo xcodebuild -license to accept the license. Then edit
/opt/local/etc/macports/macports.conf and append:
universal_target 10.11 macosx_deployment_target 10.11 macosx_sdk_version 10.11
To be completely sure to build for the right target, also set
export MACOSX_DEPLOYMENT_TARGET=10.11 in your
.profile and in the
.profile of user root.
port often simply copies a binary file. To make sure, everything is correctly rebuilt, you must use the option
-s to build from sources. Also make sure you don’t have unwanted caches,
port clean --all all is the safest way to get rid of all old files,
port uninstall installed removes everything that is already installed.
Then build something, e.g.
doxygen and test it:
$ sudo port -s install doxygen […] $ otool -l /opt/local/bin/doxygen \ | grep -B1 -A3 LC_VERSION_MIN_MACOSX Load command 9 cmd LC_VERSION_MIN_MACOSX cmdsize 16 version 10.11 sdk 10.11
Now you can set
export MACOSX_DEPLOYMENT_TARGET=10.11, build your dependencies, then append
mmacosx-version-min=10.11 to your builds.
You should see only success stories when you build your dependencies and check the built binaries:
$ sudo -Hi $ export MACOSX_DEPLOYMENT_TARGET=10.11 $ port -s -N -v install \ qt5 boost cppunit subversion doxygen \ wget emacs autoconf automake libtool \ pkgconfig pkcs11-helper libproxy $ for f in /opt/local/bin/*; do \ if otool -l $f \ | grep -B1 -A3 LC_VERSION_MIN_MACOSX \ | grep -q 10.11; then \ echo "success: $f"; \ else \ echo "* error: $f"; \ fi; done