我正在尝试构建一个框架,该框架使用 geopackage-ios
a> cocoapods依赖性。然后,我想将此框架静态嵌入到一个或多个应用程序中。
之前已经提出过类似的问题,但我找不到解决问题的方法。这是我到目前为止一直在尝试的方法:
第一种方法:
在这种方法中手动构建,我将使用Xcode创建一个静态库,将CocoApods依赖性添加到其上并构建。但是,这种方法的问题在于,由此产生的框架将不会将可可脚类依赖性嵌入其中。
- 从Xcode( file> new> project…> ios:static库)中创建一个新的静态库,名为“ mylibrary”,language swift。
- 在项目根目录中创建
podfile
,其中包含以下内容:
target 'MyLibrary' do
pod 'geopackage-ios', '~> 7.2.1'
end
- run
pod install
。 (这将安装 geopackage-ios
pod和10个根据豆荚。)
- 打开新创建的
myLibrary.xcworkspace
,然后添加 bridgingheader.h
具有以下内容的“ mylibrary”组:
#ifndef BridgingHeader_h
#define BridgingHeader_h
#import "geopackage-ios-Bridging-Header.h"
#endif
- 通过单击项目Navigator中的“ mylibrary”项目参考桥接标头,选择“ mylibrary”目标,以及在 build build settings 中,指定
> mylibrary/bridgingheader.h
作为“ Objective-C Bridging标头”。
- 修改
mylibrary.swift
使用geopackage依赖关系:
public class MyLibrary {
public init() {}
public func test() {
let manager = GPKGGeoPackageFactory.manager()!
print("Manager:", manager)
}
}
- 通过按
cmd + b
来构建iOS模拟器库。
- 可选地,使用本文(它将为模拟器编译一次库,一次用于物理设备,然后使用
lipo 命令)。
当我将静态库(以及 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)
我还可以添加 geopackage_ios.framework (在应用程序的“ mylibrary”的构建文件夹中找到)到该应用程序(确保选择 emp; amp; amp; emp; em>嵌入式选项),这将允许成功构建应用程序。但是,该应用将在启动时崩溃:
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
一个人可以通过将所有11个POD框架添加到应用程序中来解决此问题,但是,这是我要避免的。
第二种方法:使用podbuilder
第二种方法是使用 ,旨在自动执行此特定的构建任务。但是,这种方法因构建错误而失败,这是我无法完全理解的原因。
- 同样,我将从一个新的Xcode项目开始。这次,我将创建一个名为“ MyApp”的iOS Swift应用程序。
- 我将创建一个
podfile
,几乎与上面的内容相同:
use_frameworks!
target 'MyApp' do
pod 'geopackage-ios', '~> 7.2.1'
end
- 然后,我将运行
pod install
。
- 接下来,我将安装podbuilder,创建一个空的git存储库(出于某种原因需要该存储库),初始化podbuilder,然后启动构建任务:
sudo gem install pod-builder
git init
pod_builder init
pod_builder build geopackage-ios
- 构建将失败,但是,类似这样的错误将其写入
/tmp/pod_builderderderdem /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本身的问题,可以通过克隆我们自己的repo………
cd ..
git clone --branch 7.2.1 https://github.com/ngageoint/geopackage-ios.git
- ,安装吊舱
cd geopackage-ios
pod install
- ……………………手动复制
proj-ios
源文件…
cp -r Pods/proj-ios/proj-ios geopackage-ios
-
…,并打开 geopackage-ios.xcodeproj
以引用 proj-ios
文件在该项目中的 geopackage-ios
组中。
-
然后告诉Cocoapods使用我们的本地版本的POD…
use_frameworks!
target 'MyApp' do
pod 'geopackage-ios', :path => '../geopackage-ios'
end
- ,重新定性podbuilder
cd ../MyApp
pod_builder deintegrate
pod deintegrate
pod install
pod_builder init
- 使用
。
{
…,
"allow_building_development_pods": true,
…
}
- …………并允许podbuilder编辑
./ podbuilder/podbuilder.json.json
文件:然后,一个人可以尝试尝试,一个人可以尝试尝试,一个人可以尝试尝试,一个人可以尝试试图尝试,一个人可以尝试试图尝试,一个人可以尝试尝试,一个人可以尝试尝试,一个人可以尝试尝试 重建:
pod_builder build geopackage-ios
这次,构建将失败,并以不同的错误失败:
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)
sfpgeometrytransform.m
文件看起来不错。
The full build log is available here.
第三种方法:使用罗马
第三种方法是使用 cocoapods-rome < /代码>
。
- 要使用它,一个人会安装罗马……
sudo gem install cocoapods-rome
- ,摆脱podbuilder的东西……
pod_builder deintegrate
pod deintegrate
- ,快速调整
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
- …并安装pods:
pod install
但是,这种错误将失败,并且与完全相同的错误失败Podbuilder。
谁能就这些方法给我一些建议?还是有人对如何构建这样的框架有完全不同的想法?
(编辑:看起来像 projproctiveTransform.h
导入到 sfppeometrytransform.m
的文件。无论如何,我认为这些方法都不是权宜的。高度赞赏。)
I am trying to build a framework that makes use of the geopackage-ios
CocoaPods dependency. 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. The problem with this approach, however, is that the resulting framework will not have the CocoaPods dependencies embedded into it.
- Create a new static library from Xcode (File > New > Project… > iOS: Static Library) named "MyLibrary" with language Swift.
- Create a
Podfile
in the project root directory with the following content:
target 'MyLibrary' do
pod 'geopackage-ios', '~> 7.2.1'
end
- Run
pod install
. (This will install the geopackage-ios
pod and 10 depending pods.)
- Open the newly created
MyLibrary.xcworkspace
and add a BridgingHeader.h
to the "MyLibrary" group having the following content:
#ifndef BridgingHeader_h
#define BridgingHeader_h
#import "geopackage-ios-Bridging-Header.h"
#endif
- Reference the bridging header by clicking on the "MyLibrary" project in the project navigator, selecting the "MyLibrary" target and, in the Build Settings, specifying
MyLibrary/BridgingHeader.h
as the "Objective-C Bridging Header".
- Modify
MyLibrary.swift
to use the GeoPackage dependency:
public class MyLibrary {
public init() {}
public func test() {
let manager = GPKGGeoPackageFactory.manager()!
print("Manager:", manager)
}
}
- Build the library for the iOS simulator by pressing
Cmd + B
.
- Optionally, create a static framework using a shell script like the one in this article (which will compile the library once for the simulator and once for physical devices and then combine the two results to a universal framework using the
lipo
command).
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:
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. 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.
Second Approach: Using PodBuilder
A second approach would be to use PodBuilder
, which aims at automating this particular kind of build task. This approach, however, fails with a build error, the cause of which I can't quite make out.
- Again, I would start out with a new Xcode project. This time, I'd create an iOS Swift app named "MyApp".
- I would create a
Podfile
with almost the same content as above:
use_frameworks!
target 'MyApp' do
pod 'geopackage-ios', '~> 7.2.1'
end
- Then, I'd run
pod install
.
- Next, I would install PodBuilder, create an empty Git repository (which PodBuilder requires for some reason), initialize PodBuilder, and start the build task:
sudo gem install pod-builder
git init
pod_builder init
pod_builder build geopackage-ios
- The build will fail, however, with errors like these written to
/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
[…]
- This seems to be a problem with the
geopackage-ios
pod itself, which can be fixed by cloning our own version of the repo …
cd ..
git clone --branch 7.2.1 https://github.com/ngageoint/geopackage-ios.git
- …, installing the pods …
cd geopackage-ios
pod install
- … manually copying the
proj-ios
source files …
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.
-
Then telling CocoaPods to use our local version of the pod …
use_frameworks!
target 'MyApp' do
pod 'geopackage-ios', :path => '../geopackage-ios'
end
- …, reinitializing PodBuilder …
cd ../MyApp
pod_builder deintegrate
pod deintegrate
pod install
pod_builder init
- … and allowing PodBuilder to use local pods by editing the
./PodBuilder/PodBuilder.json
file:
{
…,
"allow_building_development_pods": true,
…
}
- Then, one can try to rebuild:
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.
The full build log is available here.
Third Approach: Using Rome
The third approach would be to use cocoapods-rome
.
- To use it, one would install Rome …
sudo gem install cocoapods-rome
- …, get rid of the PodBuilder stuff …
pod_builder deintegrate
pod deintegrate
- …, quickly adjust the
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
- … and install the pods:
pod install
This, however, will fail with the exact same error as 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.)
发布评论
评论(1)
通过简单地将所有汇总的源文件从 pod安装中馈送到新的静态库中,然后使用 lipo 命令来解决问题,从而解决了问题。 creating an Xcode framework from it (as described here).然后,可以使用编译的框架来创建另一个在其顶部构建的框架。
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). The compiled framework could then be used to create another framework built on top of it.