Skip to content

fix: include TargetConditionals.h in target.h for iOS cross-compilation#3115

Closed
lukejmann wants to merge 1 commit intoaws:mainfrom
lukejmann:fix/ios-target-conditionals
Closed

fix: include TargetConditionals.h in target.h for iOS cross-compilation#3115
lukejmann wants to merge 1 commit intoaws:mainfrom
lukejmann:fix/ios-target-conditionals

Conversation

@lukejmann
Copy link
Copy Markdown

Issues:

None filed yet — discovered in the wild cross-compiling for iOS via aws-lc-sys 0.38.0.

Description of changes:

aws-lc-sys 0.38.0 fails to compile urandom.c for aarch64-apple-ios on Xcode 16.2 (iPhoneOS 18.2 SDK) when built through the Rust cc-rs build system. Two compiler errors:
urandom.c:370:9: error: call to undeclared function 'ioctl' [-Werror,-Wimplicit-function-declaration]
urandom.c:370:27: error: use of undeclared identifier 'RNDGETENTCNT'

Root cause: target.h checks TARGET_OS_IPHONE to define OPENSSL_IOS, but never includes <TargetConditionals.h> itself — it relies on base.h having done so. On this toolchain, TARGET_OS_IPHONE is not available as a compiler builtin when target.h is processed, so OPENSSL_IOS is never defined. The entropy source selection in internal.h falls through to OPENSSL_RAND_URANDOM (the Linux /dev/urandom path) instead of OPENSSL_RAND_CCRANDOMGENERATEBYTES. urandom.c then tries to call ioctl(RNDGETENTCNT), but the headers for those (<linux/random.h>, <sys/ioctl.h>) are only included behind #if defined(OPENSSL_LINUX).
Two changes:

  1. include/openssl/target.h: Include <TargetConditionals.h> directly, guarded by !__ASSEMBLER__ since target.h is also used from .S files.
  2. crypto/rand_extra/urandom.c: Guard the RNDGETENTCNT / ioctl() entropy-check loop in ensure_dev_urandom_is_initialized() behind #if defined(OPENSSL_LINUX), matching the guards already on the corresponding #include directives. Both fixes are required — CI testing showed that fix 1 alone is not sufficient on Xcode 16.2.

Call-outs:

  • The target.h !__ASSEMBLER__ guard keeps <TargetConditionals.h> out of assembly contexts. In assembly, the TARGET_OS_* checks evaluate to false, matching current behavior.
  • The urandom.c change doesn't alter any behavior on Linux, where OPENSSL_LINUX is always defined alongside OPENSSL_RAND_URANDOM. On non-Linux platforms that reach this path, it skips the entropy-count check and goes straight to STATE_READY.

Testing:

We verified this end-to-end in CI on a macOS 14 / Xcode 16.2 runner. Our project (worldcoin/walletkit) cross-compiles aws-lc-sys 0.38.0 for aarch64-apple-ios, aarch64-apple-ios-sim, and x86_64-apple-ios.
Before (no fix): CI run — urandom.c fails
After (both fixes applied as a build-time source patch): CI run — Swift build passes
Fix 1 alone (target.h only, no urandom.c guard): CI run — still fails — confirmed that TARGET_OS_IPHONE remains unavailable on Xcode 16.2 even with the explicit include, so the urandom.c guard is also needed.
The test wiring is visible in worldcoin/walletkit#314, which applies both patches at build time against the crates.io source.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.

target.h checks TARGET_OS_IPHONE to define OPENSSL_IOS, but relies on
base.h having already included <TargetConditionals.h>. On toolchains
where TARGET_OS_IPHONE is not a compiler builtin (e.g. Xcode 16.2 /
Apple Clang 16 on macOS 14), the macro is never set, OPENSSL_IOS is
never defined, and the entropy source selection in internal.h falls
through to OPENSSL_RAND_URANDOM. This compiles urandom.c's full body
for iOS, which references the Linux-only RNDGETENTCNT ioctl and calls
ioctl() without <sys/ioctl.h>, producing hard errors:

  urandom.c:370: error: call to undeclared function 'ioctl'
  urandom.c:370: error: use of undeclared identifier 'RNDGETENTCNT'

Two changes:
1. target.h now includes <TargetConditionals.h> directly (guarded by
   !__ASSEMBLER__ since the header is also used in .S files). This
   ensures OPENSSL_IOS is always defined for iOS targets.
2. urandom.c's ensure_dev_urandom_is_initialized() guards the
   RNDGETENTCNT/ioctl block behind #if defined(OPENSSL_LINUX) as a
   defensive measure, since those symbols only come from headers that
   are themselves guarded by OPENSSL_LINUX.

Made-with: Cursor
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