ahha に新しいネイティブモジュールをひとつ追加しました。expo-tracking-transparency です。
手順は教科書どおりでした。
npx expo install expo-tracking-transparency cd ios && pod install
pod install は成功しました。
Pod install took 27 [s] to run Integrating client project Pod installation complete! There are 117 dependencies from the Podfile and 143 total pods installed.
Podfile.lock にもきちんと入っています。TypeScript のコンパイルも通りました。そしてビルドを回すと。
› Compiling ahha » ahha_vers.c › Linking ahha » ahha.debug.dylib ❌ ld: symbol(s) not found for architecture arm64 CommandError: Failed to build iOS project. "xcodebuild" exited with error code 65.
コンパイルは全部通っているのに、リンク段階で落ちました。
どのシンボルなのか分からなかった
ld: symbol(s) not found は結果だけを告げる要約行です。通常はそのすぐ上にこういうものが出ます。
Undefined symbol: _OBJC_CLASS_$_ATTrackingManager
この名前が分かれば、どのフレームワークがリンクされていないかを特定できます。ところがコンソール出力にその行がありませんでした。
Xcode のビルドログを直接漁ることにしました。
DD=~/Library/Developer/Xcode/DerivedData/<プロジェクト>-<ハッシュ> grep -rh 'Undefined symbol' "$DD/Logs/Build"
何も出ません。理由はこれでした。.xcactivitylog は gzip 圧縮ファイルです。拡張子だけを見てテキストだと思い込み、そのまま grep をかけていました。
LOG=$(ls -1t "$DD/Logs/Build"/*.xcactivitylog | head -1) gunzip -c "$LOG" | tr '\r' '\n' | grep -a 'Undefined symbol'
こう展開する必要があります。それでも出ませんでした。単純な gzip テキストではなく独自のバイナリ構造を持っているためと思われます。
結局、実際のシンボル名を確保できませんでした。この記事の限界です。
解決 — Pods を丸ごと消して入れ直す
原因を特定できないまま、これを試しました。
cd ios rm -rf Pods Podfile.lock pod install cd .. yarn ios
ビルドが通りました。アプリを起動すると ATT の許可ダイアログも正常に出て、その後の審査も通過しています。
スポンサーリンク
スポンサーリンク
なぜこれが規約違反だったのか
このプロジェクトにはこういう規約を置いていました。
ライブラリのバージョン変更時は
pod update <PodName>を使う。pod deintegrate・rm -rf Podsは不要。
理由があります。Pods フォルダを丸ごと消すと 143 個の pod を全部取り直して再コンパイルします。ビルド時間が何倍にもなる。バージョンをひとつ上げるためにやることではありません。
実際その規約はうまく機能していました。ところが今回はバージョン変更ではなく、新規モジュールの追加でした。
整理した判定基準
| 状況 | 対処 |
|---|---|
| バージョン変更 | pod update <PodName>。Pods フォルダには触れない |
| 新規ネイティブモジュール追加後のリンク失敗 | rm -rf ios/Pods ios/Podfile.lock → pod install |
前者を先に試し、リンクエラーが出たら後者に移る順序です。最初から消すと時間の無駄で、消さないと解けません。
ついでに — 無視してよい警告
pod install の出力には警告が大量に出ます。今回の問題とは無関係なので区別しておくと役に立ちます。
spm.config.json の読み込み失敗
[!] [Expo-precompiled] Failed to read spm.config.json ... undefined method `filter_map' for #<Array>
22 個のモジュール全部で同じエラーが出ます。filter_map は Ruby 2.7 から追加されたメソッドです。システム Ruby のバージョンが低くて出る Expo ツーリングの警告であり、特定パッケージの問題ではありません。
FirebaseCore の deprecation
CocoaPods 配布を 2026 年 10 月以降に停止するという予告です。現在の動作には影響しません。
Precompiled modules の警告
事前コンパイル済みバイナリがないのでソースからビルドする、という案内です。遅くなりますが正常に動きます。
スポンサーリンク
スポンサーリンク
Pod installation complete! が出ていればインストール自体は成功です。上の警告は別の話です。
シンボル名を確保する方法(次回のために)
今回はできませんでしたが、次に同じ状況が来たらこうします。
1. コンソール出力を取りこぼさない
yarn ios 2>&1 | tee /tmp/build.log grep -B20 'symbol(s) not found' /tmp/build.log
❌ ld: 行のすぐ上の 10〜20 行に Undefined symbol: が出ます。スクロールで流れてしまう前にファイルへ落とします。
2. Xcode で直接ビルドする
.xcworkspace を開いてビルドすると、Issue Navigator にリンカエラーが構造化されて表示されます。ログファイルを掘るより確実です。
3. xcodebuild を直接呼ぶ
xcodebuild -workspace ios/<アプリ>.xcworkspace \
-scheme <スキーム> \
-configuration Debug \
-sdk iphonesimulator 2>&1 | tee /tmp/xcodebuild.log
元の出力がそのまま残ります。
まとめ
pod install の成功はリンクの成功ではありません。Podfile.lock に登録されたら終わりでもありません。
新規ネイティブモジュールを追加した後に ld: symbol(s) not found が出たら、Pods 全体の再インストールを試します。バージョン変更のときは不要ですが、新規追加は例外です。
ビルドログは .xcactivitylog を漁らず、コンソール出力をファイルに保存します。圧縮フォーマットなので grep が通りません。
この記事について
自社アプリ ahha(React Native + Expo Bare Workflow・RevenueCat サブスク・AdMob)の開発中に踏んだ内容です。
リンカエラーの実際のシンボル名は最後まで確保できませんでした。Pods の再インストールで解決したため再現を中止しています。したがって「キャッシュの不整合」は推定であり、確定した原因ではありません。Pods フォルダと Podfile.lock のどちらの削除が決定的だったかも分離検証していません。
この現象が expo-tracking-transparency 固有のものか、新規ネイティブモジュール一般の問題かも未確認です。


コメント