CodeEditApp / CodeEditApp/CodeEditSymbols
`swift build` fails without Xcode: `Symbols.xcassets` not declared as a resource, and `Bundle.module` unreachable in distributed apps
- Dominant language
- Swift
- Stars
- 25
- Forks
- 15
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
`CodeEditSymbols` builds cleanly under Xcode but has two problems for consumers
who build with `swift build` on the command line and package their own `.app`:
1. **The build fails outright.** `Package.swift` never declares
`Symbols.xcassets` as a resource, so SwiftPM's command-line build does not
process the asset catalog and does not synthesize `Bundle.module`. (Xcode
auto-detects asset catalogs, which is why this is invisible in an Xcode
build.) This is a one-line manifest fix.
2. **Once building, a distributed `.app` crashes** on first symbol access,
because the generated `Bundle.module` accessor cannot find the resource
bundle inside a `.app`.
## Environment
- Package: `CodeEditSymbols` 0.2.3.
- Build: `swift build` from the command line. **No `.xcodeproj`.** The app is
assembled into a `.app` by a custom script that copies the SwiftPM resource
bundle (`CodeEditSymbols_CodeEditSymbols.bundle`) into
`MyApp.app/Contents/Resources/`.
- macOS, Apple Silicon, current Swift toolchain.
## Defect 1 — `swift build` fails: asset catalog not declared as a resource
### Root cause
`Package.swift` declares the target with no `resources:` rule:
```swift
.target(
name: "CodeEditSymbols",
dependencies: []
),
```
`Sources/CodeEditSymbols/Symbols.xcassets` is therefore not treated as a
package resource by the SwiftPM command-line build, `Bundle.module` is not
generated, and `CodeEditSymbols.swift` (which references `Bundle.module`)
fails to compile / the resource is never processed. Xcode papers over this by
auto-detecting `.xcassets`; `swift build` does not.
### Repro
1. `swift build` a target that depends on `CodeEditSymbols` (no Xcode project).
2. Build fails:
```text
Sources/CodeEditSymbols/CodeEditSymbols.swift:47:16: error: type 'Bundle' has no member 'module'
```
- **Expected:** `swift build` succeeds and bundles the symbol assets.
- **Actual:** build failure.
### Fix
Declare the asset catalog as a processed resource. `.process` has been
available since swift-tools-version 5.3, so **no tools-version bump is needed**
(the manifest stays at 5.5):
```swift
.target(
name: "CodeEditSymbols",
dependencies: [],
resources: [
.process("Symbols.xcassets")
]
),
```
## Defect 2 — `Bundle.module` fatalErrors in a distributed `.app`
### Root cause
Same shape as the companion `CodeEditLanguages` issue. The SwiftPM-generated
accessor probes only `Bundle.main.bundleURL/.bundle` (the `.app` wrapper
root) and a hardcoded absolute build-machine path, then `fatalError`s.
`Contents/Resources/.bundle` — where a CLI-assembled app copies the
resource bundle — is not among the probed locations.
`Bundle.module` is used in `CodeEditSymbols.swift`:
```swift
init(symbol: String) {
self.init(symbol, bundle: Bundle.module) // Image
}
static func symbol(named: String) -> NSImage? {
Bundle.module.image(forResource: named) // NSImage
}
```
### Repro
1. With Defect 1 fixed, assemble a `.app` and copy
`CodeEditSymbols_CodeEditSymbols.bundle` into `Contents/Resources/`.
2. Run the `.app`; access any `Image(symbol:)` / `.symbol(named:)`.
3. Crash at the accessor's `fatalError`.
- **Expected:** the symbol renders; no crash.
- **Actual:** `fatalError("could not load resource bundle …")`.
### Fix
Resolve the bundle from `Bundle.main.resourceURL` (i.e. `Contents/Resources`)
first, then fall back to `Bundle.module` (which still serves `swift build` /
`swift test` on the build machine). This changes nothing for Xcode consumers:
```swift
let symbolsBundle: Bundle = {
if let bundled = Bundle.main.resourceURL?
.appendingPathComponent("CodeEditSymbols_CodeEditSymbols.bundle"),
let bundle = Bundle(url: bundled) {
return bundle
}
return Bundle.module
}()
```
…and route the two `Bundle.module` references through `symbolsBundle`.
## Offer to contribute
We're already running both changes as a local patch against 0.2.3 with no
observed regression. Per the CodeEdit contribution convention (open an issue
first, ask to be assigned), we'd be happy to submit the PR — could you assign
this to us? The patch passes SwiftLint. Glad to adjust if you'd prefer a
different approach.
Thanks for maintaining CodeEditSymbols.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in Package.swift by checking the CodeEditSymbols target resource declaration, then read the Bundle.module uses in Sources/CodeEditSymbols/CodeEditSymbols.swift. Run swift build and reproduce a CLI-assembled app with the resource bundle in Contents/Resources. Done means the package builds without Xcode and symbol access works without a distributed-app crash.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- build-system, desktop
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100