Skip to content

Codegen: app codegenConfig with no spec files emits "${PODS_ROOT}/.." as Generate Specs input and causes an Xcode dependency cycle #58621

Description

@mateus-araujo

Description

scripts/codegen/generate-artifacts-executor/generateReactCodegenPodspec.jsgetInputFiles() builds the Generate Specs script phase input_files from a find over the app's codegenConfig.jsSrcsDir. When that directory contains no Native*.{js,ts} / *NativeComponent.{js,ts} files, execSync(find …) returns an empty string, ''.trim().split('\n') is [''], and the single empty path is mapped to:

'input_files' => ["${PODS_ROOT}/.."]

i.e. the whole ios/ directory. Xcode then sees that the Generate Specs phase of ReactCodegen depends on files produced by other targets' script phases in that directory (in an Expo project: the app target's [Expo] Configure project phase, which writes Pods/Target Support Files/…/ExpoModulesProvider.swift) and fails:

error: Cycle in dependencies between targets 'Callingx' and 'TurnoHosts'; building could produce unreliable results.
Cycle path: Callingx → ReactCodegen → TurnoHosts → Callingx
→ Target 'Callingx' has an explicit dependency on Target 'ReactCodegen'
○ That command depends on command in Target 'ReactCodegen': script phase “[CP-User] Generate Specs”
→ That command depends on command in Target 'TurnoHosts': script phase “[Expo] Configure project”

An app-level codegenConfig with no spec files is a legitimate setup: it is the documented way to declare ios.modulesConformingToProtocol (e.g. an RCTImageURLLoader) from the app when a dependency cannot.

Steps to reproduce

  1. In an app's package.json add
    "codegenConfig": { "name": "AppSpecs", "type": "modules", "jsSrcsDir": "src/config", "ios": { "modulesConformingToProtocol": { "RCTImageURLLoader": ["SomeLoader"] } } }
    where src/config exists but has no spec files.
  2. pod install
  3. Inspect ios/build/generated/ios/ReactCodegen/ReactCodegen.podspec'input_files' => ["${PODS_ROOT}/.."].
  4. Build in Xcode → dependency cycle error above (seen with Expo SDK 57 projects; any other script phase writing under ios/ triggers it too).

Fix

Filter the empty entry:

   const list = String(execSync(findCommand))
     .trim()
     .split('\n')
+    .filter(Boolean)
     .sort()

With that, input_files is [] (same as projects without an app codegenConfig) and the build succeeds.

React Native Version

0.86.3

Affected Platforms

Build - MacOS, Runtime - iOS

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs: Author FeedbackNeeds: ReproThis issue could be improved with a clear list of steps to reproduce the issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions