cocoapods-binary-matchup 0.0.27 → 0.0.28
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 +4 -4
- metadata +3 -29
- data/.gitignore +0 -32
- data/.travis.yml +0 -23
- data/Gemfile +0 -13
- data/Gemfile.lock +0 -161
- data/LICENSE.txt +0 -22
- data/README.md +0 -83
- data/Rakefile +0 -13
- data/cocoapods-binary-matchup.gemspec +0 -27
- data/lib/cocoapods-binary-matchup/Integration.rb +0 -287
- data/lib/cocoapods-binary-matchup/Integration_cache.rb +0 -320
- data/lib/cocoapods-binary-matchup/Main.rb +0 -386
- data/lib/cocoapods-binary-matchup/Prebuild.rb +0 -249
- data/lib/cocoapods-binary-matchup/gem_version.rb +0 -3
- data/lib/cocoapods-binary-matchup/helper/feature_switches.rb +0 -109
- data/lib/cocoapods-binary-matchup/helper/passer.rb +0 -41
- data/lib/cocoapods-binary-matchup/helper/podfile_options.rb +0 -122
- data/lib/cocoapods-binary-matchup/helper/prebuild_sandbox.rb +0 -53
- data/lib/cocoapods-binary-matchup/helper/target_checker.rb +0 -49
- data/lib/cocoapods-binary-matchup/rome/build_framework.rb +0 -316
- data/lib/cocoapods-binary-matchup/tool/tool.rb +0 -12
- data/lib/cocoapods-binary.rb +0 -1
- data/lib/cocoapods_plugin.rb +0 -2
- data/spec/plugin_spec.rb +0 -43
- data/spec/spec_helper.rb +0 -50
|
@@ -1,386 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
require_relative 'helper/podfile_options'
|
|
3
|
-
require_relative 'tool/tool'
|
|
4
|
-
require_relative 'Integration_cache'
|
|
5
|
-
|
|
6
|
-
module Pod
|
|
7
|
-
class Podfile
|
|
8
|
-
module DSL
|
|
9
|
-
|
|
10
|
-
# Enable prebuiding for all pods
|
|
11
|
-
# it has a lower priority to other binary settings
|
|
12
|
-
def all_binary!
|
|
13
|
-
DSL.prebuild_all = true
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Disable simulator build
|
|
17
|
-
def simulator_build_disable!
|
|
18
|
-
DSL.simulator_build_enabled = false
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# Enable bitcode for prebuilt frameworks
|
|
22
|
-
def enable_bitcode_for_prebuilt_frameworks!
|
|
23
|
-
DSL.bitcode_enabled = true
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# Don't remove source code of prebuilt pods
|
|
27
|
-
# It may speed up the pod install if git didn't
|
|
28
|
-
# include the `Pods` folder
|
|
29
|
-
def keep_source_code_for_prebuilt_frameworks!
|
|
30
|
-
DSL.dont_remove_source_code = true
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# Add custom xcodebuild option to the prebuilding action
|
|
35
|
-
#
|
|
36
|
-
# You may use this for your special demands. For example: the default archs in dSYMs
|
|
37
|
-
# of prebuilt frameworks is 'arm64 armv7 x86_64', and no 'i386' for 32bit simulator.
|
|
38
|
-
# It may generate a warning when building for a 32bit simulator. You may add following
|
|
39
|
-
# to your podfile
|
|
40
|
-
#
|
|
41
|
-
# ` set_custom_xcodebuild_options_for_prebuilt_frameworks :simulator => "ARCHS=$(ARCHS_STANDARD)" `
|
|
42
|
-
#
|
|
43
|
-
# Another example to disable the generating of dSYM file:
|
|
44
|
-
#
|
|
45
|
-
# ` set_custom_xcodebuild_options_for_prebuilt_frameworks "DEBUG_INFORMATION_FORMAT=dwarf"`
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
# @param [String or Hash] options
|
|
49
|
-
#
|
|
50
|
-
# If is a String, it will apply for device and simulator. Use it just like in the commandline.
|
|
51
|
-
# If is a Hash, it should be like this: { :device => "XXXXX", :simulator => "XXXXX" }
|
|
52
|
-
#
|
|
53
|
-
def set_custom_xcodebuild_options_for_prebuilt_frameworks(options)
|
|
54
|
-
if options.kind_of? Hash
|
|
55
|
-
DSL.custom_build_options = [ options[:device] ] unless options[:device].nil?
|
|
56
|
-
DSL.custom_build_options_simulator = [ options[:simulator] ] unless options[:simulator].nil?
|
|
57
|
-
elsif options.kind_of? String
|
|
58
|
-
DSL.custom_build_options = [options]
|
|
59
|
-
DSL.custom_build_options_simulator = [options]
|
|
60
|
-
else
|
|
61
|
-
raise "Wrong type."
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
class_attr_accessor :simulator_build_enabled
|
|
66
|
-
self.simulator_build_enabled = true
|
|
67
|
-
|
|
68
|
-
private
|
|
69
|
-
class_attr_accessor :prebuild_all
|
|
70
|
-
self.prebuild_all = false
|
|
71
|
-
|
|
72
|
-
class_attr_accessor :bitcode_enabled
|
|
73
|
-
self.bitcode_enabled = false
|
|
74
|
-
|
|
75
|
-
class_attr_accessor :dont_remove_source_code
|
|
76
|
-
self.dont_remove_source_code = false
|
|
77
|
-
|
|
78
|
-
class_attr_accessor :custom_build_options
|
|
79
|
-
class_attr_accessor :custom_build_options_simulator
|
|
80
|
-
self.custom_build_options = []
|
|
81
|
-
self.custom_build_options_simulator = []
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
Pod::HooksManager.register('cocoapods-binary-matchup', :pre_install) do |installer_context|
|
|
87
|
-
|
|
88
|
-
require_relative 'helper/feature_switches'
|
|
89
|
-
if Pod.is_prebuild_stage
|
|
90
|
-
next
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# [Check Environment]
|
|
94
|
-
# check user_framework is on
|
|
95
|
-
podfile = installer_context.podfile
|
|
96
|
-
podfile.target_definition_list.each do |target_definition|
|
|
97
|
-
next if target_definition.prebuild_framework_names.empty?
|
|
98
|
-
if not target_definition.uses_frameworks?
|
|
99
|
-
STDERR.puts "[!] Cocoapods-binary requires `use_frameworks!`".red
|
|
100
|
-
exit
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
main_target = installer_context.podfile.target_definition_list[1]
|
|
105
|
-
if main_target.platform
|
|
106
|
-
Pod::UI.puts "📱 Project Main Target name: #{main_target.name}"
|
|
107
|
-
Pod.main_deployment_target_name = main_target.name
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# -- step 1: prebuild framework ---
|
|
111
|
-
# Execute a sperated pod install, to generate targets for building framework,
|
|
112
|
-
# then compile them to framework files.
|
|
113
|
-
require_relative 'helper/prebuild_sandbox'
|
|
114
|
-
require_relative 'Prebuild'
|
|
115
|
-
|
|
116
|
-
Pod::UI.puts "🚀 Prebuild frameworks"
|
|
117
|
-
|
|
118
|
-
# Fetch original installer (which is running this pre-install hook) options,
|
|
119
|
-
# then pass them to our installer to perform update if needed
|
|
120
|
-
# Looks like this is the most appropriate way to figure out that something should be updated
|
|
121
|
-
|
|
122
|
-
update = nil
|
|
123
|
-
repo_update = nil
|
|
124
|
-
|
|
125
|
-
# pod install → update=false, repo_update=false
|
|
126
|
-
# pod update → update=true, repo_update=false
|
|
127
|
-
# pod install --repo-update → update=false, repo_update=true
|
|
128
|
-
# pod update --repo-update → update=true, repo_update=true
|
|
129
|
-
include ObjectSpace
|
|
130
|
-
ObjectSpace.each_object(Pod::Installer) { |installer|
|
|
131
|
-
update = installer.update
|
|
132
|
-
repo_update = installer.repo_update
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
# control features
|
|
136
|
-
Pod.is_prebuild_stage = true
|
|
137
|
-
Pod::Podfile::DSL.enable_prebuild_patch true # enable sikpping for prebuild targets
|
|
138
|
-
Pod::Installer.force_disable_integration true # don't integrate targets
|
|
139
|
-
Pod::Config.force_disable_write_lockfile true # disbale write lock file for perbuild podfile
|
|
140
|
-
Pod::Installer.disable_install_complete_message true # disable install complete message
|
|
141
|
-
|
|
142
|
-
# make another custom sandbox
|
|
143
|
-
standard_sandbox = installer_context.sandbox
|
|
144
|
-
prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sandbox)
|
|
145
|
-
|
|
146
|
-
# get the podfile for prebuild
|
|
147
|
-
prebuild_podfile = Pod::Podfile.from_ruby(podfile.defined_in_file)
|
|
148
|
-
|
|
149
|
-
# install
|
|
150
|
-
lockfile = installer_context.lockfile
|
|
151
|
-
binary_installer = Pod::Installer.new(prebuild_sandbox, prebuild_podfile, lockfile)
|
|
152
|
-
|
|
153
|
-
# 优化的三级缓存逻辑
|
|
154
|
-
if binary_installer.have_exact_prebuild_cache? && !update
|
|
155
|
-
# 1. 优先:_prebuild 目录已有完整缓存
|
|
156
|
-
Pod::UI.puts "📦 Using exact prebuild cache from _Prebuild"
|
|
157
|
-
binary_installer.install_when_cache_hit!
|
|
158
|
-
else
|
|
159
|
-
# 3. 最后:重新构建
|
|
160
|
-
Pod::UI.puts "🔨 Building frameworks (no cache available)"
|
|
161
|
-
binary_installer.update = update
|
|
162
|
-
binary_installer.repo_update = repo_update
|
|
163
|
-
binary_installer.install!
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
# reset the environment
|
|
168
|
-
Pod.is_prebuild_stage = false
|
|
169
|
-
Pod::Installer.force_disable_integration false
|
|
170
|
-
Pod::Podfile::DSL.enable_prebuild_patch false
|
|
171
|
-
Pod::Config.force_disable_write_lockfile false
|
|
172
|
-
Pod::Installer.disable_install_complete_message false
|
|
173
|
-
|
|
174
|
-
# -- step 2: pod install ---
|
|
175
|
-
# install
|
|
176
|
-
Pod::UI.puts "\n"
|
|
177
|
-
Pod::UI.puts "🤖 Pod Install"
|
|
178
|
-
# 只有进入正常阶段才会执行Integration中的相关hook行为
|
|
179
|
-
require_relative 'Integration'
|
|
180
|
-
# go on the normal install step ...
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
Pod::HooksManager.register('cocoapods-binary-matchup', :post_install) do |installer_context|
|
|
184
|
-
require_relative 'Integration'
|
|
185
|
-
|
|
186
|
-
# 检查是否是预构建阶段,如果是则跳过
|
|
187
|
-
require_relative 'helper/feature_switches'
|
|
188
|
-
if Pod.is_prebuild_stage
|
|
189
|
-
next
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
Pod::UI.puts "📱 Post-install: Adding prebuilt framework resources to Pods-OMI-resources.sh"
|
|
193
|
-
|
|
194
|
-
# 从ObjectSpace中获取installer实例(类似pre_install hook的做法)
|
|
195
|
-
installer = nil
|
|
196
|
-
include ObjectSpace
|
|
197
|
-
ObjectSpace.each_object(Pod::Installer) { |inst| installer = inst }
|
|
198
|
-
|
|
199
|
-
if installer.nil?
|
|
200
|
-
Pod::UI.puts "⚠️ Could not find installer instance, skipping framework resources processing"
|
|
201
|
-
next
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
# 处理每个aggregate target的资源脚本
|
|
205
|
-
installer.aggregate_targets.each do |aggregate_target|
|
|
206
|
-
if !aggregate_target.static_framework?
|
|
207
|
-
Pod::UI.puts " ⚠️ Skipping static framework: #{aggregate_target.name}"
|
|
208
|
-
next
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
# 手动构建资源脚本路径(CocoaPods没有直接的script_path API)
|
|
212
|
-
target_support_dir = installer.sandbox.target_support_files_dir(aggregate_target.name)
|
|
213
|
-
script_path = target_support_dir + "#{aggregate_target.name}-resources.sh"
|
|
214
|
-
|
|
215
|
-
Pod::UI.puts " 🔍 Checking script path: #{script_path}"
|
|
216
|
-
next unless script_path.exist?
|
|
217
|
-
|
|
218
|
-
Pod::UI.puts " 🔧 Processing #{script_path.basename}"
|
|
219
|
-
|
|
220
|
-
# 收集预编译framework的资源
|
|
221
|
-
framework_resources = collect_prebuilt_framework_resources(installer, aggregate_target)
|
|
222
|
-
|
|
223
|
-
if framework_resources.any?
|
|
224
|
-
# 修改资源脚本
|
|
225
|
-
modify_resources_script(script_path, framework_resources)
|
|
226
|
-
Pod::UI.puts " ✅ Added #{framework_resources.count} framework resources to #{script_path.basename}"
|
|
227
|
-
else
|
|
228
|
-
Pod::UI.puts " ℹ️ No framework resources found for #{aggregate_target.name}"
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
Pod::UI.puts "✅ Framework resources processing completed"
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
# 收集预编译framework中的资源
|
|
236
|
-
def collect_prebuilt_framework_resources(installer, aggregate_target)
|
|
237
|
-
framework_resources = []
|
|
238
|
-
|
|
239
|
-
# 获取预编译的pod列表 - 强制刷新以确保获取最新状态
|
|
240
|
-
prebuilt_pod_names = installer.refresh_prebuild_pod_names!
|
|
241
|
-
|
|
242
|
-
aggregate_target.pod_targets.each do |pod_target|
|
|
243
|
-
next unless prebuilt_pod_names.include?(pod_target.pod_name)
|
|
244
|
-
|
|
245
|
-
Pod::UI.puts " 📱 Scanning prebuilt pod: #{pod_target.pod_name}"
|
|
246
|
-
|
|
247
|
-
# 获取pod目录
|
|
248
|
-
pod_dir = installer.sandbox.pod_dir(pod_target.pod_name)
|
|
249
|
-
next unless pod_dir.exist?
|
|
250
|
-
|
|
251
|
-
# 查找framework目录
|
|
252
|
-
framework_dirs = pod_dir.children.select { |child|
|
|
253
|
-
child.directory? && child.extname == '.framework'
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
framework_dirs.each do |framework_dir|
|
|
257
|
-
framework_name = framework_dir.basename.to_s
|
|
258
|
-
Pod::UI.puts " 🔍 Scanning framework: #{framework_name}"
|
|
259
|
-
|
|
260
|
-
# 扫描framework中的资源
|
|
261
|
-
resources = scan_framework_resources(framework_dir, pod_target.pod_name)
|
|
262
|
-
framework_resources.concat(resources)
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
framework_resources.uniq
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
# 扫描framework中的资源文件
|
|
270
|
-
def scan_framework_resources(framework_dir, pod_name)
|
|
271
|
-
resources = []
|
|
272
|
-
framework_name = framework_dir.basename.to_s
|
|
273
|
-
|
|
274
|
-
Pod::UI.puts " 🎯 Framework path: #{framework_dir}"
|
|
275
|
-
|
|
276
|
-
# 资源文件类型
|
|
277
|
-
resource_patterns = [
|
|
278
|
-
'*.png', '*.jpg', '*.jpeg', '*.gif', '*.webp', # 图片
|
|
279
|
-
'*.storyboard', '*.xib', # 界面文件
|
|
280
|
-
'*.storyboardc', # 编译后的storyboard
|
|
281
|
-
'*.nib', # 编译后的xib
|
|
282
|
-
'*.bundle', # 资源包
|
|
283
|
-
'*.ttf', '*.otf', # 字体
|
|
284
|
-
'*.mp3', '*.wav', '*.m4a', '*.mp4', '*.mov', # 媒体
|
|
285
|
-
'*.bin', # 二进制资源
|
|
286
|
-
'*.metallib' # metal or opengl文件
|
|
287
|
-
]
|
|
288
|
-
|
|
289
|
-
# 扫描framework根目录
|
|
290
|
-
resource_patterns.each do |pattern|
|
|
291
|
-
Dir.glob(framework_dir + pattern).each do |resource_path|
|
|
292
|
-
resource_file = Pathname(resource_path)
|
|
293
|
-
# 其他资源使用BUILT_PRODUCTS_DIR/framework路径
|
|
294
|
-
# 例如:${PODS_ROOT}/CocoaDebug/CocoaDebug.framework/App.storyboardc
|
|
295
|
-
resource_entry = "${PODS_ROOT}/#{pod_name}/#{framework_name}/#{resource_file.basename}"
|
|
296
|
-
resources << resource_entry
|
|
297
|
-
end
|
|
298
|
-
end
|
|
299
|
-
|
|
300
|
-
# 扫描framework/Resources目录
|
|
301
|
-
resources_dir = framework_dir + 'Resources'
|
|
302
|
-
if resources_dir.exist?
|
|
303
|
-
resource_patterns.each do |pattern|
|
|
304
|
-
Dir.glob(resources_dir + pattern).each do |resource_path|
|
|
305
|
-
resource_file = Pathname(resource_path)
|
|
306
|
-
|
|
307
|
-
# Resources目录中的资源也使用BUILT_PRODUCTS_DIR路径
|
|
308
|
-
resource_entry = "${PODS_ROOT}/#{pod_name}/#{framework_name}/#{resource_file.basename}"
|
|
309
|
-
resources << resource_entry
|
|
310
|
-
end
|
|
311
|
-
end
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
resources
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
# 修改resources脚本,添加framework资源
|
|
318
|
-
def modify_resources_script(script_path, framework_resources)
|
|
319
|
-
return if framework_resources.empty?
|
|
320
|
-
|
|
321
|
-
original_content = script_path.read
|
|
322
|
-
|
|
323
|
-
# 检查是否已经添加过framework资源(避免重复)
|
|
324
|
-
# if original_content.include?('# Prebuilt Framework Resources')
|
|
325
|
-
# Pod::UI.puts " ℹ️ Framework resources already added, skipping"
|
|
326
|
-
# return
|
|
327
|
-
# end
|
|
328
|
-
|
|
329
|
-
# Pod::UI.puts " 📝 Adding #{framework_resources.count} framework resources to script"
|
|
330
|
-
# framework_resources.each_with_index do |resource, index|
|
|
331
|
-
# Pod::UI.puts " #{index + 1}. #{resource}"
|
|
332
|
-
# end
|
|
333
|
-
|
|
334
|
-
# 构建要添加的资源安装代码
|
|
335
|
-
framework_resources_block = build_framework_resources_block(framework_resources)
|
|
336
|
-
|
|
337
|
-
# 在Debug配置块中插入framework资源(而不是脚本末尾)
|
|
338
|
-
debug_pattern = /if \[\[ "\$CONFIGURATION" == "Debug" \]\]; then/
|
|
339
|
-
if original_content.match(debug_pattern)
|
|
340
|
-
# 找到Debug配置块,在其中插入framework资源
|
|
341
|
-
modified_content = original_content.sub(debug_pattern) do |match|
|
|
342
|
-
"#{match}\n#{framework_resources_block}"
|
|
343
|
-
end
|
|
344
|
-
else
|
|
345
|
-
# 如果没有找到Debug配置块,创建一个新的
|
|
346
|
-
framework_resources_with_condition = <<~SCRIPT
|
|
347
|
-
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
|
348
|
-
#{framework_resources_block}
|
|
349
|
-
fi
|
|
350
|
-
SCRIPT
|
|
351
|
-
|
|
352
|
-
# 在脚本末尾(exit 0之前)插入
|
|
353
|
-
if original_content.include?('exit 0')
|
|
354
|
-
modified_content = original_content.sub(/exit 0/, "#{framework_resources_with_condition}\nexit 0")
|
|
355
|
-
else
|
|
356
|
-
modified_content = original_content + "\n#{framework_resources_with_condition}"
|
|
357
|
-
end
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
# 写回修改后的内容
|
|
361
|
-
script_path.write(modified_content)
|
|
362
|
-
|
|
363
|
-
Pod::UI.puts " ✅ Script modified successfully"
|
|
364
|
-
|
|
365
|
-
# 显示修改后脚本的相关部分以便验证
|
|
366
|
-
debug_lines = modified_content.lines.select.with_index do |line, index|
|
|
367
|
-
line.include?('CONFIGURATION') || line.include?('Prebuilt Framework') ||
|
|
368
|
-
(index > 0 && modified_content.lines[index-1].include?('CONFIGURATION'))
|
|
369
|
-
end
|
|
370
|
-
Pod::UI.puts " 📄 Debug configuration block preview:"
|
|
371
|
-
debug_lines.first(5).each { |line| Pod::UI.puts " #{line.chomp}" }
|
|
372
|
-
end
|
|
373
|
-
|
|
374
|
-
# 构建framework资源安装代码块
|
|
375
|
-
def build_framework_resources_block(framework_resources)
|
|
376
|
-
block = " # Prebuilt Framework Resources\n"
|
|
377
|
-
block += " echo \"Installing prebuilt framework resources...\"\n"
|
|
378
|
-
|
|
379
|
-
framework_resources.each do |resource|
|
|
380
|
-
block += " install_resource \"#{resource}\"\n"
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
block += " echo \"Prebuilt framework resources installation completed\"\n"
|
|
384
|
-
|
|
385
|
-
return block
|
|
386
|
-
end
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
require_relative 'rome/build_framework'
|
|
2
|
-
require_relative 'helper/passer'
|
|
3
|
-
require_relative 'helper/target_checker'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# patch prebuild ability
|
|
7
|
-
module Pod
|
|
8
|
-
class Installer
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
def local_manifest
|
|
14
|
-
if not @local_manifest_inited
|
|
15
|
-
@local_manifest_inited = true
|
|
16
|
-
raise "This method should be call before generate project" unless self.analysis_result == nil
|
|
17
|
-
@local_manifest = self.sandbox.manifest
|
|
18
|
-
end
|
|
19
|
-
@local_manifest
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# @return [Analyzer::SpecsState]
|
|
23
|
-
def prebuild_pods_changes
|
|
24
|
-
return nil if local_manifest.nil?
|
|
25
|
-
UI.puts "--------------------------------"
|
|
26
|
-
UI.puts "prebuild_pods_changes"
|
|
27
|
-
UI.puts "--------------------------------"
|
|
28
|
-
if @prebuild_pods_changes.nil?
|
|
29
|
-
# detect the changes with podfile by manifest.lock
|
|
30
|
-
changes = local_manifest.detect_changes_with_podfile(podfile)
|
|
31
|
-
@prebuild_pods_changes = Analyzer::SpecsState.new(changes)
|
|
32
|
-
# save the chagnes info for later stage
|
|
33
|
-
Pod::Prebuild::Passer.prebuild_pods_changes = @prebuild_pods_changes
|
|
34
|
-
end
|
|
35
|
-
@prebuild_pods_changes
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
public
|
|
40
|
-
|
|
41
|
-
# check if need to prebuild
|
|
42
|
-
def have_exact_prebuild_cache?
|
|
43
|
-
# check if need build frameworks
|
|
44
|
-
return false if local_manifest == nil
|
|
45
|
-
|
|
46
|
-
changes = prebuild_pods_changes
|
|
47
|
-
added = changes.added
|
|
48
|
-
changed = changes.changed
|
|
49
|
-
unchanged = changes.unchanged
|
|
50
|
-
deleted = changes.deleted
|
|
51
|
-
|
|
52
|
-
unchange_framework_names = (added + unchanged)
|
|
53
|
-
|
|
54
|
-
exsited_framework_names = sandbox.exsited_framework_names
|
|
55
|
-
missing = unchanged.select do |pod_name|
|
|
56
|
-
not exsited_framework_names.include?(pod_name)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
needed = (added + changed + deleted + missing)
|
|
60
|
-
return needed.empty?
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
# The install method when have completed cache
|
|
65
|
-
def install_when_cache_hit!
|
|
66
|
-
# just print log
|
|
67
|
-
self.sandbox.exsited_framework_names.each do |name|
|
|
68
|
-
UI.puts "Using #{name}"
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
# Build the needed framework files
|
|
74
|
-
def prebuild_frameworks!
|
|
75
|
-
|
|
76
|
-
# check
|
|
77
|
-
# give a early warning, instead of after compiling all the pods
|
|
78
|
-
Prebuild.check_one_pod_should_have_only_one_target(self.pod_targets)
|
|
79
|
-
|
|
80
|
-
# build options
|
|
81
|
-
sandbox_path = sandbox.root
|
|
82
|
-
existed_framework_folder = sandbox.generate_framework_path
|
|
83
|
-
bitcode_enabled = Pod::Podfile::DSL.bitcode_enabled
|
|
84
|
-
targets = []
|
|
85
|
-
|
|
86
|
-
if local_manifest != nil
|
|
87
|
-
|
|
88
|
-
changes = prebuild_pods_changes
|
|
89
|
-
added = changes.added
|
|
90
|
-
changed = changes.changed
|
|
91
|
-
unchanged = changes.unchanged
|
|
92
|
-
deleted = changes.deleted
|
|
93
|
-
|
|
94
|
-
existed_framework_folder.mkdir unless existed_framework_folder.exist?
|
|
95
|
-
exsited_framework_names = sandbox.exsited_framework_names
|
|
96
|
-
|
|
97
|
-
# additions
|
|
98
|
-
missing = unchanged.select do |pod_name|
|
|
99
|
-
not exsited_framework_names.include?(pod_name)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
root_names_to_update = (added + changed + missing)
|
|
103
|
-
|
|
104
|
-
# transform names to targets
|
|
105
|
-
name_to_target_hash = self.pod_targets.reduce({}) do |sum, target|
|
|
106
|
-
sum[target.name] = target
|
|
107
|
-
sum
|
|
108
|
-
end
|
|
109
|
-
targets = root_names_to_update.map do |root_name|
|
|
110
|
-
t = name_to_target_hash[root_name]
|
|
111
|
-
raise "There's no target named (#{root_name}) in Pod.xcodeproj.\n #{name_to_target_hash.keys}" if t.nil?
|
|
112
|
-
t
|
|
113
|
-
end || []
|
|
114
|
-
|
|
115
|
-
# add the dendencies
|
|
116
|
-
dependency_targets = targets.map {|t| t.recursive_dependent_targets }.flatten.uniq || []
|
|
117
|
-
targets = (targets + dependency_targets).uniq
|
|
118
|
-
else
|
|
119
|
-
targets = self.pod_targets
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
targets = targets.reject {|pod_target| sandbox.local?(pod_target.pod_name) }
|
|
123
|
-
|
|
124
|
-
Pod::PrebuildCache::Cache.remove_all_invalid_cache(sandbox, targets)
|
|
125
|
-
|
|
126
|
-
# build!
|
|
127
|
-
Pod::UI.puts "Prebuild frameworks (total #{targets.count})"
|
|
128
|
-
Pod::Prebuild.remove_build_dir(sandbox_path)
|
|
129
|
-
targets.each do |target|
|
|
130
|
-
# If target shouldn't build, we copy all the original files
|
|
131
|
-
# This is for target with only .a and .h files
|
|
132
|
-
if !target.should_build?
|
|
133
|
-
UI.puts "Prebuilding #{target.label}"
|
|
134
|
-
next
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
standard_sandbox_path = sandbox.standard_sanbox_path
|
|
138
|
-
Pod::UI.puts "📦 [#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}] Prebuild Start pod: #{target.pod_name}"
|
|
139
|
-
if Pod::PrebuildCache::Cache.restore_from_pod_cache(target.pod_name, sandbox)
|
|
140
|
-
Pod::UI.puts "📦 [#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}] Using exact cache from ~/.PodCache"
|
|
141
|
-
next
|
|
142
|
-
end
|
|
143
|
-
Pod::UI.puts "📦 [#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}] Prebuild End pod: #{target.pod_name}"
|
|
144
|
-
|
|
145
|
-
output_path = sandbox.framework_folder_path_for_pod_name(target.name)
|
|
146
|
-
output_path.mkpath unless output_path.exist?
|
|
147
|
-
Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled, Podfile::DSL.custom_build_options, Podfile::DSL.custom_build_options_simulator)
|
|
148
|
-
|
|
149
|
-
# save the resource paths for later installing
|
|
150
|
-
if target.static_framework? and !target.resource_paths.empty?
|
|
151
|
-
framework_path = output_path + target.framework_name
|
|
152
|
-
standard_sandbox_path = sandbox.standard_sanbox_path
|
|
153
|
-
|
|
154
|
-
resources = begin
|
|
155
|
-
if Pod::VERSION.start_with? "1.5"
|
|
156
|
-
target.resource_paths
|
|
157
|
-
else
|
|
158
|
-
# resource_paths is Hash{String=>Array<String>} on 1.6 and above
|
|
159
|
-
# (use AFNetworking to generate a demo data)
|
|
160
|
-
# https://github.com/leavez/cocoapods-binary/issues/50
|
|
161
|
-
target.resource_paths.values.flatten
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
raise "Wrong type: #{resources}" unless resources.kind_of? Array
|
|
165
|
-
|
|
166
|
-
path_objects = resources.map do |path|
|
|
167
|
-
object = Prebuild::Passer::ResourcePath.new
|
|
168
|
-
object.real_file_path = framework_path + File.basename(path)
|
|
169
|
-
object.target_file_path = path.gsub('${PODS_ROOT}', standard_sandbox_path.to_s) if path.start_with? '${PODS_ROOT}'
|
|
170
|
-
object.target_file_path = path.gsub("${PODS_CONFIGURATION_BUILD_DIR}", standard_sandbox_path.to_s) if path.start_with? "${PODS_CONFIGURATION_BUILD_DIR}"
|
|
171
|
-
object
|
|
172
|
-
end
|
|
173
|
-
Prebuild::Passer.resources_to_copy_for_static_framework[target.name] = path_objects
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
Pod::Prebuild.remove_build_dir(sandbox_path)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
# copy vendored libraries and frameworks
|
|
180
|
-
targets.each do |target|
|
|
181
|
-
root_path = self.sandbox.pod_dir(target.name)
|
|
182
|
-
target_folder = sandbox.framework_folder_path_for_pod_name(target.name)
|
|
183
|
-
|
|
184
|
-
# If target shouldn't build, we copy all the original files
|
|
185
|
-
# This is for target with only .a and .h files
|
|
186
|
-
if not target.should_build?
|
|
187
|
-
Prebuild::Passer.target_names_to_skip_integration_framework << target.pod_name
|
|
188
|
-
FileUtils.cp_r(root_path, target_folder, :remove_destination => true)
|
|
189
|
-
next
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
# copy the vendored frameworks and libraries in _Prebuild to Pods/
|
|
193
|
-
target.spec_consumers.each do |consumer|
|
|
194
|
-
file_accessor = Sandbox::FileAccessor.new(root_path, consumer)
|
|
195
|
-
lib_paths = file_accessor.vendored_frameworks || []
|
|
196
|
-
lib_paths += file_accessor.vendored_libraries
|
|
197
|
-
# @TODO dSYM files
|
|
198
|
-
lib_paths.each do |lib_path|
|
|
199
|
-
relative = lib_path.relative_path_from(root_path)
|
|
200
|
-
destination = target_folder + relative
|
|
201
|
-
destination.dirname.mkpath unless destination.dirname.exist?
|
|
202
|
-
FileUtils.cp_r(lib_path, destination, :remove_destination => true)
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
# save the manifest.lock to cache
|
|
208
|
-
Pod::PrebuildCache::Cache.save_manifest_to_cache(sandbox)
|
|
209
|
-
|
|
210
|
-
# Remove useless files
|
|
211
|
-
# remove useless pods
|
|
212
|
-
all_needed_names = self.pod_targets.map(&:name).uniq
|
|
213
|
-
useless_names = sandbox.exsited_framework_names.reject do |name|
|
|
214
|
-
all_needed_names.include? name
|
|
215
|
-
end
|
|
216
|
-
useless_names.each do |name|
|
|
217
|
-
path = sandbox.framework_folder_path_for_pod_name(name)
|
|
218
|
-
path.rmtree if path.exist?
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
if not Podfile::DSL.dont_remove_source_code
|
|
222
|
-
# only keep manifest.lock and framework folder in _Prebuild
|
|
223
|
-
to_remain_files = ["Manifest.lock", File.basename(existed_framework_folder)]
|
|
224
|
-
to_delete_files = sandbox_path.children.select do |file|
|
|
225
|
-
filename = File.basename(file)
|
|
226
|
-
not to_remain_files.include?(filename)
|
|
227
|
-
end
|
|
228
|
-
to_delete_files.each do |path|
|
|
229
|
-
path.rmtree if path.exist?
|
|
230
|
-
end
|
|
231
|
-
else
|
|
232
|
-
# just remove the tmp files
|
|
233
|
-
path = sandbox.root + 'Manifest.lock.tmp'
|
|
234
|
-
path.rmtree if path.exist?
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
# patch the post install hook
|
|
240
|
-
old_method2 = instance_method(:run_plugins_post_install_hooks)
|
|
241
|
-
define_method(:run_plugins_post_install_hooks) do
|
|
242
|
-
old_method2.bind(self).()
|
|
243
|
-
if Pod::is_prebuild_stage
|
|
244
|
-
self.prebuild_frameworks!
|
|
245
|
-
end
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
end
|
|
249
|
-
end
|