Skip to content

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

Closed
lukejmann wants to merge 1 commit intoaws:mainfrom
lukejmann:fix/ios-cross-compilation
Closed

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

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:

target.h checks TARGET_OS_IPHONE and TARGET_OS_OSX to define OPENSSL_IOS and OPENSSL_MACOS, but never includes <TargetConditionals.h> itself. It relies on base.h having done the include first. On toolchains where TARGET_OS_* are not compiler builtins (observed with Xcode 16.2 / iPhoneOS 18.2 SDK, compiled through the cc-rs build system), the macros are absent when target.h is processed. OPENSSL_IOS is never defined.

That causes the entropy source selection in crypto/rand_extra/internal.h to skip OPENSSL_RAND_CCRANDOMGENERATEBYTES and fall through to OPENSSL_RAND_URANDOM. urandom.c then fails to compile because ensure_dev_urandom_is_initialized() references ioctl() and RNDGETENTCNT, whose headers (<linux/random.h>, <sys/ioctl.h>) are only included behind #if defined(OPENSSL_LINUX):

urandom.c:370:9: error: call to undeclared function 'ioctl'; ISO C99 and later do not support implicit function declarations [-Werror,-Wimplicit-function-declaration]
urandom.c:370:27: error: use of undeclared identifier 'RNDGETENTCNT'

Fix: include <TargetConditionals.h> directly in target.h so it is self-contained on Apple platforms. Guarded by !__ASSEMBLER__ since target.h is also pulled into .S files.

Call-outs:

The target.h header is documented as safe for C, C++, and assembly. The !__ASSEMBLER__ guard keeps <TargetConditionals.h> out of assembly contexts where system headers aren't available. In assembly, the TARGET_OS_* checks simply evaluate to false, which matches current behavior (assembly files don't inspect OPENSSL_IOS).

Testing:

We verified this end-to-end. 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 in CI on a macOS 14 / Xcode 16.2 runner.

Before (no fix): CI fails compiling urandom.cfailing run

After (this fix): We forked aws-lc-rs, pointed the aws-lc-sys/aws-lc submodule at this branch (lukejmann/aws-lc@fix/ios-cross-compilation), then patched our Cargo.toml to use the fork:

[patch.crates-io]
aws-lc-sys = { git = "https://github.com/lukejmann/aws-lc-rs.git", branch = "fix/ios-cross-compilation" }

CI passes with no workarounds — passing run

The fix and test wiring can be seen in this walletkit PR, which is structured as a single commit on top of the original failing commit: worldcoin/walletkit#314 (base bump-aws-lc-broken = the commit that bumps to aws-lc-sys 0.38.0 and fails, head fix/aws-lc-ios = same + the [patch.crates-io] line).

Existing CI for Linux / macOS / Windows targets should be unaffected since the change only adds an include that's already present in base.h for those paths.

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.

@lukejmann lukejmann requested a review from a team as a code owner March 20, 2026 00:38
@lukejmann lukejmann marked this pull request as draft March 20, 2026 00:38
lukejmann added a commit to worldcoin/walletkit that referenced this pull request Mar 20, 2026
aws-lc-sys 0.38.0 fails to compile urandom.c for aarch64-apple-ios on
Xcode 16.2 because target.h doesn't include <TargetConditionals.h>,
so OPENSSL_IOS is never defined and the build falls through to the
Linux urandom path.

Patches target.h in the cargo registry before building iOS targets.
This directly proves the upstream root cause fix works:
aws/aws-lc#3111

Made-with: Cursor
lukejmann added a commit to worldcoin/walletkit that referenced this pull request Mar 20, 2026
Replace the CFLAGS workaround (which masked symptoms by stubbing
RNDGETENTCNT and suppressing warnings) with a build-time source patch
that fixes the actual root cause: aws-lc's target.h missing an
#include <TargetConditionals.h>.

Upstream PR: aws/aws-lc#3111

Made-with: Cursor
lukejmann added a commit to worldcoin/walletkit that referenced this pull request Mar 20, 2026
Replace the CFLAGS workaround (which masked symptoms by stubbing
RNDGETENTCNT and suppressing warnings) with a build-time source patch
that fixes the actual root cause: aws-lc's target.h missing an
#include <TargetConditionals.h>.

Upstream PR: aws/aws-lc#3111

