Xcode 27 unbrella for module FBLPromises already covers this directory
- Dominant language
- Objective-C
- Stars
- 3.8k
- Forks
- 316
- PR merge metrics
- No merged PRs in 30d
Description
### Description
`FBLPromises`' module map fails to build under Xcode's newer Clang toolchain (Xcode 26/27 beta, iOS 27 SDK) when **Explicitly Built Modules** are enabled. The module map declares an `umbrella header` *and* an explicit list of the sibling headers in the same directory, which the newer Clang rejects.
### Error
```
.../checkouts/promises/Sources/FBLPromises/include/module.modulemap:2:21:
error: umbrella for module 'FBLPromises' already covers this directory
```
The error is fatal to Clang dependency scanning, so every module that transitively imports `FBLPromises` (e.g. via Firebase) then fails with `could not build module 'FBLPromises'` and a cascade of `Compilation search paths unable to resolve module dependency` errors.
### Environment
- Xcode: 26/27 beta (iPhoneSimulator 27.0 SDK)
- Integration: Swift Package Manager
- Build mode: Explicitly Built Modules enabled (`-explicit-module-build`)
- Promises version:
### Root cause
`Sources/FBLPromises/include/module.modulemap` declares an umbrella header together with an explicit list of `header` entries for files that live in the same directory the umbrella already covers:
```
module FBLPromises {
umbrella header "FBLPromises.h"
header "FBLPromise.h"
header "FBLPromise+All.h"
// ... all the other FBLPromise+*.h headers ...
exclude header "FBLPromisePrivate.h"
export *
}
```
An `umbrella header` already covers the whole directory. Re-declaring the sibling headers explicitly makes Clang see the directory as covered twice. Older Clang tolerated this; the newer toolchain treats it as an error.
### Suggested fix
Drop the redundant explicit `header` entries and keep the umbrella plus the `exclude` for the private header:
```
module FBLPromises {
umbrella header "FBLPromises.h"
exclude header "FBLPromisePrivate.h"
export *
}
```
The umbrella header already imports every public `FBLPromise+*.h`, so the explicit list only duplicated coverage. The `exclude` is still required so `FBLPromisePrivate.h` (which sits in the covered directory) isn't pulled into the module.
### Steps to reproduce
1. Integrate Firebase (or Promises directly) via SPM.
2. Build with Xcode 26/27 beta with Explicitly Built Modules enabled.
3. Observe the `umbrella ... already covers this directory` error and the downstream `could not build module` cascade.
### Workarounds
- Patch the module map as above (not durable — the SPM checkout is regenerated on re-resolution).
- Disable Explicitly Built Modules (`SWIFT_ENABLE_EXPLICIT_MODULES = NO`).
Contributor guide
Research direction
Start with Sources/FBLPromises/include/module.modulemap and compare its umbrella, header, and exclude declarations with the reported Clang error. Reproduce the failure using Swift Package Manager and Explicitly Built Modules under the affected Xcode toolchain, then verify that FBLPromises and a dependent module build without the duplicate-coverage error while the private header remains excluded.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- objective-c, swift
- Domain
- build-system, mobile
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100