cocoapods-binary-cache
cocoapods-binary-cache copied to clipboard
[Idea] Centralized Cache
I really love your plugin and its a massive time saver :blush:
I just want to share my basic idea which would lead to a massive change in the architecture and workflow of the plugin. On the other hand I could bring use a centralized cache :)
I would be nice I you could share your thoughts on this.
Workaround for Realm
I had some trouble with Realm (https://github.com/grab/cocoapods-binary-cache/issues/57). While I was not able to resolve these issues I reworked them by creating a "binary pod" of Realm.
I prebuilt it myself (which is pretty easy but a manual task...) and put it on a interal git repo, than I created a Podspec which uses the internal podspec repo together with the offical cdn repo. By this the official Realm/RealmSwift Pod is overruled with my internal binary version. The clou: I also use RxRealm, which depends on RealmSwift. By overriding the dependency with a binary version, the pod resolution still works. This "workaround" made me thinking, if we could create a more global, not project specific binary cache. The global cache could work more like a maven repository.
A few preconditions for this, for making the cache relatively stable:
- host xcframeworks
- build all archs
- build with library evolution support
I've built my binary repo with this basic scheme, mirroring the podspec repo: PodName/Version/PodName.xcframework.zip
i.e: Realm/10.5.1/Realm.xcframeworks.zip RealmSwift/10.5.1/RealmSwift.xcframework.zip
I created Podspecs like these:
Pod::Spec.new do |s|
s.name = 'Realm'
s.version = '10.5.1'
....
s.platform = :ios, '11.0'
s.source = { git: 'binary_pods.git' }
s.ios.vendored_frameworks = "#{s.name}/#{s.version}/#{s.name}.xcframework"
end
In the Podfile there are two ways to use this:
pod 'Realm', '10.5.1', source: 'cocoapods_binary_specs.git'
or
source: 'cocoapods_binary_specs.git'
pod 'Realm', '10.5.1'
However this will trigger a warning, that i.e. the Realm pod is found multiple sources. This can be silenced with by setting warn_for_multiple_pod_sources
.
This is just a basic example, but it shows how we could basicly overwrite any source code dependency with a binary verison.
Basic proposal
Currently we have a binary cache per project, which cannot be versioned. Cached artifacts, cannot be shared. We have nothing like a "maven repository". I want to keep the changes to the podfile minimal by only adding a new source (no explicit pod_binary).
pod binary prebuild --push
behavior:
option 1, prebuild all pods:
- builds all dependencies as xcframeworks for a specific Podfile
- searches all pods and find dependencies
- tries to build every pod
option 2, prebuild a single pod:
pod binary prebuild --push Resolver:1.4.0
find a pod and build that exact version.
also build all dependencies of the pod.
- binaries are added versioned (like Realm/10.5.1/Realm.xcframeworks.zip) to the central cache
- create binary Podspecs and push them to cocoapods_binary_specs.git
- add transitive dependencies to the generated binary Podspecs
Usage
- Podfile has an additional source i.e. source: 'cocoapods_binary_specs.git'
- now "binary_pod" function would be used explicitly
- cocoapods_binary_pods would not integrate the xcframework itself, since the specs from cocoapods_binary_specs are used
Hi @savage7, You brought up a very interesting idea. And it is actually similar to one of our items for improvements in the long term:
- The cache frameworks are hosted somewhere else, in a store (like CDN). This store can be shared across projects depending on your needs.
- The
cache_repo
git repo only contains metadata and files other than prebuilt frameworks, just enough for cache validation. This helps reduce the time to fetch cache because only cache-hit frameworks should be fetched.
So, I'd imagine it shall develop into that form in the long run.
However, I think we need to emphasize that the prebuilt frameworks are still specific to the project because those frameworks are built with a specific configuration (Debug/Release), project build settings, and very much affected by the custom build settings (if set) by Podfile pre_install/post_install
hooks.
For example, if the pre_install/post_install
hook in Podfile sets a framework as static like this:
pre_install do |installer|
installer.pods_project.targets.each do |target|
make_static(target)
end
end
Then the prebuilt framework should be a static framework, and hence, cannot be used in other projects that require it to be dynamic.
Therefore, the idea of a centralized cache store could be adopted but please keep in mind the constraint above for the global cache setup.