Made-with: Cursor
lukejmann added a commit to worldcoin/walletkit that referenced this pull request Mar 20, 2026
aws-lc-sys 0.38.0 fails to compile urandom.c for aarch64-apple-ios on
Xcode 16.2 because target.h doesn't include <TargetConditionals.h>,
so OPENSSL_IOS is never defined and the build falls through to the
Linux urandom path.

Patches target.h in the cargo registry before building iOS targets.
This directly proves the upstream root cause fix works:
aws/aws-lc#3111

Made-with: Cursor
lukejmann added a commit to worldcoin/walletkit that referenced this pull request Mar 20, 2026
aws-lc-sys 0.38.0 fails to compile urandom.c for aarch64-apple-ios on
Xcode 16.2 because target.h doesn't include <TargetConditionals.h>,
so OPENSSL_IOS is never defined and the build falls through to the
Linux urandom path.

Patches target.h in the cargo registry before building iOS targets.
This directly proves the upstream root cause fix works:
aws/aws-lc#3111

Made-with: Cursor
…NDGETENTCNT

Two fixes for urandom.c failing to compile on aarch64-apple-ios
with Xcode 16.2 / iPhoneOS 18.2 SDK:

1. target.h: include <TargetConditionals.h> so OPENSSL_IOS is defined
   (guarded by !__ASSEMBLER__ for .S file compatibility)

2. urandom.c: guard RNDGETENTCNT/ioctl usage behind OPENSSL_LINUX,
   matching the guards already on the #include directives for
   <linux/random.h> and <sys/ioctl.h>

Made-with: Cursor
Comment on lines +355 to +358
#if defined(OPENSSL_LINUX)
// On Linux, where urandom doesn't block at startup, we ensure that the
// kernel has sufficient entropy before continuing. RNDGETENTCNT and ioctl
// are Linux-specific (from <linux/random.h> and <sys/ioctl.h>).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @lukejmann -- Thanks for the PR, and the detailed write up! We also have an issue related to this in the aws-lc-rs repo: aws/aws-lc-rs#1068. I wrote up my initial analysis here.

The change here to "urandom.c" is concerning. This is guarding the loop with OPENSSL_LINUX while still leaving random_flavor_state = STATE_READY below unconditional. The problem is that if this code were ever compiled/used on a non-Linux platform, it would silently skip entropy initialization entirely.

We believe the correct fix is likely in crypto/rand_extra/internal.h: adding an OPENSSL_APPLE catch-all so Apple platforms never fall through to OPENSSL_RAND_URANDOM in the first place.

We're working on this now — thanks again for bringing it to our attention!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!!

@lukejmann lukejmann closed this Mar 20, 2026
justsmth added a commit that referenced this pull request Mar 26, 2026
### Issues:
Related: aws/aws-lc-rs#1068
Related: #3111

### Context:

When cross-compiling for iOS on certain toolchains, `TARGET_OS_IPHONE`
from `TargetConditionals.h` can evaluate to 0 (e.g., due to compiler/SDK
version mismatches). This causes `OPENSSL_IOS` to not be defined, and
the entropy source selection in `crypto/rand_extra/internal.h` falls
through to `OPENSSL_RAND_URANDOM`, which is inherently Linux-specific.
The build then fails in `urandom.c` due to its use of `ioctl()` and
`RNDGETENTCNT`.

### Description of changes:

The fix widens the `CCRandomGenerateBytes` branch from `OPENSSL_IOS` to
`OPENSSL_APPLE`. `OPENSSL_APPLE` is derived from `__APPLE__` (a compiler
intrinsic) so it has no dependency on `TargetConditionals.h`.
`CCRandomGenerateBytes` is available on all Apple platforms, so this is
safe regardless of the specific Apple target.

### Call-outs:

We considered instead redefining `OPENSSL_IOS` using a
`TargetConditionals.h`-independent condition (e.g., `OPENSSL_APPLE &&
!OPENSSL_MACOS`), but `OPENSSL_MACOS` depends on the same
`TargetConditionals.h` mechanism and fails in the same way. It would
also incorrectly label non-iOS Apple platforms (tvOS, watchOS, etc.) as
iOS.

### Testing:

Added an iOS aarch64 cross-compilation job to the `aws-lc-rs.yml`
workflow.
This job installs Homebrew LLVM (which reproduces the
`TargetConditionals.h`
detection failure) and builds aws-lc-rs for `aarch64-apple-ios`.


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.
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.

2 participants