|
| 1 | +# Mac OS X |
| 2 | + |
| 3 | +**Disclaimer**: _Currently, the following steps are tested and confirmed to work on Linux only._ |
| 4 | + |
| 5 | +## Use case |
| 6 | + |
| 7 | +Exporting for Mac OS X is interesting if: |
| 8 | + |
| 9 | +* you do not have access to Apple hardware |
| 10 | +* you want to build from a CI, typically on a Docker image |
| 11 | + |
| 12 | +If you have access to a real Mac, building natively is easier. |
| 13 | + |
| 14 | +## Why is this complex ? |
| 15 | + |
| 16 | +Cross-compiling Rust programs for Mac OS X is as simple as: |
| 17 | + |
| 18 | +```sh |
| 19 | +rustup target add x86_64-apple-darwin |
| 20 | +cargo build --target x86_64-apple-darwin |
| 21 | +``` |
| 22 | + |
| 23 | +However to build [gdnative-sys](https://crates.io/crates/gdnative-sys) you |
| 24 | +need a Mac OS X C/C++ compiler, the Rust compiler is not enough. More precisely you need |
| 25 | +an SDK which usually comes with [Xcode](https://developer.apple.com/xcode/). |
| 26 | +For Mac users, this SDK is "just there" but when cross-compiling, it is |
| 27 | +typically missing, even if your compiler is able to produce Mac OS X compatible binaries. |
| 28 | + |
| 29 | +The most common error is: |
| 30 | + |
| 31 | +``` |
| 32 | +fatal error: 'TargetConditionals.h' file not found |
| 33 | +``` |
| 34 | + |
| 35 | +Installing just this file is not enough, this error is usually a consequence |
| 36 | +of the whole SDK missing, so there is no chance you can get a build. |
| 37 | + |
| 38 | +What you need to do is: |
| 39 | + |
| 40 | +* download the SDK |
| 41 | +* fix all paths and other details so that it ressembles a Mac OS X environment |
| 42 | +* then build with `cargo build --target x86_64-apple-darwin` |
| 43 | + |
| 44 | +Hopefully, the first two steps, downloading the SDK and fixing details, |
| 45 | +are handled by a tool called [osxcross](https://github.com/tpoechtrager/osxcross) |
| 46 | +which is just about setting up a working C/C++ compiler on Linux. |
| 47 | + |
| 48 | +## Howto |
| 49 | + |
| 50 | +```sh |
| 51 | +# make sure you have a proper C/C++ native compiler first, as a suggestion: |
| 52 | +sudo apt-get install llvm-dev libclang-dev clang libxml2-dev libz-dev |
| 53 | + |
| 54 | +# change the following path to match your setup |
| 55 | +export MACOSX_CROSS_COMPILER=$HOME/macosx-cross-compiler |
| 56 | + |
| 57 | +install -d $MACOSX_CROSS_COMPILER/osxcross |
| 58 | +install -d $MACOSX_CROSS_COMPILER/cross-compiler |
| 59 | +cd $MACOSX_CROSS_COMPILER |
| 60 | +git clone https://github.com/tpoechtrager/osxcross && cd osxcross |
| 61 | + |
| 62 | +# picked this version as they work well with godot-rust, feel free to change |
| 63 | +git checkout 7c090bd8cd4ad28cf332f1d02267630d8f333c19 |
| 64 | +``` |
| 65 | + |
| 66 | +At this stage you need to [download and package the SDK](https://github.com/tpoechtrager/osxcross#packaging-the-sdk) |
| 67 | +which can not be distributed with osxcross for legal reasons. |
| 68 | +[Please ensure you have read and understood the Xcode license terms before continuing](https://www.apple.com/legal/sla/docs/xcode.pdf). |
| 69 | + |
| 70 | +You should now have an SDK file, for example `MacOSX10.10.sdk.tar.xz`. |
| 71 | + |
| 72 | +```sh |
| 73 | +# move the file where osxcross expects it to be |
| 74 | +mv MacOSX10.10.sdk.tar.xz $MACOSX_CROSS_COMPILER/osxcross/tarballs/ |
| 75 | +# build and install osxcross |
| 76 | +UNATTENDED=yes OSX_VERSION_MIN=10.7 TARGET_DIR=$MACOSX_CROSS_COMPILER/cross-compiler ./build.sh |
| 77 | +``` |
| 78 | + |
| 79 | +At this stage, you should have, in `$MACOSX_CROSS_COMPILER/cross-compiler`, |
| 80 | +a working cross-compiler. |
| 81 | + |
| 82 | +Now you need to tell Rust to use it when linking |
| 83 | +Mac OS X programs: |
| 84 | + |
| 85 | +```sh |
| 86 | +echo "[target.x86_64-apple-darwin]" >> $HOME/.cargo/config |
| 87 | +find $MACOSX_CROSS_COMPILER -name x86_64-apple-darwin14-cc -printf 'linker = "%p"\n' >> $HOME/.cargo/config |
| 88 | +echo >> $HOME/.cargo/config |
| 89 | +``` |
| 90 | + |
| 91 | +After this, your `$HOME/.cargo/config` (not the `cargo.toml` file in your project, this is a different file) |
| 92 | +should contain: |
| 93 | + |
| 94 | +```toml |
| 95 | +[target.x86_64-apple-darwin] |
| 96 | +linker = "/home/my-user-name/macosx-cross-compiler/cross-compiler/bin/x86_64-apple-darwin14-cc" |
| 97 | +``` |
| 98 | + |
| 99 | +Then, we need to also tell the compiler to use the right compiler and headers. |
| 100 | +In our example, with SDK 10.10, the env vars we need to export are: |
| 101 | + |
| 102 | +```sh |
| 103 | +C_INCLUDE_PATH=$MACOSX_CROSS_COMPILER/cross-compiler/SDK/MacOSX10.10.sdk/usr/include |
| 104 | +CC=$MACOSX_CROSS_COMPILER/cross-compiler/bin/x86_64-apple-darwin14-cc |
| 105 | +``` |
| 106 | + |
| 107 | +You probably do not want to export those permanently as they are very |
| 108 | +specific to building for Mac OS X so they are typically passed at each |
| 109 | +call to `cargo`, eg: |
| 110 | + |
| 111 | +```sh |
| 112 | +C_INCLUDE_PATH=$MACOSX_CROSS_COMPILER/cross-compiler/SDK/MacOSX10.10.sdk/usr/include CC=$MACOSX_CROSS_COMPILER/cross-compiler/bin/x86_64-apple-darwin14-cc cargo build --release --target x86_64-apple-darwin |
| 113 | +``` |
| 114 | + |
| 115 | +As a consequence, you do *not* need to put `$MACOSX_CROSS_COMPILER/cross-compiler/bin` in your `$PATH` if |
| 116 | +you only plan to export [godot-rust](https://github.com/godot-rust/godot-rust) based programs, as the |
| 117 | +binary needs to be explicitly overloaded. |
| 118 | + |
| 119 | +## Exporting |
| 120 | + |
| 121 | +Once your `.dylib` file is built, a standard Godot export should work: |
| 122 | + |
| 123 | +```sh |
| 124 | +godot --export "Mac OSX" path/to/my.zip |
| 125 | +``` |
| 126 | + |
| 127 | +Note that when exporting from a non Mac OS X platform, it is not possible to build a `.dmg`. |
| 128 | +Instead, a `.zip` is produced. Again, the tool required to build Mac OS X disk images is |
| 129 | +only available on Mac OS X. The `.zip` works fine though, it just contains `my.app` |
| 130 | +folder, ready to use. |
| 131 | + |
| 132 | +Double-check your `.dylib` file is there. |
| 133 | + |
| 134 | +## Useful links |
| 135 | + |
| 136 | +* https://github.com/tpoechtrager/osxcross : tool used to install the Mac OS X SDK on Linux |
| 137 | +* https://wapl.es/rust/2019/02/17/rust-cross-compile-linux-to-macos.html : a complete tutorial on how to use osxcross |
0 commit comments