Don't lock transitive dependencies using submodules
When Carthage checks out Swish into a project, it also recursively copies its submodules. This means that even if Carthage finds a more recent version of Result or Argo, when Swish is built it will always link against the version in the submodule.
If the app and Swish are linked against two different versions of the same dependency, the app may crash on launch when looking up symbols.
This change now ignores Cartfile.resolved, and stops using submodules, so that Swish can dynamically be linked against any compatible version that the app uses, rather than a specific submodule revision.
Here's the linker error I was seeing:
- App is using the current version of Result, 2.1.0
- Swish has 2.0.0 checked out via submodule
- The two releases are source compatible, but the
>>-operator has moved fromResultto theResultTypeprotocol - When building, Swish is linked against 2.0.0 but 2.1.0 is what's embedded in the app
- At load time, Swish is expecting
>>-to be defined onResult, but it's actually on the protocol. From a runtime perspective this wouldn't be a problem (because the type still ultimately adopts the protocol and thus has access to that operator), but things are screwed up. I have no idea if this would be considered a compiler bug, but it might be worth raising an issue for it.
I'm generally in favor of removing the submodules, but I believe this might break the build for people using git submodules themselves as a dependency management solution? If it doesn't, we'll almost certainly need to update the submodule instructions to match the new reality. Can we confirm one way or another before moving forward with this?
...but I believe this might break the build for people using git submodules themselves as a dependency management solution?
Right, that's something I hadn't thought of—the issue being that for non-Carthage users, transitive dependencies are no longer automatically included?
I believe that a manual, submodules-only approach should still be possible the same way Carthage manages it for you: add each transitive dependency to your project as a submodule, using an Xcode workspace to build all the dependencies together. The difference is that previously a recursive submodule update would check out the transitive deps for you.
I think I have an idea for an alternative solution: what if we could either a) not check in Swish's workspace file, or b) move it out of the way so that Carthage only uses the Swish.xcodeproj to build? That way the submodules could still be a part of the project tree, but would never be seen by a Carthage build.
Hope that makes sense 😅
FWIW: this is currently breaking a project of mine, but I can think of a less invasive workaround to this problem. If we updated Result to 2.1.0 and then put out a patch release, the issue would disappear for now.
Why get rid of the workspace?
I think that I'm 👍 on this if the only real change is removing submodules.
@gfontenot I was still having issues trying to resolve this problem today and these latest commits were my attempts to get there. To summarise:
- The issue with the workspace is a) with the submodules removed, the sources for transitive dependencies are no longer checked out; b) Carthage always favours building from a workspace over a project; and c) building from the workspace was failing because the dependent projects weren't checked out.
- After deleting the workspace to try coax Carthage into building the project instead (using the shared, prebuilt binaries from the symlinked
Carthage/Builddirectory), I ran into the old chestnut of Quick & Nimble failing to build for tvOS.
So I'm kind of confused at this point. I ended up working around the linker error in my project by replacing Carthage binaries with workspace dependencies and letting Xcode build everything itself at the same time.