Skip to content

fix(iOS): replace racy RaTeXFFI modulemap-strip script with an explicit-modules opt-out#546

Merged
hryhoriiK97 merged 2 commits into
software-mansion:mainfrom
chrfalch:fix/ratexffi-explicit-modules
Jul 17, 2026
Merged

fix(iOS): replace racy RaTeXFFI modulemap-strip script with an explicit-modules opt-out#546
hryhoriiK97 merged 2 commits into
software-mansion:mainfrom
chrfalch:fix/ratexffi-explicit-modules

Conversation

@chrfalch

Copy link
Copy Markdown
Contributor

fix(iOS): replace racy RaTeXFFI modulemap-strip script with an explicit-modules opt-out

Summary

The [ios] react-native-enriched-markdown job in react-native-community/nightly-tests went red against react-native@0.88.0-nightly-20260717 (run):

error: Clang dependency scanner failure:
  …/Debug-iphonesimulator/include/module.modulemap:1:8: error: redefinition of module 'RaTeXFFI'
  …/Debug-iphonesimulator/ReactNativeEnrichedMarkdown/include/module.modulemap:1:8: note: previously defined here

What's going on

Xcode materializes the RaTeX binary target's xcframework into both the platform-wide products dir and the pod's own build dir — two identical module.modulemaps defining RaTeXFFI, both on the pod target's search paths. That duplication has always existed; the existing Fix RaTeXFFI Module Redefinition script phase sed-strips the platform-wide copy before_compile.

Two things changed:

  1. React Native's VFS-overlay removal (the prebuilt/SwiftPM stack, first shipped in 0.88.0-nightly-20260717) removed the -ivfsoverlay flag that had been disqualifying this pod target from Xcode 26's default explicit modules mode. The target now builds with -explicit-module-build, whose dependency scanner loads every reachable module map eagerly and hard-errors on the duplicate — where classic implicit modules tolerate it (verified: an implicit-modules compile against both duplicate maps prints the diagnostic but exits 0).
  2. The script-phase approach races the scanner: it mutates a build product mid-build. On Xcode 26.3 (what CI runs) the scanner reads the modulemap before the script's edit lands and the build fails even though the script ran; on 26.6 the script happens to win and the build passes. A workaround whose correctness depends on undocumented scan scheduling isn't stable across Xcode releases.

The fix

Set SWIFT_ENABLE_EXPLICIT_MODULES = NO in the pod's pod_target_xcconfig when math is enabled, and drop the now-redundant strip script (the signature-dedup phase stays). Under implicit modules the duplicate definition is benign — no build products need patching at all.

This is declarative (no mid-build mutation, no race), works on every RN version, and takes effect at pod install time.

Related: react-native side ships the same opt-out for every spm_dependency consumer in react/react-native#57589 — but this library shouldn't need to wait for an RN release, and dropping the racy script is worthwhile regardless.

Test plan

Fresh RN app on react-native@0.88.0-nightly-20260717-b33de750b + react-native-enriched-markdown@0.8.0-nightly-20260716 with the prebuilt-core flags CI uses (RCT_USE_RN_DEP=1 RCT_USE_PREBUILT_RNCORE=1), Xcode 26.6, stock React Native spm.rb (i.e. without the RN-side fix), this podspec swapped into node_modules:

  • pod install: SWIFT_ENABLE_EXPLICIT_MODULES = NO lands on both configurations of the pod target; the strip phase is gone from the generated project.
  • Build: the pod target's SwiftDriver invocation no longer contains -explicit-module-build; BUILD SUCCEEDED with both duplicate module.modulemap copies deliberately present.

…modules opt-out

Xcode materializes the RaTeX binary target's module.modulemap into both
the platform-wide products dir and the pod's own build dir. Xcode 26's
default explicit-modules dependency scanner hard-errors on the duplicate
("redefinition of module 'RaTeXFFI'"), and the before_compile script that
sed-stripped one copy races the scanner: it loses on Xcode 26.3 (the
nightly-tests failure against react-native 0.88.0-nightly-20260717) and
only happens to win on 26.6.

Opt the pod target out of explicit modules via pod_target_xcconfig
instead - implicit modules tolerate the duplicate definition, no build
products need patching mid-build, and the fix is declarative and works
on every React Native version. Drop the now-redundant strip script; the
signature-dedup phase stays.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@hryhoriiK97
hryhoriiK97 self-requested a review July 17, 2026 10:35

@hryhoriiK97 hryhoriiK97 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM! @chrfalch thank you for the fix!

The explicit-modules fix in the podspec requires Xcode 26.6 where the
Clang dependency scanner correctly respects SWIFT_ENABLE_EXPLICIT_MODULES.
On 26.3 the scanner still hard-errors on the duplicate RaTeXFFI modulemap.

Co-authored-by: Cursor <cursoragent@cursor.com>

@hryhoriiK97 hryhoriiK97 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@chrfalch CI (rn-build-ios) was failing on Xcode 26.3 - the fix needs 26.6. I've pushed a commit bumping CI Xcode to 26.6.

@hryhoriiK97
hryhoriiK97 merged commit a65a7b9 into software-mansion:main Jul 17, 2026
9 checks passed
hryhoriiK97 pushed a commit that referenced this pull request Jul 19, 2026
…n explicit-modules opt-out (#546)" (#551)

This reverts commit a65a7b9.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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