cocoapods-imy-bin 0.2.2 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +0 -540
- data/lib/cocoapods-imy-bin/command/bin/archive.rb +11 -3
- data/lib/cocoapods-imy-bin/command/bin/auto.rb +5 -1
- data/lib/cocoapods-imy-bin/command/bin/code.rb +1 -6
- data/lib/cocoapods-imy-bin/command/bin/update.rb +15 -9
- data/lib/cocoapods-imy-bin/gem_version.rb +1 -1
- data/lib/cocoapods-imy-bin/helpers/build_helper.rb +1 -1
- data/lib/cocoapods-imy-bin/helpers/framework_builder.rb +157 -117
- data/lib/cocoapods-imy-bin/helpers/library.rb +2 -2
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 52e4a6a4fb317bc8d4401fe5e14d842e062a26c44fe211c19fc8492d93e3ef68
|
4
|
+
data.tar.gz: e7ce061e032588ddc28ea6d9348426464eaf8a2bef89f449b92f59fe25a1bad4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b875bfa26b32c532f4b25559c4e4320ecab97edf2263bb889dd60576a2463b566af00b9448ee38d8e8240ebab82c640159c0ef1dfb2fb043819e5f396216d0e
|
7
|
+
data.tar.gz: c8c6e6d2a46c4168b6e655326d625b0257ace4649cc2702564cca90ff4e8aa43c15f9cfeee3f40fac699eb47245a0e383a626ca18b92a0bfaeffc7138b7e3a24
|
data/README.md
CHANGED
@@ -1,541 +1 @@
|
|
1
|
-
# cocoapods-bin
|
2
|
-
|
3
|
-
组件二进制化插件。
|
4
|
-
|
5
|
-
[基于 CocoaPods 的组件二进制化实践](https://triplecc.github.io/2019/01/21/%E5%9F%BA%E4%BA%8ECocoaPods%E7%9A%84%E7%BB%84%E4%BB%B6%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%8C%96%E5%AE%9E%E8%B7%B5/)
|
6
|
-
|
7
|
-
[Demo 工程](https://github.com/for-example-test/cocoapods-bin-example)
|
8
|
-
|
9
|
-
## 更新
|
10
|
-
|
11
|
-
#### 0.1.28
|
12
|
-
|
13
|
-
新增本地组件依赖配置文件 BinPodfile ,
|
14
|
-
|
15
|
-
场景: 不希望把本地采用的源码/二进制配置传到远程仓库。
|
16
|
-
|
17
|
-
使用: 在 Podfile 同级目录下创建 BinPodfile ,并将其加入 .gitignore 。BinPodfile 中的配置选项优先级比 Podfile 高,支持和 Podfile 相同的配置语句,如 :
|
18
|
-
|
19
|
-
```ruby
|
20
|
-
# BinPodfile
|
21
|
-
|
22
|
-
use_binaries!
|
23
|
-
set_use_source_pods ['YYModel']
|
24
|
-
|
25
|
-
```
|
26
|
-
|
27
|
-
|
28
|
-
## 概要
|
29
|
-
|
30
|
-
本插件所关联的组件二进制化策略:
|
31
|
-
|
32
|
-
预先将打包成 `.a` 或者 `.framework` 的组件(目前接入此插件必须使用 `.framework`,最好是静态 framework)保存到静态服务器上,并在 `install` 时,去下载组件对应的二进制版本,以减少组件编译时间,达到加快 App 打包、组件 lint、组件发布等操作的目的。
|
33
|
-
|
34
|
-
使用本插件需要提供以下资源:
|
35
|
-
|
36
|
-
- 静态资源服务器(可参考 [binary-server](https://github.com/tripleCC/binary-server.git))
|
37
|
-
- 源码私有源(保存组件源码版本 podspec)
|
38
|
-
- 二进制私有源(保存组件二进制版本 podspec)
|
39
|
-
|
40
|
-
在所有组件都依赖二进制版本的情况下,本插件支持切换指定组件的依赖版本。
|
41
|
-
|
42
|
-
推荐结合 GitLab CI 使用本插件,可以实现自动打包发布,并显著减少其 pipeline 耗时。关于 GitLab CI 的实践,可以参考 [火掌柜 iOS 团队 GitLab CI 集成实践](https://triplecc.github.io/2018/06/23/2018-06-23-ji-gitlabcide-ci-shi-jian/)。虽然后来对部分 stage 和脚本都进行了优化,但总体构建思路还是没变的。
|
43
|
-
|
44
|
-
## 准备工作
|
45
|
-
|
46
|
-
安装 `cocoapods-bin`:
|
47
|
-
|
48
|
-
$ gem install cocoapods-bin
|
49
|
-
|
50
|
-
初始化插件:
|
51
|
-
|
52
|
-
```shell
|
53
|
-
➜ ~ pod bin init
|
54
|
-
|
55
|
-
开始设置二进制化初始信息.
|
56
|
-
所有的信息都会保存在 /Users/songruiwang/.cocoapods/bin.yml 文件中.
|
57
|
-
你可以在对应目录下手动添加编辑该文件. 文件包含的配置信息样式如下:
|
58
|
-
|
59
|
-
---
|
60
|
-
code_repo_url: git@git.xxxxxx.net:ios/cocoapods-spec.git
|
61
|
-
binary_repo_url: git@git.xxxxxx.net:ios/cocoapods-spec-binary.git
|
62
|
-
binary_download_url: http://iosframeworkserver-shopkeeperclient.app.2dfire.com/download/%s/%s.zip
|
63
|
-
download_file_type: zip
|
64
|
-
|
65
|
-
|
66
|
-
源码私有源 Git 地址
|
67
|
-
旧值:git@git.xxxxxx.net:ios/cocoapods-spec.git
|
68
|
-
>
|
69
|
-
```
|
70
|
-
|
71
|
-
按提示输入源码私有源、二进制私有源、二进制下载地址、下载文件类型后,插件就配置完成了。其中 `binary_download_url` 需要预留组件名称与组件版本占位符,插件内部会依次替换 `%s` 为相应组件的值。
|
72
|
-
|
73
|
-
`cococapod-bin` 也支持从 url 下载配置文件,方便对多台机器进行配置:
|
74
|
-
|
75
|
-
```shell
|
76
|
-
➜ ~ pod bin init --bin-url=http://git.xxxxxx.net/qingmu/cocoapods-tdfire-binary-config/raw/master/bin.yml
|
77
|
-
```
|
78
|
-
|
79
|
-
配置文件模版内容如下,根据不同团队的需求定制即可:
|
80
|
-
|
81
|
-
```yaml
|
82
|
-
---
|
83
|
-
code_repo_url: git@git.xxxxxx.net:ios/cocoapods-spec.git
|
84
|
-
binary_repo_url: git@git.xxxxxx.net:ios/cocoapods-spec-binary.git
|
85
|
-
binary_download_url: http://iosframeworkserver-shopkeeperclient.app.2dfire.com/download/%s/%s.zip
|
86
|
-
download_file_type: zip
|
87
|
-
```
|
88
|
-
|
89
|
-
配置时,不需要手动添加源码和二进制私有源的 repo,插件在找不到对应 repo 时会主动 clone。
|
90
|
-
|
91
|
-
插件配置完后,就可以部署静态资源服务器了。对于静态资源服务器,这里不做赘述,只提示一点:在生成二进制 podspec 时,插件会根据 `download_file_type` 设置 source 的 `:type` 字段。在下载 http/https 资源时,CocoaPods 会根据 `:type` 字段的类型采取相应的解压方式,如果设置错误就会抛错。这里提到了 **二进制 podspec 的自动生成**,后面会详细介绍。
|
92
|
-
|
93
|
-
这里额外说下打包工具 [cocoapods-packager](https://github.com/CocoaPods/cocoapods-packager) 和 [Carthage](https://github.com/Carthage/Carthage/issues) ,前者可以通过 podspec 进行打包,只要保证 lint 通过了,就可以打成 `.framework`,很方便,但是作者几乎不维护了,后者需要结合组件工程。具体使用哪个可以结合自身团队,甚至可以自己写打包脚本,或者使用本插件的打包命令。
|
94
|
-
|
95
|
-
## 使用插件
|
96
|
-
|
97
|
-
接入二进制版本后,常规的发布流程需要做如下变更:
|
98
|
-
|
99
|
-
```shell
|
100
|
-
# 1 打出二进制产物 && 提交产物至静态文件服务器
|
101
|
-
pod bin archive YOUR_OPTIONS
|
102
|
-
curl xxxxxxx
|
103
|
-
|
104
|
-
# 2.1 发布二进制 podspec
|
105
|
-
pod bin repo push --binary YOUR_OPTIONS
|
106
|
-
|
107
|
-
# 2.2 发布源码 podspec
|
108
|
-
pod bin repo push YOUR_OPTIONS
|
109
|
-
```
|
110
|
-
|
111
|
-
如果团队内部集成了 CI 平台,那么上面的每大步都可以对应一个 CI stage,源码和二进制版本可并行发布,对应一个 stage 中的两个 job。
|
112
|
-
|
113
|
-
### 基本信息
|
114
|
-
|
115
|
-
`cocoapods-bin` 命令行信息可以输入以下命令查看:
|
116
|
-
|
117
|
-
```shell
|
118
|
-
➜ ~ pod bin --help
|
119
|
-
Usage:
|
120
|
-
|
121
|
-
$ pod bin [COMMAND]
|
122
|
-
|
123
|
-
组件二进制化插件。利用源码私有源与二进制私有源实现对组件依赖类型的切换。
|
124
|
-
|
125
|
-
Commands:
|
126
|
-
+ archive 将组件归档为静态 framework.
|
127
|
-
+ init 初始化插件.
|
128
|
-
+ lib 管理二进制 pod.
|
129
|
-
+ list 展示二进制 pods .
|
130
|
-
> open 打开 workspace 工程.
|
131
|
-
+ repo 管理 spec 仓库.
|
132
|
-
+ search 查找二进制 spec.
|
133
|
-
+ spec 管理二进制 spec.
|
134
|
-
+ umbrella 生成伞头文件 .
|
135
|
-
```
|
136
|
-
|
137
|
-
### 构建二进制产物
|
138
|
-
|
139
|
-
```shell
|
140
|
-
➜ ~ pod bin archive --help
|
141
|
-
Usage:
|
142
|
-
|
143
|
-
$ pod bin archive [NAME.podspec]
|
144
|
-
|
145
|
-
将组件归档为静态 framework,仅支持 iOS 平台 此静态 framework 不包含依赖组件的 symbol
|
146
|
-
|
147
|
-
Options:
|
148
|
-
|
149
|
-
--code-dependencies 使用源码依赖
|
150
|
-
--allow-prerelease 允许使用 prerelease 的版本
|
151
|
-
--use-modular-headers 使用 modular headers (modulemap)
|
152
|
-
--no-clean 保留构建中间产物
|
153
|
-
--no-zip 不压缩静态 framework 为 zip
|
154
|
-
...
|
155
|
-
```
|
156
|
-
|
157
|
-
`pod bin archive` 会根据 podspec 文件构建静态 framework ,此静态 framework 不会包含依赖组件的符号信息。命令内部利用 [cocoapods-generate](https://github.com/square/cocoapods-generate) 插件生成工程,并移植了 [cocoapods-packager](https://github.com/CocoaPods/cocoapods-packager) 插件的部分打包功能,以构建前者生成的工程,默认条件下,命令会生成一个 zip 压缩包。
|
158
|
-
|
159
|
-
### 二进制 podspec
|
160
|
-
|
161
|
-
`cocoapods-bin` 针对一个组件,同时使用了两种 podspec,分别为源码 podspec 和二进制 podspec,这种方式在没有工具支撑的情况下,势必会增加开发者维护组件的工作量。做为开发者来说,我是不希望同时维护两套 podspec 的。为了解决这个问题, 插件提供了自动生成二进制 podspec 功能,开发者依旧只需要关心源码 podspec 即可。
|
162
|
-
|
163
|
-
一般来说,在接入插件前,组件源码 podspec 是已经存在的,所以我们只需要向二进制私有源推送组件的二进制 podspec 即可。如果有条件的话,二进制和源码 podspec 的发布可以走 GitLab CI ,这也是我推荐的做法。
|
164
|
-
|
165
|
-
下面介绍下和二进制 podspec 相关的 `cocoapods-bin` 命令。
|
166
|
-
|
167
|
-
#### pod bin spec create
|
168
|
-
|
169
|
-
```shell
|
170
|
-
➜ ~ pod bin spec create --help
|
171
|
-
Usage:
|
172
|
-
|
173
|
-
$ pod bin spec create
|
174
|
-
|
175
|
-
根据源码 podspec 文件,创建对应的二进制 podspec 文件.
|
176
|
-
|
177
|
-
Options:
|
178
|
-
|
179
|
-
--platforms=ios 生成二进制 spec 支持的平台
|
180
|
-
--template-podspec=A.binary-template.podspec 生成拥有 subspec 的二进制 spec 需要的模版
|
181
|
-
podspec, 插件会更改 version 和 source
|
182
|
-
--no-overwrite 不允许覆盖
|
183
|
-
...
|
184
|
-
```
|
185
|
-
|
186
|
-
`pod bin spec create` 会根据源码 podspec ,创建出二进制 podspec 文件。如果组件存在 subspec ,需要开发者提供 podspec 模版信息,以生成二进制 podspec。插件会根据源码 podspec 更改模版中的 version 字段,并且根据插件配置的 `binary_download_url` 生成 source 字段,最终生成二进制 podspec。
|
187
|
-
|
188
|
-
以 A 组件举例,如果 A 的 podspec 如下:
|
189
|
-
|
190
|
-
```ruby
|
191
|
-
Pod::Spec.new do |s|
|
192
|
-
s.name = 'A'
|
193
|
-
s.version = '0.1.0'
|
194
|
-
s.summary = 'business A short description of A.'
|
195
|
-
s.description = <<-DESC
|
196
|
-
TODO: Add long description of the pod here.
|
197
|
-
DESC
|
198
|
-
s.homepage = 'http://git.2dfire-inc.com/ios/A'
|
199
|
-
s.license = { :type => 'MIT', :file => 'LICENSE' }
|
200
|
-
s.author = { 'qingmu' => 'qingmu@2dfire.com' }
|
201
|
-
s.source = { :git => 'http://git.2dfire-inc.com/qiandaojiang/A.git', :tag => s.version.to_s }
|
202
|
-
s.ios.deployment_target = '8.0'
|
203
|
-
s.source_files = 'A/Classes/**/*'
|
204
|
-
s.public_header_files = 'A/Classes/**/*.{h}'
|
205
|
-
s.resource_bundles = {
|
206
|
-
'A' => ['A/Assets/*']
|
207
|
-
}
|
208
|
-
end
|
209
|
-
```
|
210
|
-
|
211
|
-
那么生成的 `A.binary.podspec.json` 如下:
|
212
|
-
|
213
|
-
```json
|
214
|
-
{
|
215
|
-
"name": "A",
|
216
|
-
"version": "0.1.0",
|
217
|
-
"summary": "business A short description of A.",
|
218
|
-
"description": "TODO: Add long description of the pod here.",
|
219
|
-
"homepage": "http://git.2dfire-inc.com/ios/A",
|
220
|
-
"license": {
|
221
|
-
"type": "MIT",
|
222
|
-
"file": "LICENSE"
|
223
|
-
},
|
224
|
-
"authors": {
|
225
|
-
"qingmu": "qingmu@2dfire.com"
|
226
|
-
},
|
227
|
-
"source": {
|
228
|
-
"http": "http://iosframeworkserver-shopkeeperclient.app.2dfire.com/download/A/0.1.0.zip",
|
229
|
-
"type": "zip"
|
230
|
-
},
|
231
|
-
"platforms": {
|
232
|
-
"ios": "8.0"
|
233
|
-
},
|
234
|
-
"source_files": [
|
235
|
-
"A.framework/Headers/*",
|
236
|
-
"A.framework/Versions/A/Headers/*"
|
237
|
-
],
|
238
|
-
"public_header_files": [
|
239
|
-
"A.framework/Headers/*",
|
240
|
-
"A.framework/Versions/A/Headers/*"
|
241
|
-
],
|
242
|
-
"vendored_frameworks": "A.framework",
|
243
|
-
"resources": [
|
244
|
-
"A.framework/Resources/*.bundle",
|
245
|
-
"A.framework/Versions/A/Resources/*.bundle"
|
246
|
-
]
|
247
|
-
}
|
248
|
-
```
|
249
|
-
|
250
|
-
如果 A 拥有 subspec:
|
251
|
-
|
252
|
-
```ruby
|
253
|
-
Pod::Spec.new do |s|
|
254
|
-
s.name = 'A'
|
255
|
-
s.version = '0.1.0'
|
256
|
-
s.summary = 'business A short description of A.'
|
257
|
-
s.description = <<-DESC
|
258
|
-
TODO: Add long description of the pod here.
|
259
|
-
DESC
|
260
|
-
s.homepage = 'http://git.2dfire-inc.com/ios/A'
|
261
|
-
s.license = { :type => 'MIT', :file => 'LICENSE' }
|
262
|
-
s.author = { 'qingmu' => 'qingmu@2dfire.com' }
|
263
|
-
s.source = { :git => 'http://git.2dfire-inc.com/qiandaojiang/A.git', :tag => s.version.to_s }
|
264
|
-
s.ios.deployment_target = '8.0'
|
265
|
-
s.source_files = 'A/Classes/**/*'
|
266
|
-
s.public_header_files = 'A/Classes/**/*.{h}'
|
267
|
-
s.resource_bundles = {
|
268
|
-
'A' => ['A/Assets/*']
|
269
|
-
}
|
270
|
-
s.subspec 'B' do |ss|
|
271
|
-
ss.dependency 'YYModel'
|
272
|
-
ss.source_files = 'A/Classes/**/*'
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
```
|
277
|
-
|
278
|
-
那么就需要开发者提供 `A.binary-template.podspec`(此模版中的写法假定组件的所有 subspec 都打进一个 `.framework` 里,如果 subpsec 都有属于自己的 `.framework` ,就可以采用其他写法。),**这里要注意源码版本 subspec 集合需要为二进制版本 subspec 集合的子集,否则会出现源码拉取失败或抛出 subspec 不存在错误的情况**:
|
279
|
-
|
280
|
-
```ruby
|
281
|
-
Pod::Spec.new do |s|
|
282
|
-
s.name = 'A'
|
283
|
-
s.summary = 'business A short description of A.'
|
284
|
-
s.description = <<-DESC
|
285
|
-
TODO: Add long description of the pod here.
|
286
|
-
DESC
|
287
|
-
s.homepage = 'http://git.2dfire-inc.com/ios/A'
|
288
|
-
s.license = { :type => 'MIT', :file => 'LICENSE' }
|
289
|
-
s.author = { 'qingmu' => 'qingmu@2dfire.com' }
|
290
|
-
s.ios.deployment_target = '8.0'
|
291
|
-
|
292
|
-
s.subspec "Binary" do |ss|
|
293
|
-
ss.vendored_frameworks = "#{s.name}.framework"
|
294
|
-
ss.source_files = "#{s.name}.framework/Headers/*", "#{s.name}.framework/Versions/A/Headers/*"
|
295
|
-
ss.public_header_files = "#{s.name}.framework/Headers/*", "#{s.name}.framework/Versions/A/Headers/*"
|
296
|
-
# 结合实际打包后的资源产出文件类型编写
|
297
|
-
ss.resources = "#{s.name}.framework/Resources/*.{bundle}", "#{s.name}.framework/Versions/A/Resources/*.{bundle}"
|
298
|
-
ss.dependency 'YYModel'
|
299
|
-
end
|
300
|
-
|
301
|
-
s.subspec 'B' do |ss|
|
302
|
-
ss.dependency "#{s.name}/Binary"
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
```
|
307
|
-
|
308
|
-
最终生成的二进制 podspec 如下:
|
309
|
-
|
310
|
-
```json
|
311
|
-
{
|
312
|
-
"name": "A",
|
313
|
-
"summary": "business A short description of A.",
|
314
|
-
"description": "TODO: Add long description of the pod here.",
|
315
|
-
"homepage": "http://git.2dfire-inc.com/ios/A",
|
316
|
-
"license": {
|
317
|
-
"type": "MIT",
|
318
|
-
"file": "LICENSE"
|
319
|
-
},
|
320
|
-
"authors": {
|
321
|
-
"qingmu": "qingmu@2dfire.com"
|
322
|
-
},
|
323
|
-
"platforms": {
|
324
|
-
"ios": "8.0"
|
325
|
-
},
|
326
|
-
"version": "0.1.0",
|
327
|
-
"source": {
|
328
|
-
"http": "http://iosframeworkserver-shopkeeperclient.app.2dfire.com/download/A/0.1.0.zip",
|
329
|
-
"type": "zip"
|
330
|
-
},
|
331
|
-
"subspecs": [
|
332
|
-
{
|
333
|
-
"name": "Binary",
|
334
|
-
"vendored_frameworks": "A.framework",
|
335
|
-
"source_files": [
|
336
|
-
"A.framework/Headers/*",
|
337
|
-
"A.framework/Versions/A/Headers/*"
|
338
|
-
],
|
339
|
-
"public_header_files": [
|
340
|
-
"A.framework/Headers/*",
|
341
|
-
"A.framework/Versions/A/Headers/*"
|
342
|
-
],
|
343
|
-
"resources": [
|
344
|
-
"A.framework/Resources/*.{bundle}",
|
345
|
-
"A.framework/Versions/A/Resources/*.{bundle}"
|
346
|
-
],
|
347
|
-
"dependencies": {
|
348
|
-
"YYModel": [
|
349
|
-
|
350
|
-
]
|
351
|
-
}
|
352
|
-
},
|
353
|
-
{
|
354
|
-
"name": "B",
|
355
|
-
"dependencies": {
|
356
|
-
"A/Binary": [
|
357
|
-
|
358
|
-
]
|
359
|
-
}
|
360
|
-
}
|
361
|
-
]
|
362
|
-
}
|
363
|
-
```
|
364
|
-
|
365
|
-
#### pod bin spec lint
|
366
|
-
|
367
|
-
```shell
|
368
|
-
➜ ~ pod bin spec lint --help
|
369
|
-
Usage:
|
370
|
-
|
371
|
-
$ pod bin spec lint [NAME.podspec|DIRECTORY|http://PATH/NAME.podspec ...]
|
372
|
-
|
373
|
-
spec lint 二进制组件 / 源码组件
|
374
|
-
|
375
|
-
Options:
|
376
|
-
|
377
|
-
--binary lint 组件的二进制版本
|
378
|
-
--template-podspec=A.binary-template.podspec 生成拥有 subspec 的二进制 spec 需要的模版
|
379
|
-
podspec, 插件会更改 version 和 source
|
380
|
-
--reserve-created-spec 保留生成的二进制 spec 文件
|
381
|
-
--code-dependencies 使用源码依赖进行 lint
|
382
|
-
--loose-options 添加宽松的 options, 包括 --use-libraries
|
383
|
-
(可能会造成 entry point (start)
|
384
|
-
undefined)
|
385
|
-
...
|
386
|
-
```
|
387
|
-
|
388
|
-
`pod bin spec lint` 默认使用二进制依赖进行 lint,在添加 `--binary` 会去 lint 当前组件的二进制 podspec(动态生成)。在添加 `--code-dependencies` 将会使用源码依赖进行 lint ,个人推荐使用二进制依赖 lint,可以极大地减少编译时间。
|
389
|
-
|
390
|
-
#### pod bin repo push
|
391
|
-
|
392
|
-
```shell
|
393
|
-
|
394
|
-
➜ ~ pod bin repo push --help
|
395
|
-
Usage:
|
396
|
-
|
397
|
-
$ pod bin repo push [NAME.podspec]
|
398
|
-
|
399
|
-
发布二进制组件 / 源码组件
|
400
|
-
|
401
|
-
Options:
|
402
|
-
|
403
|
-
--binary 发布组件的二进制版本
|
404
|
-
--template-podspec=A.binary-template.podspec 生成拥有 subspec 的二进制 spec 需要的模版
|
405
|
-
podspec, 插件会更改 version 和 source
|
406
|
-
--reserve-created-spec 保留生成的二进制 spec 文件
|
407
|
-
--code-dependencies 使用源码依赖进行 lint
|
408
|
-
--loose-options 添加宽松的 options, 包括
|
409
|
-
--use-libraries (可能会造成 entry
|
410
|
-
point (start) undefined)
|
411
|
-
...
|
412
|
-
```
|
413
|
-
|
414
|
-
`pod bin repo push` 用来发布组件,其余特性和 `pod bin spec lint` 一致。
|
415
|
-
|
416
|
-
### Podfile DSL
|
417
|
-
|
418
|
-
首先,开发者需要在 Podfile 中需要使用 `plugin 'cocoapods-bin'` 语句引入插件 :
|
419
|
-
|
420
|
-
```ruby
|
421
|
-
plugin 'cocoapods-bin'
|
422
|
-
```
|
423
|
-
|
424
|
-
顺带可以删除 Podfile 中的 source ,因为插件内部会自动帮你添加两个私有源。
|
425
|
-
|
426
|
-
`cocoapods-bin `插件提供二进制相关的配置语句有 `use_binaries!`、`use_binaries_with_spec_selector!` 以及 `set_use_source_pods`,下面会分别介绍。
|
427
|
-
|
428
|
-
#### use_binaries!
|
429
|
-
|
430
|
-
全部组件使用二进制版本。
|
431
|
-
|
432
|
-
支持传入布尔值控制是否使用二进制版本,比如 DEBUG 包使用二进制版本,正式包使用源码版本,Podfile 关联语句可以这样写:
|
433
|
-
|
434
|
-
```ruby
|
435
|
-
use_binaries! (ENV['DEBUG'].nil? || ENV['DEBUG'] == 'true')
|
436
|
-
```
|
437
|
-
|
438
|
-
当组件没有二进制版本时,插件会强制工程依赖该组件的源码版本。开发者可以通过执行 `pod install--verbose` option ,在分析依赖步骤查看哪些组件没有二进制版本:
|
439
|
-
|
440
|
-
```shell
|
441
|
-
...
|
442
|
-
Resolving dependencies of `Podfile`
|
443
|
-
【AMapFrameworks | 0.0.4】组件无对应二进制版本 , 将采用源码依赖.
|
444
|
-
【ActivityForRestApp | 0.2.1】组件无对应二进制版本 , 将采用源码依赖.
|
445
|
-
【AssemblyComponent | 0.5.9】组件无对应二进制版本 , 将采用源码依赖.
|
446
|
-
【Bugly | 2.4.6】组件无对应二进制版本 , 将采用源码依赖.
|
447
|
-
【Celebi | 0.6.4】组件无对应二进制版本 , 将采用源码依赖.
|
448
|
-
【CocoaAsyncSocket/RunLoop | 7.4.3】组件无对应二进制版本 , 将采用源码依赖.
|
449
|
-
【CocoaLumberjack | 3.4.1】组件无对应二进制版本 , 将采用源码依赖.
|
450
|
-
【CocoaLumberjack/Default | 3.4.1】组件无对应二进制版本 , 将采用源码依赖.
|
451
|
-
【CocoaLumberjack/Extensions | 3.4.1】组件无对应二进制版本 , 将采用源码依赖.
|
452
|
-
【CodePush | 0.3.1】组件无对应二进制版本 , 将采用源码依赖.
|
453
|
-
【CodePush/Core | 0.3.1】组件无对应二进制版本 , 将采用源码依赖.
|
454
|
-
【CodePush/SSZipArchive | 0.3.1】组件无对应二进制版本 , 将采用源码依赖.
|
455
|
-
【ESExchangeSkin | 0.3.2】组件无对应二进制版本 , 将采用源码依赖.
|
456
|
-
...
|
457
|
-
```
|
458
|
-
|
459
|
-
也可以通过 Podfile.lock 中的 `SPEC REPOS` 字段,查看哪些组件采用了源码版本,哪些采用了二进制版本:
|
460
|
-
|
461
|
-
```yaml
|
462
|
-
...
|
463
|
-
SPEC REPOS:
|
464
|
-
"git@git.xxxxxx.net:ios/cocoapods-spec-binary.git":
|
465
|
-
- AFNetworking
|
466
|
-
- Aspects
|
467
|
-
- CocoaSecurity
|
468
|
-
- DACircularProgress
|
469
|
-
...
|
470
|
-
"git@git.xxxxxx.net:ios/cocoapods-spec.git":
|
471
|
-
- ActivityForRestApp
|
472
|
-
- AMapFrameworks
|
473
|
-
- AssemblyComponent
|
474
|
-
...
|
475
|
-
...
|
476
|
-
```
|
477
|
-
|
478
|
-
|
479
|
-
#### set_use_source_pods
|
480
|
-
|
481
|
-
设置使用源码版本的组件。
|
482
|
-
|
483
|
-
实际开发中,可能需要查看 YYModel 组件的源码,这时候可以这么设置:
|
484
|
-
|
485
|
-
```ruby
|
486
|
-
set_use_source_pods ['YYModel']
|
487
|
-
```
|
488
|
-
|
489
|
-
如果 CocoaPods 版本为 1.5.3 ,终端会输出以下内容,表示 YYModel 的参照源从二进制私有源切换到了源码私有源:
|
490
|
-
|
491
|
-
```shell
|
492
|
-
Analyzing dependencies
|
493
|
-
Fetching podspec for `A` from `../`
|
494
|
-
Downloading dependencies
|
495
|
-
Using A (0.1.0)
|
496
|
-
Installing YYModel 1.0.4.2 (source changed to `git@git.xxxxxx.net:ios/cocoapods-spec.git` from `git@git.xxxxxx.net:ios/cocoapods-spec-binary.git`)
|
497
|
-
Generating Pods project
|
498
|
-
Integrating client project
|
499
|
-
Sending stats
|
500
|
-
Pod installation complete! There is 1 dependency from the Podfile and 2 total pods installed.
|
501
|
-
```
|
502
|
-
|
503
|
-
#### use_binaries_with_spec_selector!
|
504
|
-
|
505
|
-
过滤出需要使用二进制版本组件。
|
506
|
-
|
507
|
-
假如开发者只需要 `YYModel` 的二进制版本,那么他可以在 Podfile 中添加以下代码:
|
508
|
-
|
509
|
-
```ruby
|
510
|
-
use_binaries_with_spec_selector! do |spec|
|
511
|
-
spec.name == 'YYModel'
|
512
|
-
end
|
513
|
-
```
|
514
|
-
|
515
|
-
**需要注意的是,如果组件有 subspec ,使用组件名作为判断条件应如下**:
|
516
|
-
|
517
|
-
```ruby
|
518
|
-
use_binaries_with_spec_selector! do |spec|
|
519
|
-
spec.name.start_with? == '组件名'
|
520
|
-
end
|
521
|
-
```
|
522
|
-
|
523
|
-
如果像上个代码块一样,**直接对比组件名,则插件会忽略此组件的所有 subspec,导致资源拉取错误**,这种场景下,最好通过 `set_use_source_pods` 语句配置依赖。
|
524
|
-
|
525
|
-
一个实际应用是,三方组件采用二进制版本,团队编写的组件依旧采用源码版本。如果三方组件都在 `cocoapods-repo` 组下,就可以使用以下代码过滤出三方组件:
|
526
|
-
|
527
|
-
```ruby
|
528
|
-
use_binaries_with_spec_selector! do |spec|
|
529
|
-
git = spec.source && spec.source['git']
|
530
|
-
git && git.include?('cocoapods-repo')
|
531
|
-
end
|
532
|
-
```
|
533
|
-
|
534
|
-
#### 其他设置
|
535
|
-
|
536
|
-
插件默认开启多线程下载组件资源,如果要禁用这个功能,Podfile 添加以下代码即可:
|
537
|
-
|
538
|
-
```ruby
|
539
|
-
install! 'cocoapods', { install_with_multi_threads: false }
|
540
|
-
```
|
541
1
|
|
@@ -29,6 +29,7 @@ module Pod
|
|
29
29
|
['--sources', '私有源地址,多个用分号区分'],
|
30
30
|
['--framework-output', '输出framework文件'],
|
31
31
|
['--no-zip', '不压缩静态库 为 zip'],
|
32
|
+
['--configuration', 'Build the specified configuration (e.g. Debug). Defaults to Release'],
|
32
33
|
['--env', "该组件上传的环境 %w[dev debug_iphoneos release_iphoneos]"]
|
33
34
|
].concat(Pod::Command::Gen.options).concat(super).uniq
|
34
35
|
end
|
@@ -51,6 +52,8 @@ module Pod
|
|
51
52
|
@sources = argv.option('sources') || []
|
52
53
|
@platform = Platform.new(:ios)
|
53
54
|
|
55
|
+
@config = argv.option('configuration', 'Release')
|
56
|
+
|
54
57
|
@framework_path
|
55
58
|
super
|
56
59
|
|
@@ -81,7 +84,8 @@ module Pod
|
|
81
84
|
@framework_output,
|
82
85
|
@zip,
|
83
86
|
@spec,
|
84
|
-
CBin::Config::Builder.instance.white_pod_list.include?(@spec.name)
|
87
|
+
CBin::Config::Builder.instance.white_pod_list.include?(@spec.name),
|
88
|
+
@config)
|
85
89
|
builder.build
|
86
90
|
builder.clean_workspace if @clean && !@all_make
|
87
91
|
end
|
@@ -119,9 +123,12 @@ module Pod
|
|
119
123
|
@platform,
|
120
124
|
@framework_output,
|
121
125
|
@zip,
|
122
|
-
@spec
|
126
|
+
@spec,
|
127
|
+
false ,
|
128
|
+
@config)
|
123
129
|
builder.build
|
124
|
-
rescue
|
130
|
+
rescue Object => exception
|
131
|
+
UI.puts exception
|
125
132
|
fail_build_specs << spec
|
126
133
|
end
|
127
134
|
end
|
@@ -148,6 +155,7 @@ module Pod
|
|
148
155
|
"--sources=#{sources_option(@code_dependencies, @sources)}",
|
149
156
|
"--gen-directory=#{CBin::Config::Builder.instance.gen_dir}",
|
150
157
|
'--clean',
|
158
|
+
'--use-podfile',
|
151
159
|
*@additional_args
|
152
160
|
]
|
153
161
|
|
@@ -19,6 +19,7 @@ module Pod
|
|
19
19
|
['--framework-output', '输出framework文件'],
|
20
20
|
['--no-zip', '不压缩静态 framework 为 zip'],
|
21
21
|
['--all-make', '对该组件的依赖库,全部制作为二进制组件'],
|
22
|
+
['--configuration', 'Build the specified configuration (e.g. Debug). Defaults to Release'],
|
22
23
|
['--env', "该组件上传的环境 %w[dev debug_iphoneos release_iphoneos]"]
|
23
24
|
]
|
24
25
|
end
|
@@ -38,6 +39,9 @@ module Pod
|
|
38
39
|
@zip = argv.flag?('zip', true)
|
39
40
|
@all_make = argv.flag?('all-make', false )
|
40
41
|
@verbose = argv.flag?('verbose',true)
|
42
|
+
|
43
|
+
@config = argv.option('configuration', 'Release')
|
44
|
+
|
41
45
|
super
|
42
46
|
end
|
43
47
|
|
@@ -113,7 +117,7 @@ module Pod
|
|
113
117
|
if @env
|
114
118
|
argvs += ["--env=#{@env}"]
|
115
119
|
end
|
116
|
-
|
120
|
+
argvs += ["--configuration=#{@config}"]
|
117
121
|
|
118
122
|
archive = Pod::Command::Bin::Archive.new(CLAide::ARGV.new(argvs))
|
119
123
|
archive.validate!
|
@@ -83,11 +83,6 @@ module Pod
|
|
83
83
|
FileUtils.rm_rf(target_path)
|
84
84
|
|
85
85
|
find_dependency = find_dependency(name)
|
86
|
-
# 意义不大,需要可以使用--source参数 对 github-ios 仓库对做特殊处理
|
87
|
-
# if find_dependency && find_dependency.external_source[:podspec].include?(http_gitlib_GitHub_iOS_path)
|
88
|
-
# github_ios = find_dependency.external_source[:podspec]
|
89
|
-
# find_dependency.external_source[:podspec] = github_ios.gsub(http_gitlib_GitHub_iOS_path,http_gitlib_iOS_path)
|
90
|
-
# end
|
91
86
|
|
92
87
|
spec = fetch_external_source(find_dependency, @config.podfile,@config.lockfile, @config.sandbox,true )
|
93
88
|
|
@@ -106,7 +101,6 @@ module Pod
|
|
106
101
|
break
|
107
102
|
end
|
108
103
|
end
|
109
|
-
|
110
104
|
find_dependency
|
111
105
|
end
|
112
106
|
|
@@ -150,6 +144,7 @@ module Pod
|
|
150
144
|
FileUtils.rm_rf(File.join(dir,basename))
|
151
145
|
`ln -s #{target_path} #{dir}/#{basename}`
|
152
146
|
end
|
147
|
+
|
153
148
|
check(lib_file,dir,basename)
|
154
149
|
end
|
155
150
|
|
@@ -73,26 +73,31 @@ module Pod
|
|
73
73
|
|
74
74
|
podfile.instance_eval do
|
75
75
|
begin
|
76
|
+
|
77
|
+
# podfile HASH_KEYS才有plugins字段,否则会被限制
|
78
|
+
if local_podfile.plugins.any?
|
79
|
+
hash_plugins = podfile.plugins || {}
|
80
|
+
hash_plugins = hash_plugins.merge(local_podfile.plugins)
|
81
|
+
set_hash_value(%w[plugins].first, hash_plugins)
|
82
|
+
|
83
|
+
# 加入源码白名单,避免本地库被二进制了
|
84
|
+
podfile.set_use_source_pods(local_podfile.use_source_pods) if local_podfile.use_source_pods
|
85
|
+
podfile.use_binaries!(local_podfile.use_binaries?)
|
86
|
+
end
|
87
|
+
|
76
88
|
# 在target把local-target中到dependencies值删除了,再设置
|
77
89
|
# 把本地和原始到dependencies 合并,设置dependencies
|
78
90
|
local_podfile&.target_definition_list&.each do |local_target|
|
79
91
|
next if local_target.name == 'Pods'
|
80
92
|
|
81
93
|
target_definition_list.each do |target|
|
94
|
+
|
82
95
|
unless target.name == local_target.name &&
|
83
96
|
(local_target.to_hash['dependencies'] &&local_target.to_hash['dependencies'].any?)
|
84
97
|
next
|
85
98
|
end
|
86
99
|
|
87
|
-
|
88
|
-
if local_podfile.plugins.any?
|
89
|
-
hash_plugins = podfile.plugins || {}
|
90
|
-
hash_plugins = hash_plugins.merge(local_podfile.plugins)
|
91
|
-
set_hash_value(%w[plugins].first, hash_plugins)
|
92
|
-
end
|
93
|
-
# 加入源码白名单,避免本地库被二进制了
|
94
|
-
podfile.set_use_source_pods(local_podfile.use_source_pods) if local_podfile.use_source_pods
|
95
|
-
podfile.use_binaries!(local_podfile.use_binaries?)
|
100
|
+
|
96
101
|
|
97
102
|
target.instance_exec do
|
98
103
|
# 在target把local-target中到dependencies值删除了,再设置
|
@@ -126,6 +131,7 @@ module Pod
|
|
126
131
|
|
127
132
|
end
|
128
133
|
end
|
134
|
+
|
129
135
|
end
|
130
136
|
|
131
137
|
if local_pre_install_callback
|
@@ -51,7 +51,7 @@ module CBin
|
|
51
51
|
source_dir = Dir.pwd
|
52
52
|
file_accessor = Sandbox::FileAccessor.new(Pathname.new('.').expand_path, @spec.consumer(@platform))
|
53
53
|
Dir.chdir(workspace_directory) do
|
54
|
-
builder = CBin::Framework::Builder.new(@spec, file_accessor, @platform, source_dir
|
54
|
+
builder = CBin::Framework::Builder.new(@spec, file_accessor, @platform, source_dir, @isRootSpec, @build_model )
|
55
55
|
@@build_defines = builder.build if @isRootSpec
|
56
56
|
begin
|
57
57
|
@framework_path = builder.lipo_build(@@build_defines) unless @skip_archive
|
@@ -38,7 +38,7 @@ module CBin
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def lipo_build(defines)
|
41
|
-
UI.section("Building static
|
41
|
+
UI.section("Building static Library #{@spec}") do
|
42
42
|
# defines = compile
|
43
43
|
|
44
44
|
# build_sim_libraries(defines)
|
@@ -68,118 +68,22 @@ module CBin
|
|
68
68
|
`cp -fa #{@platform}/#{framework_name} #{target_dir}`
|
69
69
|
end
|
70
70
|
|
71
|
+
#模拟器,目前只支持 debug x86-64
|
71
72
|
def build_sim_libraries(defines)
|
72
73
|
UI.message 'Building simulator libraries'
|
73
74
|
|
74
75
|
if is_debug_model
|
75
76
|
# archs = %w[i386 x86_64]
|
76
|
-
archs =
|
77
|
+
archs = ios_architectures_sim
|
77
78
|
archs.map do |arch|
|
78
79
|
xcodebuild(defines, "-sdk iphonesimulator ARCHS=\'#{arch}\' ", "build-#{arch}","Debug")
|
79
80
|
end
|
80
81
|
else
|
81
|
-
xcodebuild(defines, "-sdk iphonesimulator ", 'build-simulator')
|
82
|
+
xcodebuild(defines, "-sdk iphonesimulator ", 'build-simulator', "Release")
|
82
83
|
end
|
83
84
|
|
84
85
|
end
|
85
86
|
|
86
|
-
def copy_headers
|
87
|
-
#走 podsepc中的public_headers
|
88
|
-
public_headers = Array.new
|
89
|
-
|
90
|
-
#by slj 如果没有头文件,去 "Headers/Public"拿
|
91
|
-
# if public_headers.empty?
|
92
|
-
Dir.chdir("./Headers/Public/#{@spec.name}") do
|
93
|
-
headers = Dir.glob('*.h')
|
94
|
-
headers.each do |h|
|
95
|
-
public_headers << Pathname.new(File.join(Dir.pwd,h))
|
96
|
-
end
|
97
|
-
end
|
98
|
-
# end
|
99
|
-
|
100
|
-
# UI.message "Copying public headers #{public_headers.map(&:basename).map(&:to_s)}"
|
101
|
-
|
102
|
-
public_headers.each do |h|
|
103
|
-
`ditto #{h} #{framework.headers_path}/#{h.basename}`
|
104
|
-
end
|
105
|
-
|
106
|
-
# If custom 'module_map' is specified add it to the framework distribution
|
107
|
-
# otherwise check if a header exists that is equal to 'spec.name', if so
|
108
|
-
# create a default 'module_map' one using it.
|
109
|
-
if !@spec.module_map.nil?
|
110
|
-
module_map_file = @file_accessor.module_map
|
111
|
-
if Pathname(module_map_file).exist?
|
112
|
-
module_map = File.read(module_map_file)
|
113
|
-
end
|
114
|
-
elsif public_headers.map(&:basename).map(&:to_s).include?("#{@spec.name}.h")
|
115
|
-
module_map = <<-MAP
|
116
|
-
framework module #{@spec.name} {
|
117
|
-
umbrella header "#{@spec.name}.h"
|
118
|
-
|
119
|
-
export *
|
120
|
-
module * { export * }
|
121
|
-
}
|
122
|
-
MAP
|
123
|
-
end
|
124
|
-
|
125
|
-
unless module_map.nil?
|
126
|
-
UI.message "Writing module map #{module_map}"
|
127
|
-
unless framework.module_map_path.exist?
|
128
|
-
framework.module_map_path.mkpath
|
129
|
-
end
|
130
|
-
File.write("#{framework.module_map_path}/module.modulemap", module_map)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def copy_license
|
135
|
-
UI.message 'Copying license'
|
136
|
-
license_file = @spec.license[:file] || 'LICENSE'
|
137
|
-
`cp "#{license_file}" .` if Pathname(license_file).exist?
|
138
|
-
end
|
139
|
-
|
140
|
-
def copy_resources
|
141
|
-
|
142
|
-
bundles = Dir.glob('./build/*.bundle')
|
143
|
-
|
144
|
-
bundle_names = [@spec, *@spec.recursive_subspecs].flat_map do |spec|
|
145
|
-
consumer = spec.consumer(@platform)
|
146
|
-
consumer.resource_bundles.keys +
|
147
|
-
consumer.resources.map do |r|
|
148
|
-
File.basename(r, '.bundle') if File.extname(r) == 'bundle'
|
149
|
-
end
|
150
|
-
end.compact.uniq
|
151
|
-
|
152
|
-
bundles.select! do |bundle|
|
153
|
-
bundle_name = File.basename(bundle, '.bundle')
|
154
|
-
bundle_names.include?(bundle_name)
|
155
|
-
end
|
156
|
-
|
157
|
-
if bundles.count > 0
|
158
|
-
UI.message "Copying bundle files #{bundles}"
|
159
|
-
bundle_files = bundles.join(' ')
|
160
|
-
`cp -rp #{bundle_files} #{framework.resources_path} 2>&1`
|
161
|
-
end
|
162
|
-
|
163
|
-
real_source_dir = @isRootSpec ? @source_dir : Pathname.new(File.join(Dir.pwd,"#{@spec.name}"))
|
164
|
-
resources = [@spec, *@spec.recursive_subspecs].flat_map do |spec|
|
165
|
-
expand_paths(real_source_dir, spec.consumer(@platform).resources)
|
166
|
-
end.compact.uniq
|
167
|
-
|
168
|
-
if resources.count == 0 && bundles.count == 0
|
169
|
-
framework.delete_resources
|
170
|
-
return
|
171
|
-
end
|
172
|
-
|
173
|
-
if resources.count > 0
|
174
|
-
#把 路径转义。 避免空格情况下拷贝失败
|
175
|
-
escape_resource = []
|
176
|
-
resources.each do |source|
|
177
|
-
escape_resource << Shellwords.join(source)
|
178
|
-
end
|
179
|
-
UI.message "Copying resources #{escape_resource}"
|
180
|
-
`cp -rp #{escape_resource.join(' ')} #{framework.resources_path}`
|
181
|
-
end
|
182
|
-
end
|
183
87
|
|
184
88
|
def static_libs_in_sandbox(build_dir = 'build')
|
185
89
|
file = Dir.glob("#{build_dir}/lib#{target_name}.a")
|
@@ -194,21 +98,32 @@ module CBin
|
|
194
98
|
static_libs = static_libs_in_sandbox('build') + static_libs_in_sandbox('build-simulator') + @vendored_libraries
|
195
99
|
if is_debug_model
|
196
100
|
ios_architectures.map do |arch|
|
197
|
-
static_libs += static_libs_in_sandbox("build-#{arch}") +
|
101
|
+
static_libs += static_libs_in_sandbox("build-#{arch}") + @vendored_libraries
|
102
|
+
end
|
103
|
+
ios_architectures_sim do |arch|
|
104
|
+
static_libs += static_libs_in_sandbox("build-#{arch}") + @vendored_libraries
|
198
105
|
end
|
199
106
|
end
|
200
107
|
|
201
108
|
build_path = Pathname("build")
|
202
109
|
build_path.mkpath unless build_path.exist?
|
203
110
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
111
|
+
if is_debug_model
|
112
|
+
libs = (ios_architectures + ios_architectures_sim) .map do |arch|
|
113
|
+
library = "build-#{arch}/lib#{@spec.name}.a"
|
114
|
+
library
|
115
|
+
end
|
116
|
+
else
|
117
|
+
libs = ios_architectures.map do |arch|
|
118
|
+
library = "build/package-#{@spec.name}-#{arch}.a"
|
119
|
+
# libtool -arch_only arm64 -static -o build/package-armv64.a build/libIMYFoundation.a build-simulator/libIMYFoundation.a
|
120
|
+
# 从liBFoundation.a 文件中,提取出 arm64 架构的文件,命名为build/package-armv64.a
|
121
|
+
UI.message "libtool -arch_only #{arch} -static -o #{library} #{static_libs.join(' ')}"
|
122
|
+
`libtool -arch_only #{arch} -static -o #{library} #{static_libs.join(' ')}`
|
123
|
+
library
|
124
|
+
end
|
211
125
|
end
|
126
|
+
|
212
127
|
UI.message "lipo -create -output #{output} #{libs.join(' ')}"
|
213
128
|
`lipo -create -output #{output} #{libs.join(' ')}`
|
214
129
|
end
|
@@ -230,11 +145,18 @@ module CBin
|
|
230
145
|
# iphone5,iphone5s以下的模拟器
|
231
146
|
# >x86_64
|
232
147
|
# iphone6以上的模拟器
|
233
|
-
archs = %w[
|
148
|
+
archs = %w[arm64 armv7]
|
234
149
|
# archs = %w[x86_64 arm64 armv7s i386]
|
235
|
-
@vendored_libraries.each do |library|
|
236
|
-
|
237
|
-
end
|
150
|
+
# @vendored_libraries.each do |library|
|
151
|
+
# archs = `lipo -info #{library}`.split & archs
|
152
|
+
# end
|
153
|
+
archs
|
154
|
+
end
|
155
|
+
|
156
|
+
def ios_architectures_sim
|
157
|
+
|
158
|
+
archs = %w[x86_64]
|
159
|
+
# TODO 处理是否需要 i386
|
238
160
|
archs
|
239
161
|
end
|
240
162
|
|
@@ -245,7 +167,7 @@ module CBin
|
|
245
167
|
|
246
168
|
options = ios_build_options
|
247
169
|
if is_debug_model
|
248
|
-
archs =
|
170
|
+
archs = ios_architectures
|
249
171
|
# archs = %w[arm64 armv7 armv7s]
|
250
172
|
archs.map do |arch|
|
251
173
|
xcodebuild(defines, "ARCHS=\'#{arch}\' OTHER_CFLAGS=\'-fembed-bitcode -Qunused-arguments\'","build-#{arch}",@build_model)
|
@@ -271,10 +193,14 @@ module CBin
|
|
271
193
|
# end
|
272
194
|
end
|
273
195
|
|
274
|
-
def xcodebuild(defines = '', args = '', build_dir = 'build',build_model = '
|
275
|
-
|
276
|
-
|
277
|
-
|
196
|
+
def xcodebuild(defines = '', args = '', build_dir = 'build',build_model = 'Debug')
|
197
|
+
|
198
|
+
unless File.exist?("Pods.xcodeproj") #cocoapods-generate v2.0.0
|
199
|
+
command = "xcodebuild #{defines} #{args} CONFIGURATION_BUILD_DIR=#{File.join(File.expand_path("..", build_dir), File.basename(build_dir))} clean build -configuration #{build_model} -target #{target_name} -project ./Pods/Pods.xcodeproj 2>&1"
|
200
|
+
else
|
201
|
+
command = "xcodebuild #{defines} #{args} CONFIGURATION_BUILD_DIR=#{build_dir} clean build -configuration #{build_model} -target #{target_name} -project ./Pods.xcodeproj 2>&1"
|
202
|
+
end
|
203
|
+
|
278
204
|
UI.message "command = #{command}"
|
279
205
|
output = `#{command}`.lines.to_a
|
280
206
|
|
@@ -289,6 +215,118 @@ module CBin
|
|
289
215
|
end
|
290
216
|
end
|
291
217
|
|
218
|
+
def copy_headers
|
219
|
+
#走 podsepc中的public_headers
|
220
|
+
public_headers = Array.new
|
221
|
+
|
222
|
+
#by slj 如果没有头文件,去 "Headers/Public"拿
|
223
|
+
# if public_headers.empty?
|
224
|
+
spec_header_dir = "./Headers/Public/#{@spec.name}"
|
225
|
+
unless File.exist?(spec_header_dir)
|
226
|
+
spec_header_dir = "./Pods/Headers/Public/#{@spec.name}"
|
227
|
+
end
|
228
|
+
raise "copy_headers #{spec_header_dir} no exist " unless File.exist?(spec_header_dir)
|
229
|
+
Dir.chdir(spec_header_dir) do
|
230
|
+
headers = Dir.glob('*.h')
|
231
|
+
headers.each do |h|
|
232
|
+
public_headers << Pathname.new(File.join(Dir.pwd,h))
|
233
|
+
end
|
234
|
+
end
|
235
|
+
# end
|
236
|
+
|
237
|
+
# UI.message "Copying public headers #{public_headers.map(&:basename).map(&:to_s)}"
|
238
|
+
|
239
|
+
public_headers.each do |h|
|
240
|
+
`ditto #{h} #{framework.headers_path}/#{h.basename}`
|
241
|
+
end
|
242
|
+
|
243
|
+
# If custom 'module_map' is specified add it to the framework distribution
|
244
|
+
# otherwise check if a header exists that is equal to 'spec.name', if so
|
245
|
+
# create a default 'module_map' one using it.
|
246
|
+
if !@spec.module_map.nil?
|
247
|
+
module_map_file = @file_accessor.module_map
|
248
|
+
if Pathname(module_map_file).exist?
|
249
|
+
module_map = File.read(module_map_file)
|
250
|
+
end
|
251
|
+
elsif public_headers.map(&:basename).map(&:to_s).include?("#{@spec.name}.h")
|
252
|
+
module_map = <<-MAP
|
253
|
+
framework module #{@spec.name} {
|
254
|
+
umbrella header "#{@spec.name}.h"
|
255
|
+
|
256
|
+
export *
|
257
|
+
module * { export * }
|
258
|
+
}
|
259
|
+
MAP
|
260
|
+
end
|
261
|
+
|
262
|
+
unless module_map.nil?
|
263
|
+
UI.message "Writing module map #{module_map}"
|
264
|
+
unless framework.module_map_path.exist?
|
265
|
+
framework.module_map_path.mkpath
|
266
|
+
end
|
267
|
+
File.write("#{framework.module_map_path}/module.modulemap", module_map)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def copy_license
|
272
|
+
UI.message 'Copying license'
|
273
|
+
license_file = @spec.license[:file] || 'LICENSE'
|
274
|
+
`cp "#{license_file}" .` if Pathname(license_file).exist?
|
275
|
+
end
|
276
|
+
|
277
|
+
def copy_resources
|
278
|
+
resource_dir = './build/*.bundle'
|
279
|
+
resource_dir = './build-armv7/*.bundle' if File.exist?('./build-armv7')
|
280
|
+
resource_dir = './build-arm64/*.bundle' if File.exist?('./build-arm64')
|
281
|
+
|
282
|
+
bundles = Dir.glob(resource_dir)
|
283
|
+
|
284
|
+
bundle_names = [@spec, *@spec.recursive_subspecs].flat_map do |spec|
|
285
|
+
consumer = spec.consumer(@platform)
|
286
|
+
consumer.resource_bundles.keys +
|
287
|
+
consumer.resources.map do |r|
|
288
|
+
File.basename(r, '.bundle') if File.extname(r) == 'bundle'
|
289
|
+
end
|
290
|
+
end.compact.uniq
|
291
|
+
|
292
|
+
bundles.select! do |bundle|
|
293
|
+
bundle_name = File.basename(bundle, '.bundle')
|
294
|
+
bundle_names.include?(bundle_name)
|
295
|
+
end
|
296
|
+
|
297
|
+
if bundles.count > 0
|
298
|
+
UI.message "Copying bundle files #{bundles}"
|
299
|
+
bundle_files = bundles.join(' ')
|
300
|
+
`cp -rp #{bundle_files} #{framework.resources_path} 2>&1`
|
301
|
+
end
|
302
|
+
|
303
|
+
spec_source_dir = File.join(Dir.pwd,"#{@spec.name}")
|
304
|
+
unless File.exist?(spec_source_dir)
|
305
|
+
spec_source_dir = File.join(Dir.pwd,"Pods/#{@spec.name}")
|
306
|
+
end
|
307
|
+
raise "copy_resources #{spec_source_dir} no exist " unless File.exist?(spec_source_dir)
|
308
|
+
|
309
|
+
real_source_dir = @isRootSpec ? @source_dir : spec_source_dir
|
310
|
+
resources = [@spec, *@spec.recursive_subspecs].flat_map do |spec|
|
311
|
+
expand_paths(real_source_dir, spec.consumer(@platform).resources)
|
312
|
+
end.compact.uniq
|
313
|
+
|
314
|
+
if resources.count == 0 && bundles.count == 0
|
315
|
+
framework.delete_resources
|
316
|
+
return
|
317
|
+
end
|
318
|
+
|
319
|
+
if resources.count > 0
|
320
|
+
#把 路径转义。 避免空格情况下拷贝失败
|
321
|
+
escape_resource = []
|
322
|
+
resources.each do |source|
|
323
|
+
escape_resource << Shellwords.join(source)
|
324
|
+
end
|
325
|
+
UI.message "Copying resources #{escape_resource}"
|
326
|
+
`cp -rp #{escape_resource.join(' ')} #{framework.resources_path}`
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
292
330
|
def expand_paths(source_dir, path_specs)
|
293
331
|
path_specs.map do |path_spec|
|
294
332
|
Dir.glob(File.join(source_dir, path_spec))
|
@@ -302,6 +340,8 @@ module CBin
|
|
302
340
|
framework
|
303
341
|
end
|
304
342
|
end
|
343
|
+
|
344
|
+
|
305
345
|
end
|
306
346
|
end
|
307
347
|
end
|
@@ -38,12 +38,12 @@ module CBin
|
|
38
38
|
|
39
39
|
def make_headers
|
40
40
|
@headers_path = @versions_path + Pathname.new('Headers')
|
41
|
-
|
41
|
+
@headers_path.mkpath unless @headers_path.exist?
|
42
42
|
end
|
43
43
|
|
44
44
|
def make_resources
|
45
45
|
@resources_path = @versions_path + Pathname.new('Resources')
|
46
|
-
|
46
|
+
@resources_path.mkpath unless @resources_path.exist?
|
47
47
|
end
|
48
48
|
|
49
49
|
def make_root
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocoapods-imy-bin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 苏良锦
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parallel
|
@@ -169,8 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
169
|
- !ruby/object:Gem::Version
|
170
170
|
version: '0'
|
171
171
|
requirements: []
|
172
|
-
|
173
|
-
rubygems_version: 2.5.2.3
|
172
|
+
rubygems_version: 3.0.1
|
174
173
|
signing_key:
|
175
174
|
specification_version: 4
|
176
175
|
summary: cocoapods-imy-bin is a plugin which helps develpers switching pods between
|