Skip to content

Add iOS cross-compilation support#2

Open
Maxnflaxl wants to merge 2 commits into
masterfrom
feat/ios-support
Open

Add iOS cross-compilation support#2
Maxnflaxl wants to merge 2 commits into
masterfrom
feat/ios-support

Conversation

@Maxnflaxl
Copy link
Copy Markdown
Member

Adds iOS cross-compile paths so callers (e.g. the Beam iOS wallet) can build libipfs-bindings.a + libasio-ipfs.a for arm64 device and arm64/x86_64 simulator slices, mirroring the existing Android path. The Go cgo build is driven from CMake by setting GOOS=ios and bridging the Xcode SDK via xcrun. The Go 1.16.10 Darwin tarball this repo already pins is reused — its c-archive mode handles iOS cross-compile when given the right env vars.

Changes

  • CMakeLists.txt — detect CMAKE_SYSTEM_NAME=iOS, infer device-vs-simulator from CMAKE_OSX_SYSROOT and target arch from CMAKE_OSX_ARCHITECTURES; enforce one slice per invocation. Resolve the Xcode SDK path + clang binary via xcrun at configure time and bake them into CGO_CFLAGS / CGO_CXXFLAGS / CGO_LDFLAGS so the iOS target + sysroot reach every cgo compile (including Go's std-library cgo glue — net, os/user, plugin). Skip Boost find_package on iOS (header-only path via BOOST_ROOT / BOOST_ROOT_IOS, matching Beam's existing iOS wallet convention). Extend the imported-library + CoreFoundation/Security framework block to cover iOS.
  • scripts/build-ios.sh — driver script that builds all three slices and combines them into ipfs-bindings.xcframework + asio-ipfs.xcframework via xcodebuild -create-xcframework, lipo-ing the two simulator arches first.
  • README.md — iOS cross-compilation section.

Why two commits

c7f2db2 initially passed the iOS target/sysroot via a multi-word CC value. That works for asio-ipfs's own cgo glue but fails on Go's std-library cgo compiles (net/cgo_bsd.go, os/user/cgo_lookup_unix.go, plugin/plugin_dlopen.go) — Go's internal compile path uses only the first token of CC as the program and silently drops the rest. beded1b moves the flags into CGO_CFLAGS / CGO_LDFLAGS instead, which Go appends verbatim to every cgo invocation.

Verification

  • cmake -S . -B build/ios-device -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_ARCHITECTURES=arm64 -DBOOST_ROOT=… configures cleanly; generated build files reference xcrun-resolved SDK + correct arm64-apple-ios<deployment> triple.
  • Same for CMAKE_OSX_SYSROOT=iphonesimulator with arm64 and x86_64 arches (-simulator triple suffix).
  • Non-iOS host configures (Linux / macOS / Windows) unchanged — no regressions.
  • End-to-end build exercised via enable asset swap, IPFS, and related features for iOS builds beam#2046, which bumps the submodule to this branch's tip and turns BEAM_IPFS_SUPPORT=On for iOS in CI.

Caveats / follow-ups

  • Go 1.16.10 (this repo's pinned version) supports GOOS=ios since 1.16, including Apple-Silicon simulator via the -target arm64-apple-ios<ver>-simulator clang flag we set. A future bump to a newer Go would tighten iOS handling further but isn't required for this PR.
  • Boost on iOS is consumed header-only (asio / intrusive / optional / system). If a future change to this repo needs a compiled Boost component, that has to land alongside an iOS Boost lib path.

Maxnflaxl added 2 commits May 12, 2026 16:21
Build libipfs-bindings.a + libasio-ipfs.a for iOS (arm64 device + arm64
and x86_64 simulators), mirroring the existing Android path. The Go
cgo build is driven from CMake by setting GOOS=ios and a CC value of
`<xcrun clang> -target <triple> -isysroot <sdk>` resolved at configure
time; the host-arch Darwin Go 1.16.10 tarball already used by the
macOS build is reused.

- CMakeLists.txt: detect CMAKE_SYSTEM_NAME=iOS, enforce single-arch
  slices, skip Boost find_package on iOS (header-only via BOOST_ROOT /
  BOOST_ROOT_IOS, matching the Beam iOS wallet build), add an
  iOS-specific add_custom_command using cmake -E env to dodge shell-
  quoting headaches with the multi-word CC, extend the imported-
  library + CoreFoundation/Security framework block to cover iOS.
- scripts/build-ios.sh: build all three slices and combine into
  ipfs-bindings.xcframework + asio-ipfs.xcframework via
  xcodebuild -create-xcframework.
- README.md: iOS cross-compilation section.
CI fail mode: net/cgo_bsd.go, os/user/cgo_lookup_unix.go and
plugin/plugin_dlopen.go errored with `'netdb.h' / 'unistd.h' /
'dlfcn.h' file not found` even though our CC string carried
`-isysroot <iphoneos.sdk>`.

Root cause: Go's cgo treats CC as a "program" when composing the
internal compile commands for std-library cgo glue. Anything past the
first token (-target, -isysroot, ...) gets silently dropped on that
path, so clang ran without a sysroot and couldn't find POSIX headers.
The cgo glue for our own package was fine because that path does
respect the multi-word CC, which masked the issue until the std-lib
packages were compiled.

Fix: keep CC as the bare clang binary and ship the iOS target /
sysroot through CGO_CFLAGS / CGO_CXXFLAGS / CGO_LDFLAGS. Those are
appended verbatim to every cgo invocation, so the iOS cross-compile
flags reach the std-library compiles too.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant