120 lines
4.6 KiB
Markdown
120 lines
4.6 KiB
Markdown
# 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. |