I'm having problems trying to realize the following dependency setup between two frameworks and an app, all developed by me:
Util containts a bunch of low-level utilities and extensions to
Foundation
types such asString
,Date
, etc.UI contains a bunch of custom
UIView
andUIViewController
subclasses, class extensions forUIColor
,UIImage
, etc..
The app and each framework has its own repository on GitHub.
The UI framework is set up to depend on the Util framework, using Carthage:
The project's Cartfile contains a reference to the Util repo:
github "MyOrganization/Util.git"
Util is listed in "Linked Frameworks and Libraries", but not embedded (because UI is a framework project, not an app).
The Framework Search Paths build setting contains
$(PROJECT_DIR)/Carthage/Build/iOS
in addition to$(inherited)
The .gitignore file is configured to ignore the whole
Carthage
directory (not just/Build
)I am not using git submodules, and I don't intend to (I have enough headaches already).
If I clone the UI framework and run carthage update
, Carthage fetches/builds Util and I can embed it manually to build the UI framework.
So far so good.
But if I clone the App framework and run carthage update
, Carthage fetches the UI repo, but it fails to build:
The directory
App/Carthage/Checkouts
contains the checked-out copy of the UI project, as expected. However, there is no further Carthage directory for the nested framework (I assume it should beApp/Carthage/Checkouts/UI/Carhage/Checkout/Util
).Navigating to
App/Carthage/Checkouts/UI
opening the workspace there with Xcode and building it also fails, obviously. The reference toUtil.framework
is broken.
From what I've read, Carthage should fetch the recursive dependency; What am I missing here?
I tried adding both framework URLs the the App Cartfile, but xcode still fails to build the UI framework.
The bottom part of the log pointed to by the carthage output says:
/Users/me/Projects/App/code/App/Carthage/Checkouts/UI/code/UI/UI/MyClass.swift:10:8: error: no such module 'Util'
import Util
^
** ARCHIVE FAILED **
The following build commands failed:
CompileSwift normal arm64
CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler
(2 failures)
Update
I put together a minimal reproducible example on GitHub. The app and frameworks make up this dependency graph:
A -> B -> C
// (and also A -> C, but that's not relevant now)
(C is the app, B and C are frameworks).
When running carthage update
on the A project, it fetches both framework repos, checks out both, starts to build B first and fails, just as above (import
directive).
The checked out copy of B has the right Cartfile, along with all the source files, but there is no nested Carthage/
directory, let alone the necessary copy of C within it.
I guess I need to somehow make the build process refer to A/Carthage/Builds/C.framework
instead of A/Carthage/Checkouts/B/Carthage/Builds/C.framework
, but don't know how to set up the B project for that to work out...