Mac OS X cross toolchain for Linux, FreeBSD, OpenBSD and Android (Termux)
Go to file
Thomas Pöchtrager fd32ecc6e0
Merge pull request #424 from nicksherron/package_name_fix
Fix misnamed "packet manager" to "package manager"  in docs
2024-06-27 08:19:16 +02:00
oclang Undo accidental change 2023-08-17 18:58:50 +02:00
patches Fix building GCC with 10.15 SDK 2019-09-14 11:38:18 +02:00
tarballs New: 2019-06-01 19:57:44 +02:00
tools Fix misnamed "packet manager" to "package manager" in docs 2024-06-26 19:49:41 -04:00
wrapper Add '__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__' compatiblity quirks for MacOS >= 14 SDKs 2023-08-17 22:44:57 +02:00
.gitignore Update cctools to 886 and ld64 to 264.3.102 2016-06-25 12:44:41 +02:00
AUTHORS add osxcross-macports - a minimalistic macports packet manager for 16.000+ binary packages 2014-12-24 10:52:24 +01:00
build_apple_clang.sh Update build_clang.sh: 2023-08-19 22:14:10 +02:00
build_binutils.sh Support non-x86_64 targets for binutils 2022-07-28 09:48:49 -04:00
build_clang.sh Fix CLANG_LLVM_PKG check in build_clang.sh 2023-09-16 14:59:38 +02:00
build_compiler_rt.sh Support both short and full SDK version naming (e.g., 14 and 14.0) (closes #377) 2023-08-17 21:52:37 +02:00
build_gcc.sh Support extracting MacOS 13.x and MacOS 14.x SDKs. 2023-08-17 18:55:09 +02:00
build_llvm_dsymutil.sh New: 2019-06-01 19:57:44 +02:00
build.sh Add support for MacOSX SDKs 14.2, 14.4 and 14.5 SDKs 2024-06-19 15:15:17 +02:00
CHANGELOG Fix misnamed "packet manager" to "package manager" in docs 2024-06-26 19:49:41 -04:00
cleanup.sh xcrun: 2015-06-27 19:01:56 +02:00
COPYING xcrun: 2015-06-27 19:01:56 +02:00
KNOWN_BUGS.md Update KNOWN_BUGS.md 2015-08-29 12:56:40 +02:00
package.sh Fix package.sh trying to include a deleted file. 2019-05-28 08:05:51 +00:00
README.COMPILER-RT.md compiler-rt: Add option to automate install process 2021-07-12 13:34:37 +02:00
README.DEBUGGING.md * Update README 2020-08-17 19:19:47 +02:00
README.MACPORTS.md Fix misnamed "packet manager" to "package manager" in docs 2024-06-26 19:49:41 -04:00
README.md Fix misnamed "packet manager" to "package manager" in docs 2024-06-26 19:49:41 -04:00
README.PKG-CONFIG.md Misc pkg-config adjustments (closes #69) 2016-03-29 20:16:54 +02:00
TODO Update TODO 2016-02-27 09:35:19 +01:00

macOS Cross toolchain for Linux and *BSD

WHAT IS THE GOAL OF OSXCROSS?

The goal of OSXCross is to provide a well working macOS cross toolchain for
Linux, FreeBSD, OpenBSD, and Android (Termux).

OSXCross works on x86, x86_64, arm and AArch64/arm64,
and is able to target arm64, arm64e, x86_64, x86_64h and i386.

arm64 requires macOS 11.0 SDK (or later).
arm64e requires a recent Apple clang compiler.

There is also a ppc test branch that has recently seen some daylight.

HOW DOES IT WORK?

For cross-compiling for macOS you need

  • the Clang/LLVM compiler
  • the cctools (lipo, otool, nm, ar, ...) and ld64
  • the macOS SDK.

Clang/LLVM is a cross compiler by default and is now available on nearly every Linux distribution, so we just need a proper port of the cctools/ld64 and the macOS SDK.

OSXCross includes a collection of scripts for preparing the SDK and building the cctools/ld64.

It also includes scripts for optionally building

  • Clang using gcc (for the case your distribution does not include it),
  • an up-to-date vanilla GCC as a cross-compiler for target macOS,
  • the "compiler-rt" runtime library, and
  • the llvm-dsymutil tool required for debugging.

Note: The "compiler-rt" library can be needed to link code that uses the __builtin_available() runtime version check.

WHAT CAN BE BUILT WITH IT?

Basically everything you can build on macOS with clang/gcc should build with this cross toolchain as well.

PACKAGE MANAGERS

OSXCross comes with a minimalistic MacPorts Package Manager. See README.MACPORTS for more.

INSTALLATION:

Move your packaged SDK to the tarballs/ directory.

Then ensure you have the following installed on your system:

Clang 3.9+, cmake, git, patch, Python, libssl-dev (openssl) lzma-dev, libxml2-dev, xz, bzip2, cpio, libbz2, zlib1g-dev and the bash shell.

You can run 'sudo tools/get_dependencies.sh' to get these (and the optional packages) automatically. (outdated)

Optional:

  • llvm-devel: For Link Time Optimization support
  • llvm-devel: For ld64 -bitcode_bundle support
  • uuid-devel: For ld64 -random_uuid support

On Ubuntu trusty you must upgrade CMake to >= 3.2.3 first. Or do this:

    curl -sSL https://cmake.org/files/v3.14/cmake-3.14.5-Linux-x86_64.tar.gz | sudo tar -xzC /opt
    export PATH=/opt/cmake-3.14.5-Linux-x86_64/bin:$PATH
Building Clang

OSXCross uses clang as the default compiler for building its tools, and also as a cross-compiler to create macOS binaries.

In clang there is no difference between cross-compilation and native compilation, so OSXCross can use a normal clang install for both. You can use either a clang installation you already have, or build your own from source.

To build and install your own clang from a recent source tree, using gcc, run:

    ./build_clang.sh # Builds a mainline version of Clang
    ./build_apple_clang.sh # Builds Apple's version of Clang

This installs clang into /usr/local. If you want to install somewhere else, set the INSTALLPREFIX variable. For example:

    INSTALLPREFIX=/opt/clang ./build_clang.sh
Building OSXCross

To build the cross toolchain (using clang), run:

    ./build.sh

This installs the osxcross toolchain into <path>/target. If you want to install somewhere else, set the TARGET_DIR variable. For example:

    TARGET_DIR=/usr/local/osxcross ./build.sh

And/Or, set variable UNATTENDED to 1 to skip the prompt and proceed straight to the build:

    UNATTENDED=1 ./build.sh

(This will search 'tarballs' for your SDK and then build in its own directory.)

Once this is done: add <path>/target/bin to your PATH variable so that you can invoke the cross-compiler.

That's it. See usage examples below.

Building GCC:

If you also want to build GCC as a cross-compiler, you can do that by running:

    ./build_gcc.sh

The script lets you select a GCC version by setting the variable GCC_VERSION. By default you get C and C++ compilers, but you can tell the script to build a Fortran compiler as well:

    GCC_VERSION=5.2.0 ENABLE_FORTRAN=1 ./build_gcc.sh
A gfortran usage example can be found [here](https://github.com/tpoechtrager/osxcross/issues/28#issuecomment-67047134)]

Before you do this, make sure you have the GCC build depedencies installed on
your system.

On debian like systems you can install these using:

```shell
    sudo apt-get install gcc g++ zlib1g-dev libmpc-dev libmpfr-dev libgmp-dev
```

ATTENTION:

OSXCross does not enable `-Werror=implicit-function-declaration` by default.  
You can emulate Xcode 12's behavior by setting the environmental variable  
`OSXCROSS_ENABLE_WERROR_IMPLICIT_FUNCTION_DECLARATION` to 1.

OSXCross links libgcc and libstdc++ statically by default (this affects
`-foc-use-gcc-libstdc++` too).  You can turn this behavior off with
`OSXCROSS_GCC_NO_STATIC_RUNTIME=1` (env).

The build also creates aliases `*-g++-libc++` which link with the `clang`
implementation of the C++ standard library instead of the GCC version.  Don't
use these variants unless you know what you're doing.

### PACKAGING THE SDK: ###

**[Please ensure you have read and understood the Xcode license
   terms before continuing.](https://www.apple.com/legal/sla/docs/xcode.pdf)**

The SDKs can be extracted either from full Xcode or from Command Line
Tools for Xcode.

##### Packaging the SDK on recent macOS (Xcode): #####

1. [Download Xcode: https://developer.apple.com/download/all/?q=xcode] \*\*
2. [Mount Xcode.dmg (Open With -> DiskImageMounter) \*\*\*]
3. Run: `./tools/gen_sdk_package.sh` (from the OSXCross package)
4. Copy the packaged SDK (\*.tar.\* or \*.pkg) on a USB Stick
5. (On Linux/BSD) Copy or move the SDK into the tarballs/ directory of
   OSXCross.

\*\*  
-- Xcode up to 15 Beta 6 is known to work.  
-- Use Firefox if you have problems signing in.

\*\*\*  
-- If you get a dialog with a crossed circle, ignore it.  
-- You don't need to install Xcode.

Step 1. and 2. can be skipped if you have Xcode installed.

##### Packaging the Xcode 4.2 SDK on Snow Leopard: #####
1. Install a recent version of Bash from MacPorts or Tigerbrew
2. Download Xcode 4.2 for Snow Leopard
3. Mount the disk image with DiskImageMounter or by running
  `hdiutil attach <xcode>.dmg`
4. Run: `XCODEDIR=/Volumes/Xcode ./tools/gen_sdk_package.sh`
5. (On Linux/BSD) Copy or move the SDK into the tarballs/ directory of
   OSXCross.

##### Packing the SDK on Linux - Method 1 (Xcode > 8.0): #####

This method may require up to 45 GB of free disk space.  
An SSD is recommended for this method.

1. Download Xcode like described in 'Packaging the SDK on macOS'
2. Install `clang`, `make`, `libssl-devel`, `lzma-devel` and `libxml2-devel`
3. Run `./tools/gen_sdk_package_pbzx.sh <xcode>.xip`
4. Copy or move the SDK into the tarballs/ directory

##### Packing the SDK on Linux - Method 2 (works up to Xcode 7.3): #####

1. Download Xcode like described in 'Packaging the SDK on macOS'
2. Install `cmake`, `libxml2-dev` and `fuse`
3. Run `./tools/gen_sdk_package_darling_dmg.sh <xcode>.dmg`
4. Copy or move the SDK into the tarballs/ directory

##### Packing the SDK on Linux (and others) - Method 3 (works up to Xcode 7.2): #####

1. Download Xcode like described in 'Packaging the SDK on macOS'
2. Ensure you have `clang` and `make` installed
3. Run `./tools/gen_sdk_package_p7zip.sh <xcode>.dmg`
4. Copy or move the SDK into the tarballs/ directory

##### Packing the SDK on Linux - Method 4 (works up to Xcode 4.2): #####

1. Download Xcode 4.2 for Snow Leopard
2. Ensure you are downloading the "Snow Leopard" version
3. Install `dmg2img`
4. Run (as root): `./tools/mount_xcode_image.sh /path/to/xcode.dmg`
5. Follow the instructions printed by `./tools/mount_xcode_image.sh`
6. Copy or move the SDK into the tarballs/ directory


##### Packaging the SDK from Xcode Command Line Tools on macOS: #####

1. [Download Xcode Command Line Tools: https://developer.apple.com/download/more] \*\*\*\*
2. [Mount Command_Line_Tools_for_Xcode.dmg (Open With -> DiskImageMounter)]
3. [Install "Command Line Tools.pkg" (Open With -> Installer)]
3. Run: `./tools/gen_sdk_package_tools.sh` (from the OSXCross package)
4. Copy the packaged SDK (\*.tar.\* or \*.pkg) on a USB Stick
5. (On Linux/BSD) Copy or move the SDK into the tarballs/ directory of
   OSXCross.

\*\*\*\*
-- Xcode command line tools 12.x are known to work.

Steps 1. to 3. can be skipped if you have Xcode Command line tools
already installed (e.g., auto-installed by running `git` or `gcc`
command from command-line).

##### Packing the SDK from from Xcode Command Line Tools on Linux: #####

This method may require up to 45 GB of free disk space.
An SSD is recommended for this method.

1. Download Xcode Command Line Tools like described in 'Packaging the SDK from Xcode Command Line Tools on macOS'
2. Install `clang`, `make`, `libssl-devel`, `lzma-devel` and `libxml2-devel`
3. Run `./tools/gen_sdk_package_tools_dmg.sh <command_line_tools_for_xcode>.dmg`
4. Copy or move the SDK into the tarballs/ directory


### USAGE EXAMPLES: ###

##### Example.  To compile a file called test.cpp, you can run: #####

##### x86 #####

* Clang:

  * 32 bit: `o32-clang++ test.cpp -O3 -o test` OR
    `i386-apple-darwinXX-clang++ test.cpp -O3 -o test`
  * 64 bit: `o64-clang++ test.cpp -O3 -o test` OR
    `x86_64-apple-darwinXX-clang++ test.cpp -O3 -o test`

* GCC:

  * 32 bit:  `o32-g++ test.cpp -O3 -o test` OR
    `i386-apple-darwinXX-g++ test.cpp -O3 -o test`
  * 64 bit:  `o64-g++ test.cpp -O3 -o test` OR
    `x86_64-apple-darwinXX-g++ test.cpp -O3 -o test`

##### ARM #####

* Clang:

  * arm64: `oa64-clang++ test.cpp -O3 -o test` OR
    `arm64-apple-darwinXX-clang++ test.cpp -O3 -o test`
  * arm64e: `oa64e-clang++ test.cpp -O3 -o test` OR
    `arm64e-apple-darwinXX-clang++ test.cpp -O3 -o test`


XX= the target version, you can find it out by running  `osxcross-conf` and
then see `TARGET`.

You can use the shortcuts `o32-...` for `i386-apple-darwin...`, depending on
which you prefer.

*I'll continue from here on with `o32-clang`, but remember,
 you can simply replace it with `o32-gcc` or `i386-apple-darwin...`.*

##### Building Makefile based projects: #####

  * `make CC=o32-clang CXX=o32-clang++`

##### Building automake based projects: #####

  * `CC=o32-clang CXX=o32-clang++ ./configure --host=i386-apple-darwinXX`

##### Building test.cpp with libc++: #####

Note: libc++ requires macOS 10.7 or later! If you really need C++11 for
an older macOS version, then you can do the following:

1. Build GCC so you have an up-to-date libstdc++
2. Build your source code with GCC or
   `clang++-gstdc++` / `clang++ -foc-use-gcc-libstdc++`

Usage Examples:

* Clang:

  * C++98: `o32-clang++ -stdlib=libc++ -std=c++98 test.cpp -o test`
  * C++11: `o32-clang++ -stdlib=libc++ -std=c++11 test1.cpp -o test`
  * C++14: `o32-clang++ -stdlib=libc++ -std=c++14 test1.cpp -o test`
  * C++17: `o32-clang++ -stdlib=libc++ -std=c++17 test1.cpp -o test`
  * C++2a: `o32-clang++ -stdlib=libc++ -std=c++20 test1.cpp -o test`

* Clang (shortcut):

  * C++98: `o32-clang++-libc++ -std=c++98 test.cpp -o test`
  * C++11: `o32-clang++-libc++ -std=c++11 test.cpp -o test`
  * C++14: `o32-clang++-libc++ -std=c++14 test.cpp -o test`
  * C++17: `o32-clang++-libc++ -std=c++17 test.cpp -o test`
  * C++2a: `o32-clang++-libc++ -std=c++20 test.cpp -o test`

* GCC

  * C++11: `o32-g++-libc++ -std=c++11 test.cpp`
  * C++14: `o32-g++-libc++ -std=c++14 test.cpp -o test`
  * C++17: `o32-g++-libc++ -std=c++17 test.cpp -o test`
  * C++2a: `o32-g++-libc++ -std=c++20 test.cpp -o test`

##### Building test1.cpp and test2.cpp with LTO (Link Time Optimization): #####

  * build the first object file: `o32-clang++ test1.cpp -O3 -flto -c`
  * build the second object file: `o32-clang++ test2.cpp -O3 -flto -c`
  * link them with LTO: `o32-clang++ -O3 -flto test1.o test2.o -o test`

##### Building a universal binary: #####

* Clang:
  * `o64-clang++ test.cpp -O3 -arch i386 -arch x86_64 -o test`
* GCC:
  * build the 32 bit binary: `o32-g++ test.cpp -O3 -o test.i386`
  * build the 64 bit binary: `o64-g++ test.cpp -O3 -o test.x86_64`
  * use lipo to generate the universal binary:
    `x86_64-apple darwinXX-lipo -create test.i386 test.x86_64 -output test`

### DEPLOYMENT TARGET: ###

The default deployment target is:  

SDK <= 10.13: `macOS 10.6`  
SDK >= 10.14: `macOS 10.9`

However, there are several ways to override the default value:

1. by passing `OSX_VERSION_MIN=10.x` to `./build.sh`
2. by passing `-mmacosx-version-min=10.x` to the compiler
3. by setting the `MACOSX_DEPLOYMENT_TARGET` environment variable

\>= 10.9 also defaults to `libc++` instead of `libstdc++`,  
this behavior can be overriden by explicitly passing `-stdlib=libstdc++` to clang.

x86\_64h defaults to `macOS 10.8` and requires clang 3.5+.  
x86\_64h = x86\_64 with optimizations for the Intel Haswell Architecture.

### PROJECTS USING OSXCROSS: ###

* [multiarch/crossbuild](https://github.com/multiarch/crossbuild):  
  various cross-compilers  
  (**Systems**: Linux, macOS, Windows, **Archs**: x86\_64,i386, arm, ppc, mips)  
  in Docker. OSXCross powers the Darwin builds.
* [Smartmontools](https://www.smartmontools.org)

### LICENSE: ####
  * scripts/wrapper: GPLv2
  * cctools/ld64: APSL 2.0
  * xar: New BSD

### CREDITS: ####
 * [cjacker for the initial cctools port](https://code.google.com/p/ios-toolchain-based-on-clang-for-linux/source/browse/#svn%2Ftrunk%2Fcctools-porting%2Fpatches)