From 2edaca2c249912e6b03eda73ed0bbffe72cd8f10 Mon Sep 17 00:00:00 2001 From: Dragos Daian Date: Mon, 8 Jul 2024 14:15:55 +0200 Subject: [PATCH] Create export-mac.md (#50) --- src/SUMMARY.md | 1 + src/toolchain/export-mac-and-ios.md | 323 ++++++++++++++++++++++++++++ 2 files changed, 324 insertions(+) create mode 100644 src/toolchain/export-mac-and-ios.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 4fd2986..73043c1 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -29,6 +29,7 @@ - [Debugging](toolchain/debugging.md) - [Export to Android](toolchain/export-android.md) - [Export to Web](toolchain/export-web.md) + - [Export to macOS and iOS](toolchain/export-mac-and-ios.md) - [Recipes](recipes/index.md) - [Custom resources](recipes/custom-resources.md) - [Editor plugins](recipes/editor-plugin/index.md) diff --git a/src/toolchain/export-mac-and-ios.md b/src/toolchain/export-mac-and-ios.md new file mode 100644 index 0000000..9174543 --- /dev/null +++ b/src/toolchain/export-mac-and-ios.md @@ -0,0 +1,323 @@ + + +# Export to macOS and iOS + +Mac libraries that are intended to be shared with other people require Code Signing and Notarization. For this you will need: + +- A Mac Computer +- An Apple ID enrolled in Apple Developer Program (99 USD per year) + +Without Code Signing and Notarization, the other person can still use the built library, but either needs to: + +- rebuild the whole thing locally +- re-sign it +- accept that it may contain malicious code. + +Prerequisites: + +- Download and install [Xcode](https://developer.apple.com/xcode/) on your Mac computer. + + +## Building macOS universal lib + + +Add both x64 and arm64 targets. This is needed in order to create a universal build. + +```sh +rustup target add x86_64-apple-darwin +rustup target add aarch64-apple-darwin +``` + +Build the library for both target architectures: + +```sh +cargo build --target=x86_64-apple-darwin --release +cargo build --target=aarch64-apple-darwin --release +``` + +Run the [lipo](https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary) tool +to merge the two in one universal library. + +```sh +lipo -create -output target/release/lib{YourCrate}.macos.dylib \ + target/aarch64-apple-darwin/release/lib{YourCrate}.dylib \ + target/x86_64-apple-darwin/release/lib{YourCrate}.dylib +``` + +The result of this will be the file `target/release/lib{YourCrate}.macos.dylib` that will now have support for both x64 and arm64 platforms. + +The user would need to replace `{YourCrate}` with the crate name. +The name of your library will be the one you provided in `Cargo.toml` file, prefixed with `lib` and followed by `.dylib`: + +```ini +[package] +name = "{YourCrate}" +``` + +Next, you will need to create the `.framework` folder. + +```sh +mkdir target/release/lib{YourCrate}.macos.framework +cp target/release/lib{YourCrate}.macos.dylib \ + target/release/lib{YourCrate}.macos.framework/lib{YourCrate}.macos.dylib +``` + +Next, create the `Info.plist` file inside the `Resources` folder: + +```sh +mkdir target/release/lib{YourCrate}.macos.framework/Resources +``` + +File contents: + +```xml + + + + + CFBundleExecutable + lib{YourCrate}.macos.dylib + CFBundleIdentifier + org.mywebsite.myapp + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + My App Name + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSupportedPlatforms + + MacOSX + + NSHumanReadableCopyright + Copyright (c)... + CFBundleVersion + 1.0.0 + LSMinimumSystemVersion + 10.12 + + +``` + +```admonish note title="XML format" +The `CFBundleExecutable` name **must** match the dylib file name. Some of the contents in the XML file **must** not contain some characters. +Generally avoid using anything other than letters and numbers. +Related [StackOverflow issue](https://stackoverflow.com/questions/3757817/plist-contains-the-character). +``` + +Edit the project's `.gdextension` file to include support for macOS. +This file will probably be at `godot/{YourCrate}.gdextension`. +The format will be similar to the following: + +```ini +[libraries] +... +macos.release = "res://../rust/target/release/lib{YourCrate}.macos.framework" +``` + + +## Building an iOS library + + +Add as target arm64 iOS. + +```sh +rustup target add aarch64-apple-ios +``` + +Build the library: + +```sh +cargo build --target=aarch64-apple-ios --release +``` + +The result of this will be the file `target/aarch64-apple-ios/release/lib{YourCrate}.dylib`. + +Next, you will need to create the `.framework` folder. + +```sh +mkdir target/release/lib{YourCrate}.ios.framework +cp target/release/lib{YourCrate}.ios.dylib \ + target/release/lib{YourCrate}.ios.framework/lib{YourCrate}.ios.dylib +``` + +Next, create the `Info.plist` file inside the `.framework` folder, with the following contents: + +```xml + + + + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleDevelopmentRegion + en + CFBundleExecutable + lib{YourCrate}.ios.dylib + CFBundleName + My App Name + CFBundleDisplayName + My App Name + CFBundleIdentifier + org.my-website.my-app + NSHumanReadableCopyright + Copyright (c) ... + CFBundleVersion + 0.12.0 + CFBundleShortVersionString + 0.12.0 + CFBundlePackageType + FMWK + CSResourcesFileMapped + + DTPlatformName + iphoneos + MinimumOSVersion + 12.0 + + +``` + +See XML format requirements above. + +Edit the project's `.gdextension` file to include support for iOS. +This file will probably be at `godot/{YourCrate}.gdextension`. +The format will be similar to the following: + +```ini +[libraries] +... +ios.release = "res://../rust/target/release/lib{YourCrate}.ios.framework" +``` + + +## Code Signing and Notarizing (macOS only) + + +```admonish note title="Optional Step" +This step is only needed if you want to share the library. +If you are building the whole game, you will sign everything and don't need to sign the library. You can skip to [Godot Build](#godot-build) step. +``` + +In order to code-sign and notarize your app, you will first need to gather some information from your enrolled Apple Developer account. +We will create corresponding environment variables and use a script to sign, so it's easier to run. Here are the environment variables needed: + +- `APPLE_CERT_BASE64` +- `APPLE_CERT_PASSWORD` +- `APPLE_DEV_ID` +- `APPLE_DEV_TEAM_ID` +- `APPLE_DEV_PASSWORD` +- `APPLE_DEV_APP_ID` + +Firstly, make sure to enroll your Apple ID to the Developer Program: + +- Create an Apple ID if you don't have one already. +- Use your Apple ID to register in the Apple Developer Program by going to [developer.apple.com](https://developer.apple.com). +- Accept all agreements from the Apple Developer Page. + + +### `APPLE_DEV_ID` - Apple ID + + +Your email used for your Apple ID. + +```sh +APPLE_DEV_ID = email@provider.com +``` + + +### `APPLE_DEV_TEAM_ID` - Apple Team ID + + +Go to [developer.apple.com](https://developer.apple.com). Go to account. + +Go to membership details. Copy Team ID. + +```sh +APPLE_DEV_TEAM_ID = 1ABCD23EFG +``` + + +### `APPLE_DEV_PASSWORD` - Apple App-Specific Password + + +Create Apple App-Specific Password. Copy the password. + +```sh +APPLE_DEV_PASSWORD = abcd-abcd-abcd-abcd +``` + + +### `APPLE_CERT_BASE64`, `APPLE_CERT_PASSWORD` and `APPLE_DEV_APP_ID` + + +Go to [developer.apple.com](https://developer.apple.com). Go to account. + +Go to certificates. + +Click on + at Certificates tab. Create Developer ID Application. Click Continue. + +Leave profile type as is. Create a certificate signing request from a Mac. You can use your own name and email address. Save the file to disk. +You will get a file called `CertificateSigningRequest.certSigningRequest`. Upload it to the Developer ID Application request. Click Continue. + +Download the certificate. You will get a file `developerID_application.cer`. + +On a Mac, right click and select open. Add it to the login keychain. +In the Keychain Access app that opened, log into Keychain tab, go to Keys, sort by date modified, +and expand your key (the key should have the name you entered at _Common Name_). +Right click the expanded certificate, get info, and copy the text at _Details -> Subject Name -> Common Name_. For example: + +```sh +APPLE_DEV_APP_ID = Developer ID Application: Common Name (1ABCD23EFG) +``` + +Then, select the certificate, right click and click export. At file format select `p12`. When exporting, set a password for the certificate. +This will be the value of `APPLE_CERT_PASSWORD`. You will get a `Certificates.p12` file. + +For example: + +```sh +APPLE_CERT_PASSWORD = +``` + +Then you need to make a base64 file out of it, by running: + +```sh +base64 -i Certificates.p12 -o Certificates.base64 +``` + +Copy the contents of the generated file, e.g.: + +```sh +APPLE_CERT_BASE64 = ...(A long text file) +``` + +After these secrets are obtained, all that remains is to set them as environment variables. +Afterwards you can use the following script +for signing [ci-sign-macos.ps1](https://github.com/godot-jolt/godot-jolt/blob/master/scripts/ci_sign_macos.ps1). +In order to run this script you will need to install [powershell](https://learn.microsoft.com/en-us/powershell/) on your Mac. + +```powershell +ci-sign-macos.ps1 target/release/{YourCrate}.framework +``` + +```admonish note title="External script disclaimer" +The user is responsible for the security and up-to-dateness of the script. +``` + + +## Godot Build + + +After building the libraries, you can now distribute them as they are, or build the whole game using Godot. +For that, follow Godot's _How to export_ guide: + +- [Exporting for macOS](https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_macos.html) +- [Exporting for iOS](https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_ios.html)