Document how the Monero iOS library is built
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
# Monero native library for iOS
|
||||
|
||||
The wallet runs monero-project `wallet2` (plus monero-cpp as the C++ API) on
|
||||
device. Everything is compiled into a single static archive that the app links.
|
||||
|
||||
## Artifacts
|
||||
|
||||
| File | Architecture | Platform |
|
||||
|---|---|---|
|
||||
| `libs/libkoins_monero_merged.a` | arm64 | iOS simulator |
|
||||
| `libs/libkoins_monero_device.a` | arm64 | iOS device |
|
||||
|
||||
Both are needed: they are the same CPU architecture but different platforms, so
|
||||
they cannot be merged into one fat archive. `project.yml` selects the right one
|
||||
per SDK.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Xcode with the iOS device and simulator SDKs
|
||||
- CMake 3.2x (monero 0.18 is not tested with CMake 4)
|
||||
- GNU make (the builds use the "Unix Makefiles" generator)
|
||||
- Roughly 10 GB of disk and a long coffee break
|
||||
|
||||
## Sources
|
||||
|
||||
- monero-project v0.18.5.1
|
||||
- monero-cpp (woodser), which keeps monero-project at `external/monero-project`
|
||||
|
||||
## Toolchain customisations
|
||||
|
||||
The files under `depends/` are the ones modified from upstream, kept here so the
|
||||
archive can be regenerated:
|
||||
|
||||
| File | Change |
|
||||
|---|---|
|
||||
| `depends/hosts/ios.mk` | new host; `IOS_PLATFORM=SIMULATOR` (default) or `DEVICE` selects the SDK and the target triple (`aarch64-apple-ios[-simulator]`) |
|
||||
| `depends/packages/packages.mk` | `ios_packages := boost openssl zeromq expat unbound sodium` (no libiconv) |
|
||||
| `depends/packages/boost.mk` | boost for the `ios` toolset: darwin toolset, libtool archiver, c++11, no b2 python |
|
||||
| `depends/packages/zeromq.mk` | ios config opts (`--host=aarch64-apple-darwin`), no libsodium, no curve |
|
||||
| `depends/packages/unbound.mk` | drops the autoconf dependency |
|
||||
| `depends/packages/sodium.mk` | drops the autoconf dependency |
|
||||
| `depends/funcs.mk` | create the prefix `lib` directory before extracting dependency archives |
|
||||
|
||||
One source change is also required, in monero-project:
|
||||
|
||||
- `src/cryptonote_basic/miner.cpp` — wrap the IOKit includes and the related
|
||||
code with `defined(TARGET_OS_OSX) && TARGET_OS_OSX`; IOKit is unavailable on
|
||||
iOS. Two locations, around lines 51 and 986.
|
||||
|
||||
Two more steps are needed when targeting a device:
|
||||
|
||||
- Copy monero's patched boost serialisation headers into the dependency prefix,
|
||||
because monero's build otherwise only finds them for the platform it was
|
||||
installed for:
|
||||
|
||||
```sh
|
||||
cp external/boost/archive/portable_binary_*.hpp \
|
||||
contrib/depends/$HOST/include/boost/archive/
|
||||
```
|
||||
|
||||
- randomx's AArch64 JIT references `__clear_cache`, which libSystem exports on
|
||||
macOS and the simulator but not on iOS. The app supplies it in
|
||||
`Koins/Support/ClearCache.c`.
|
||||
|
||||
## Build
|
||||
|
||||
Set `PLATFORM` to `SIMULATOR` or `DEVICE`; the only differences are the depends
|
||||
host flag and the output archive name.
|
||||
|
||||
```sh
|
||||
MONERO=/path/to/monero-project
|
||||
PLATFORM=SIMULATOR # or DEVICE
|
||||
HOST=aarch64-apple-ios
|
||||
|
||||
# 1. Cross-compiled dependencies (boost, openssl, zeromq, expat, unbound, sodium)
|
||||
cd "$MONERO/contrib/depends"
|
||||
make HOST=$HOST IOS_PLATFORM=$PLATFORM -j"$(sysctl -n hw.ncpu)"
|
||||
|
||||
# 2. monero-project, static wallet library
|
||||
cd "$MONERO"
|
||||
mkdir -p build/ios-$PLATFORM && cd build/ios-$PLATFORM
|
||||
cmake -G "Unix Makefiles" \
|
||||
-DCMAKE_TOOLCHAIN_FILE="$MONERO/contrib/depends/$HOST/share/toolchain.cmake" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DSTATIC=ON -DBUILD_SHARED_LIBS=OFF \
|
||||
-DBUILD_TESTS=OFF -DBUILD_DOCUMENTATION=OFF -DUSE_DEVICE_TREZOR=OFF \
|
||||
../..
|
||||
make -j"$(sysctl -n hw.ncpu)" wallet # produces lib/libwallet.a
|
||||
|
||||
# 3. monero-cpp
|
||||
cd /path/to/monero-cpp
|
||||
mkdir -p build-ios-$PLATFORM && cd build-ios-$PLATFORM
|
||||
cmake -G "Unix Makefiles" \
|
||||
-DCMAKE_TOOLCHAIN_FILE="$MONERO/contrib/depends/$HOST/share/toolchain.cmake" \
|
||||
../..
|
||||
make -j"$(sysctl -n hw.ncpu)" # produces libmonero-cpp.a
|
||||
|
||||
# 4. Merge into one archive for the app
|
||||
libtool -static -o libkoins_monero_merged.a \
|
||||
libmonero-cpp.a \
|
||||
"$MONERO/build/ios-$PLATFORM/lib/libwallet.a" \
|
||||
"$MONERO/build/ios-$PLATFORM"/src/*/lib*.a \
|
||||
"$MONERO/build/ios-$PLATFORM"/external/*/lib*.a \
|
||||
"$MONERO/build/ios-$PLATFORM"/contrib/epee/src/libepee.a \
|
||||
"$MONERO/contrib/depends/$HOST"/lib/lib*.a
|
||||
```
|
||||
|
||||
Copy the result to `libs/`, using `libkoins_monero_merged.a` for the simulator
|
||||
and `libkoins_monero_device.a` for the device.
|
||||
|
||||
## Notes
|
||||
|
||||
- Only the simulator archive is needed to run in the simulator; the device
|
||||
archive is needed for a real iPhone, and Xcode requires the matching one at
|
||||
link time.
|
||||
- Building the device slice after a simulator build requires moving the
|
||||
simulator depends prefix aside first, since depends installs into
|
||||
`contrib/depends/<host>` and both platforms share the host name.
|
||||
- The app also links the OpenSSL that is embedded in this archive, which is how
|
||||
the XRP wallet gets secp256k1 without an extra dependency.
|
||||
Reference in New Issue
Block a user