yonaskolb / yonaskolb/XcodeGen

resources: files silently dropped when target has multiple/nested sources: entries

Open
#1,645 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Swift
Stars
8.8k
Forks
908
Avg merge
17d 14h
Merged PRs (30d)
2

Description

Summary

When a target declares a top-level resources: key and has more than one sources: entry (or a single sources: entry whose directory contains subdirectories), the files listed under resources: are silently dropped from the generated project — no PBXBuildFile/PBXResourcesBuildPhase entries are created for them at all. xcodegen generate exits 0 with no warning or error, and the resulting Xcode project builds successfully, but the resource files are simply missing from the app bundle at runtime.

This is a nasty failure mode because there's no diagnostic of any kind — I only found it because our app crashed on launch with Could not locate configuration file: 'GoogleService-Info.plist' (Firebase), even though the file was present on disk and listed under resources: in project.yml.

Environment

  • XcodeGen 2.46.0 (Homebrew)
  • macOS 26.6.2, Xcode 26.6 (17F113)

Minimal reproduction

Sources/App/App.swift
Sources/Models/Model.swift
Resources/config.plist
project.yml

project.yml:

name: Demo
options:
  deploymentTarget:
    iOS: "17.0"
targets:
  Demo:
    type: application
    platform: iOS
    sources:
      - path: Sources/App
      - path: Sources/Models
    resources:
      - path: Resources
    settings:
      base:
        PRODUCT_BUNDLE_IDENTIFIER: com.example.demo
        GENERATE_INFOPLIST_FILE: YES

Run xcodegen generate, then:

grep -c "config.plist" Demo.xcodeproj/project.pbxproj
# => 0

config.plist does not appear anywhere in the generated project.pbxproj — no file reference, no build file, no resources build phase entry. No error or warning is printed during generation.

Workaround

Removing the resources: key and instead adding the resources folder as one more entry in the sources: array makes it work correctly (XcodeGen auto-classifies non-compilable extensions like .plist into the Resources build phase):

    sources:
      - path: Sources/App
      - path: Sources/Models
      - path: Resources
grep -c "config.plist" Demo.xcodeproj/project.pbxproj
# => 4  (file reference + build file + 2 group listings)

Notes on what does/doesn't trigger it, from bisecting:

  • resources: + a single, flat sources: entry (no subdirectories) → works fine.
  • resources: + a single sources: entry whose directory contains subdirectories → broken (0 matches).
  • resources: + two or more sources: entries (even flat, sibling directories) → broken (0 matches).
  • Moving the resources path into sources: instead of resources: → always works, regardless of how many other sources: entries exist.

This doesn't seem related to defaultSourceDirectoryType: syncedFolder (not used here, plain group-type sources) so I don't think it's the same as #1586 — that one was specific to synced folders and was fixed by #1587, but this reproduces with plain path-based sources on a fresh 2.46.0 install.

Impact

Since this fails silently (no error, no warning, successful build), it's easy to ship an app missing critical bundled resources without noticing until a runtime crash or missing-asset bug shows up. Given how common it is to have more than one sources: path in a real project, this seems worth flagging even though there's a simple workaround once you know about it.

Happy to provide more detail or test a fix if useful.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the shown project.yml by running xcodegen generate, then inspect Demo.xcodeproj/project.pbxproj and confirm config.plist is absent. Trace resource handling for multiple or nested sources; done means the resource has file-reference, PBXBuildFile, and PBXResourcesBuildPhase entries, with regression coverage for the listed triggering cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
build-system, cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.