Skip to content

Pod build frameworks - #765

Merged
ekharkunov merged 14 commits into
devfrom
pod-build-frameworks
Aug 23, 2025
Merged

Pod build frameworks#765
ekharkunov merged 14 commits into
devfrom
pod-build-frameworks

Conversation

@ekharkunov

@ekharkunov ekharkunov commented Aug 13, 2025

Copy link
Copy Markdown
Contributor

Added method to build Cocoapods dependencies as framework. Initially it should solve problem that Firebase libraries can't be built if use_frameworks! flag is not used in Podfile.

Technical details

Main

Now every Project can specify in its Podfile use_frameworks! flags which we detect and added to the final Podfile used for dependency resolution. By default use_frameworks == true for now because it was old behaviour and it can be changed after updating Firebase extensions with that flag During cocoapods dependency resolution we check is use_frameworks!` is presented and have two code paths to build dependency: as static library or as framework.

Framework build consist of:

  1. Create framework structure: Headers and Modules directories.
  2. Copying public headers to Headers directories
  3. Copying modulemap which was generated by Cocoapods (from Target Support Files) to Modules
  4. Copying umbrella headers which was generated by Cocoapods to Headers
  5. Generated VFS and header map for current framework
  6. Build library. As header search path uses generated header map. For module-related stuff we pass -F<path_to_current_framework>. Additionally we pass generated VFS definition. It solves problem that compiler detect the same headers in different locations which leads to errors. VFS solves it. If framework has dependencies (defined in Pod spec) we merge generated GFS from that dependencies into current framework VFS (To be short, compiler will now where to find headers for dependencies).
  7. Copying result swiftmodule with correct name to the Modules directory
  8. Copying Swift compatibility header
  9. Updated copied modulemap with Swift module definition.
  10. Copying all resource bundles and resources to framework root.
  11. Generated Info.plist for framework from template which was generated by Cocoapods.
  12. Sign framework.

Virtual Filesystem (VFS) and Header maps

VFS overlay and Header maps are Apple private formats which used for compile-time optimizations. VFS is a list of mappings where files used for compilation (headers) are located in the real FS. Header map is the similar mappings but it defined where to find header for different include format ("" and <>). Header map is a binary format that's why for generation I used a third-party tool hmap (installed from brew). Initially I generated headermap in json format and than convert it to binary. In headermap I include all public headers in 2 variants: "SomeHeader.h" and <SomeFramework/SomeHeader.h>. For private headers - only "" format. It solves problem when inside dependency code headers include differently - in one place via <>; in other - via "".
Also those two files should helps to avoid excessive disk operation for searching headers and as a result - faster compilation.

Other notes

  • For Extender and CocoapodsService I introduced so-called "State" class which contains some values that should be used across all build process. For example, paths to build and intermediate directories. Those state passed into different build method which helps to reduce overall amount of arguments.
  • Introduced PodBuildSpec. These class contains all runtime-generated information which is needed for compilation. PodSpec now contains only parsed from pod spec information, nothing else. Also PodBuildSpec has methods to add subspec if any of subspecs is defined in Podfile or during pod resolution. Now if several subspec are used they all accumulated (sources, resources, headers, flags) under one PodBuildSpec with name of main PodSpec. During the build we iterate and build PodBuildSpec (which can contains several subspec). It solves problem that several subspec should be united and presented as one static library inside framework (for example, KSCrash). When we built as static library - it doesn't matter are they separate libraries or not.
  • ResolvedPods now collects all frameworks, search paths, etc. when it's initialized and used that information during build in opposite of collecting every time when information is needed. So if someone wants to update search paths during the build - it may be ignored.
  • For backward compatibility I added several places (marked with // **********************) which updates compiler command for old versions of build.yml

Fixes #733

@github-actions

github-actions Bot commented Aug 20, 2025

Copy link
Copy Markdown

Summary - Extender code coverage report

Summary
Generated on: 08/21/2025 - 11:38:14
Coverage date: 08/21/2025 - 11:37:53
Parser: JaCoCo
Assemblies: 13
Classes: 79
Files: 79
Line coverage: 30.2% (1637 of 5407)
Covered lines: 1637
Uncovered lines: 3770
Coverable lines: 5407
Total lines: 11093
Branch coverage: 33% (665 of 2013)
Covered branches: 665
Total branches: 2013
Method coverage: Feature is only available for sponsors
Tag: 24_17125747527

Coverage

com/defold/extender - 26.4%
Name Line Branch
com/defold/extender 26.4% 29.5%
com/defold/extender/AppManifestConfiguration 100%
com/defold/extender/AppManifestPlatformConfig 100%
com/defold/extender/AsyncBuilder 0% 0%
com/defold/extender/BuilderConstants 0%
com/defold/extender/Configuration 100%
com/defold/extender/Extender 11.2% 10.3%
com/defold/extender/ExtenderApplication 0%
com/defold/extender/ExtenderBuildState 63.1% 57.1%
com/defold/extender/ExtenderController 21.2% 24.3%
com/defold/extender/ExtenderException 42.8%
com/defold/extender/ExtenderUtil 67.1% 57.3%
com/defold/extender/ExtenderYamlSafeConstructor 100%
com/defold/extender/ExtensionManifestValidator 69.5% 55%
com/defold/extender/ManifestConfiguration 100%
com/defold/extender/ManifestPlatformConfig 100%
com/defold/extender/PlatformConfig 100%
com/defold/extender/TemplateExecutor 33.3% 50%
com/defold/extender/Timer 0%
com/defold/extender/TreePrinter 0% 0%
com/defold/extender/Version 0%
com/defold/extender/WebSecurityConfig 0% 0%
com/defold/extender/WhitelistConfig 100%
com/defold/extender/ZipUtils 64.9% 56.6%
com/defold/extender/builders - 0%
Name Line Branch
com/defold/extender/builders 0% 0%
com/defold/extender/builders/CSharpBuilder 0% 0%
com/defold/extender/cache - 35.4%
Name Line Branch
com/defold/extender/cache 35.4% 9.3%
com/defold/extender/cache/CacheEntry 100%
com/defold/extender/cache/CacheKeyGenerator 81.8% 100%
com/defold/extender/cache/DataCache
com/defold/extender/cache/DataCacheException 0%
com/defold/extender/cache/DataCacheFactory 0% 0%
com/defold/extender/cache/DummyDataCache 80%
com/defold/extender/cache/GCPDataCache 0% 0%
com/defold/extender/cache/LocalDiskDataCache 64.7% 16.6%
com/defold/extender/cache/info - 100%
Name Line Branch
com/defold/extender/cache/info 100% ****
com/defold/extender/cache/info/CacheInfoFileParser 100%
com/defold/extender/cache/info/CacheInfoFileWriter 100%
com/defold/extender/cache/info/CacheInfoWrapper 100%
com/defold/extender/log - 0%
Name Line Branch
com/defold/extender/log 0% 0%
com/defold/extender/log/ExtenderLogEnhancer 0% 0%
com/defold/extender/log/ExtenderLogEnhancerConfiguration 0% 0%
com/defold/extender/log/Markers 0%
com/defold/extender/metrics - 7.4%
Name Line Branch
com/defold/extender/metrics 7.4% ****
com/defold/extender/metrics/MetricsWriter 7.4%
com/defold/extender/process - 10.4%
Name Line Branch
com/defold/extender/process 10.4% 7.1%
com/defold/extender/process/ProcessExecutor 12.3% 8.8%
com/defold/extender/process/ProcessUtils 0% 0%
com/defold/extender/remote - 0%
Name Line Branch
com/defold/extender/remote 0% 0%
com/defold/extender/remote/RemoteBuildException 0%
com/defold/extender/remote/RemoteEngineBuilder 0% 0%
com/defold/extender/remote/RemoteHostConfiguration 0%
com/defold/extender/remote/RemoteInstanceConfig 0%
com/defold/extender/services - 23.9%
Name Line Branch
com/defold/extender/services 23.9% 24.3%
com/defold/extender/services/DataCacheService 0% 0%
com/defold/extender/services/DefoldSdkService 78% 66.6%
com/defold/extender/services/DefoldSdkServiceConfiguration
com/defold/extender/services/GCPInstanceService 0% 0%
com/defold/extender/services/GradleService 0%
com/defold/extender/services/GradleServiceInterface
com/defold/extender/services/HealthReporterService 0% 0%
com/defold/extender/services/MockGradleService 0%
com/defold/extender/services/RealGradleService 0% 0%
com/defold/extender/services/UserUpdateService 0% 0%
com/defold/extender/services/cocoapods - 50.3%
Name Line Branch
com/defold/extender/services/cocoapods 50.3% 52.4%
com/defold/extender/services/cocoapods/CocoaPodsService 2.1% 1.8%
com/defold/extender/services/cocoapods/CocoaPodsServiceBuildState 16.6% 0%
com/defold/extender/services/cocoapods/CreateBuildSpecArgs 60.7%
com/defold/extender/services/cocoapods/IConfigParser
com/defold/extender/services/cocoapods/LanguageSet 66.6% 50%
com/defold/extender/services/cocoapods/MainPodfile 20%
com/defold/extender/services/cocoapods/PlatformAndLanguageSet 0% 0%
com/defold/extender/services/cocoapods/PlatformSet 0% 0%
com/defold/extender/services/cocoapods/PlistBuddyWrapper 0% 0%
com/defold/extender/services/cocoapods/PodBuildSpec 77.1% 58.7%
com/defold/extender/services/cocoapods/PodfileParser 92.8% 81.8%
com/defold/extender/services/cocoapods/PodfileParsingException 100%
com/defold/extender/services/cocoapods/PodSpec 52% 10%
com/defold/extender/services/cocoapods/PodSpecParser 89.4% 78.7%
com/defold/extender/services/cocoapods/PodUtils 63% 51.4%
com/defold/extender/services/cocoapods/ResolvedPods 52.7% 45.6%
com/defold/extender/services/cocoapods/XCConfigParser 94.6% 88.4%
com/defold/extender/services/data - 80.7%
Name Line Branch
com/defold/extender/services/data 80.7% 75%
com/defold/extender/services/data/DefoldSdk 87.5% 75%
com/defold/extender/services/data/GCPInstanceState 0%
com/defold/extender/tracing - 0%
Name Line Branch
com/defold/extender/tracing 0% 0%
com/defold/extender/tracing/ExtenderExecutor 0% 0%
com/defold/extender/tracing/ExtenderTracerInterceptor 0% 0%
com/defold/extender/tracing/TraceIdInResponseServletFilter 0% 0%
com/defold/extender/utils - 0%
Name Line Branch
com/defold/extender/utils 0% 0%
com/defold/extender/utils/FrameworkUtil 0% 0%
com/defold/extender/utils/PodBuildUtil 0% 0%

@ekharkunov
ekharkunov requested a review from britzl August 21, 2025 12:30
@ekharkunov
ekharkunov marked this pull request as ready for review August 21, 2025 12:30
@ekharkunov
ekharkunov merged commit 61ba95a into dev Aug 23, 2025
1 check passed
@ekharkunov
ekharkunov deleted the pod-build-frameworks branch August 23, 2025 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cocoapods dependencies not being built

2 participants