[英]iOS: How to build a static framework based on CocoaPods dependencies?
I am trying to build a framework that makes use of the geopackage-ios
CocoaPods dependency.我正在尝试构建一个使用
geopackage-ios
CocoaPods 依赖项的框架。 I would then like to statically embed this framework into one or more apps.然后我想将此框架静态嵌入到一个或多个应用程序中。
Similar questions have been asked before, but I couldn't find a solution to my problem.以前也有人问过类似的问题,但我找不到解决问题的方法。 Here's what I've been trying so far:
这是我到目前为止一直在尝试的:
First Approach: Building Manually第一种方法:手动构建
In this approach, I would create a static library using Xcode, add the CocoaPods dependencies to it and build it.在这种方法中,我将使用 Xcode 创建一个静态库,向其中添加 CocoaPods 依赖项并构建它。 The problem with this approach, however, is that the resulting framework will not have the CocoaPods dependencies embedded into it.
然而,这种方法的问题是生成的框架不会嵌入 CocoaPods 依赖项。
Podfile
in the project root directory with the following content:Podfile
,内容如下:target 'MyLibrary' do
pod 'geopackage-ios', '~> 7.2.1'
end
pod install
.pod install
。 (This will install the geopackage-ios
pod and 10 depending pods.) geopackage-ios
pod 和 10 个依赖的 pod。)MyLibrary.xcworkspace
and add a BridgingHeader.h
to the "MyLibrary" group having the following content:MyLibrary.xcworkspace
并将BridgingHeader.h
添加到具有以下内容的“MyLibrary”组:#ifndef BridgingHeader_h
#define BridgingHeader_h
#import "geopackage-ios-Bridging-Header.h"
#endif
MyLibrary/BridgingHeader.h
as the "Objective-C Bridging Header".MyLibrary/BridgingHeader.h
指定为“Objective-C Bridging Header”来引用桥接头。MyLibrary.swift
to use the GeoPackage dependency:MyLibrary.swift
以使用 GeoPackage 依赖项:public class MyLibrary {
public init() {}
public func test() {
let manager = GPKGGeoPackageFactory.manager()!
print("Manager:", manager)
}
}
Cmd + B
.Cmd + B
为 iOS 模拟器构建库。lipo
command).lipo
命令将这两个结果组合到一个通用框架)。 When I embed either the static library (along with the MyLibrary.swiftmodule
) or the universal framework into an app, linking will fail for this app:当我将静态库(连同
MyLibrary.swiftmodule
)或通用框架嵌入到应用程序中时,此应用程序的链接将失败:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_GPKGGeoPackageManager", referenced from:
objc-class-ref in libMyLibrary.a(MyLibrary.o)
"_OBJC_CLASS_$_GPKGGeoPackageFactory", referenced from:
objc-class-ref in libMyLibrary.a(MyLibrary.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I could also add the geopackage_ios.framework
(found in the build folder of "MyLibrary") to the app (making sure to choose the Embed & Sign embedding option), which will allow the app to be built successfully.我还可以将
geopackage_ios.framework
(位于“MyLibrary”的构建文件夹中)添加到应用程序(确保选择嵌入和签名嵌入选项),这将允许成功构建应用程序。 Then, however, the app will crash upon launch:但是,该应用程序将在启动时崩溃:
dyld[79209]: Library not loaded: @rpath/ogc_api_features_json_ios.framework/ogc_api_features_json_ios
Referenced from: /Users/admin1/Library/Developer/CoreSimulator/Devices/C3D61224-CFE8-45CC-951B-7B6AB54BC8B3/data/Containers/Bundle/Application/D41A82D6-4E69-4BB6-AC59-6BC28AE58795/TestApp.app/Frameworks/geopackage_ios.framework/geopackage_ios
One might be able to fix this by adding all eleven pod frameworks to the app, which, however, is what I'm trying to avoid.可以通过将所有 11 个 pod 框架添加到应用程序来解决此问题,但是,这是我试图避免的。
Second Approach: Using PodBuilder第二种方法:使用 PodBuilder
A second approach would be to use PodBuilder
, which aims at automating this particular kind of build task.第二种方法是使用
PodBuilder
,它旨在自动化这种特定类型的构建任务。 This approach, however, fails with a build error, the cause of which I can't quite make out.然而,这种方法因构建错误而失败,我无法完全确定其原因。
Podfile
with almost the same content as above:Podfile
:use_frameworks!
target 'MyApp' do
pod 'geopackage-ios', '~> 7.2.1'
end
pod install
.pod install
。sudo gem install pod-builder
git init
pod_builder init
pod_builder build geopackage-ios
/tmp/pod_builder/pod_builder.err
:/tmp/pod_builder/pod_builder.err
:Undefined symbols for architecture arm64:
"_PROJ_WEB_MERCATOR_MAX_LAT_RANGE", referenced from:
+[GPKGTileBoundingBoxUtils toWebMercatorWithBoundingBox:] in GPKGTileBoundingBoxUtils.o
+[GPKGTileBoundingBoxUtils boundDegreesBoundingBoxWithWebMercatorLimits:] in GPKGTileBoundingBoxUtils.o
-[GPKGTileDao isXYZTiles] in GPKGTileDao.o
-[GPKGTileGenerator adjustXYZBounds] in GPKGTileGenerator.o
"_PROJ_UNDEFINED_CARTESIAN", referenced from:
-[GPKGSpatialReferenceSystemDao createIfNeededWithSrs:andOrganization:andCoordsysId:] in GPKGSpatialReferenceSystemDao.o
"_PROJ_AUTHORITY_NONE", referenced from:
-[GPKGSpatialReferenceSystemDao createIfNeededWithSrs:andOrganization:andCoordsysId:] in GPKGSpatialReferenceSystemDao.o
[…]
geopackage-ios
pod itself, which can be fixed by cloning our own version of the repo …geopackage-ios
pod 本身的问题,可以通过克隆我们自己的 repo 版本来解决……cd ..
git clone --branch 7.2.1 https://github.com/ngageoint/geopackage-ios.git
cd geopackage-ios
pod install
proj-ios
source files … proj-ios
源文件 …cp -r Pods/proj-ios/proj-ios geopackage-ios
…, and opening the geopackage-ios.xcodeproj
to reference the proj-ios
files in the geopackage-ios
group inside that project. ...,并打开
geopackage-ios.xcodeproj
以引用该项目内geopackage-ios
组中的proj-ios
文件。
Then telling CocoaPods to use our local version of the pod …然后告诉 CocoaPods 使用我们本地版本的 pod……
use_frameworks!
target 'MyApp' do
pod 'geopackage-ios', :path => '../geopackage-ios'
end
cd ../MyApp
pod_builder deintegrate
pod deintegrate
pod install
pod_builder init
./PodBuilder/PodBuilder.json
file: ./PodBuilder/PodBuilder.json
文件来使用本地 pod:{
…,
"allow_building_development_pods": true,
…
}
pod_builder build geopackage-ios
This time, the build will fail with a different error:这一次,构建将失败并出现不同的错误:
The following build commands failed:
CompileC /tmp/pod_builder/build/Pods.build/Release-iphoneos/sf-proj-ios.build/Objects-normal/arm64/SFPGeometryTransform.o /tmp/pod_builder/Pods/sf-proj-ios/sf-proj-ios/SFPGeometryTransform.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler (in target 'sf-proj-ios' from project 'Pods')
(1 failure)
The SFPGeometryTransform.m
file, however, looks fine.然而,
SFPGeometryTransform.m
文件看起来不错。
The full build log is available here .完整的构建日志可在此处获得。
Third Approach: Using Rome第三种方法:使用罗马
The third approach would be to use cocoapods-rome
.第三种方法是使用
cocoapods-rome
。
sudo gem install cocoapods-rome
pod_builder deintegrate
pod deintegrate
Podfile
: Podfile
:use_frameworks!
platform :ios, '13.0'
plugin 'cocoapods-rome', { :pre_compile => Proc.new { |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '5.0'
end
end
installer.pods_project.save
},
dsym: false,
configuration: 'Release'
}
target 'MyApp' do
pod 'geopackage-ios', :path => '../geopackage-ios'
end
pod install
This, however, will fail with the exact same error as PodBuilder.但是,这将失败,并出现与 PodBuilder 完全相同的错误。
Can anyone give me some advice on any of these approaches?任何人都可以就这些方法中的任何一种给我一些建议吗? Or does anyone perhaps have a whole different idea on how to build such a framework?
或者是否有人对如何构建这样一个框架有完全不同的想法?
(EDIT: It seems like the PROJProjectionTransform.h
file imported to SFPGeometryTransform.m
cannot be found. Anyway, I don't think these approaches are expedient. So any help is highly appreciated.) (编辑:似乎找不到导入到
SFPGeometryTransform.m
的PROJProjectionTransform.h
文件。无论如何,我认为这些方法并不方便。因此,非常感谢任何帮助。)
Solved the problem by simply feeding all the aggregated source files from the pod installation into a new static library, then using either the lipo command to make a fat binary out of it or creating an Xcode framework from it (as described here ).通过简单地将pod 安装中的所有聚合源文件输入到一个新的静态库中,然后使用lipo命令从中生成一个胖二进制文件或从中创建一个 Xcode 框架来解决该问题(如此处所述)。 The compiled framework could then be used to create another framework built on top of it.
然后可以使用编译的框架来创建另一个构建在它之上的框架。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.