cocoapods-binary-cache 0.1.7 → 0.1.12
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
- data/lib/cocoapods-binary-cache/cache/validation_result.rb +4 -0
- data/lib/cocoapods-binary-cache/dependencies_graph/dependencies_graph.rb +20 -25
- data/lib/cocoapods-binary-cache/dependencies_graph/graph_visualizer.rb +29 -38
- data/lib/cocoapods-binary-cache/diagnosis/diagnosis.rb +9 -1
- data/lib/cocoapods-binary-cache/diagnosis/integration.rb +3 -1
- data/lib/cocoapods-binary-cache/helper/podspec.rb +4 -2
- data/lib/cocoapods-binary-cache/hooks/post_install.rb +2 -12
- data/lib/cocoapods-binary-cache/hooks/pre_install.rb +19 -36
- data/lib/cocoapods-binary-cache/main.rb +0 -1
- data/lib/cocoapods-binary-cache/pod-binary/helper/build.rb +27 -29
- data/lib/cocoapods-binary-cache/pod-binary/helper/detected_prebuilt_pods/installer.rb +1 -1
- data/lib/cocoapods-binary-cache/pod-binary/helper/prebuild_sandbox.rb +14 -13
- data/lib/cocoapods-binary-cache/pod-binary/helper/target_checker.rb +7 -10
- data/lib/cocoapods-binary-cache/pod-binary/integration.rb +1 -2
- data/lib/cocoapods-binary-cache/pod-binary/integration/alter_specs.rb +32 -15
- data/lib/cocoapods-binary-cache/pod-binary/integration/patch/embed_framework_script.rb +1 -1
- data/lib/cocoapods-binary-cache/pod-binary/integration/patch/resolve_dependencies.rb +0 -3
- data/lib/cocoapods-binary-cache/pod-binary/integration/patch/sandbox_analyzer_state.rb +29 -0
- data/lib/cocoapods-binary-cache/pod-binary/integration/patch/source_installation.rb +25 -11
- data/lib/cocoapods-binary-cache/pod-binary/integration/source_installer.rb +30 -19
- data/lib/cocoapods-binary-cache/pod-binary/prebuild.rb +30 -108
- data/lib/cocoapods-binary-cache/pod-binary/prebuild_dsl.rb +0 -2
- data/lib/cocoapods-binary-cache/pod-binary/prebuild_hook.rb +0 -1
- data/lib/cocoapods-binary-cache/pod-rome/xcodebuild_command.rb +222 -146
- data/lib/cocoapods-binary-cache/pod-rome/xcodebuild_raw.rb +45 -32
- data/lib/cocoapods-binary-cache/prebuild_output/output.rb +6 -4
- data/lib/cocoapods-binary-cache/state_store.rb +16 -6
- data/lib/command/config.rb +42 -4
- data/lib/command/executor/base.rb +18 -1
- data/lib/command/executor/fetcher.rb +21 -3
- data/lib/command/executor/prebuilder.rb +9 -7
- data/lib/command/executor/pusher.rb +20 -4
- data/lib/command/executor/visualizer.rb +3 -2
- data/lib/command/prebuild.rb +6 -0
- metadata +17 -7
- data/lib/cocoapods-binary-cache/pod-binary/helper/feature_switches.rb +0 -52
- data/lib/cocoapods-binary-cache/pod-binary/helper/passer.rb +0 -25
- data/lib/cocoapods-binary-cache/pod-binary/integration/remove_target_files.rb +0 -29
- data/lib/cocoapods-binary-cache/pod-binary/tool/tool.rb +0 -12
- data/lib/cocoapods-binary-cache/scheme_editor.rb +0 -35
@@ -1,176 +1,252 @@
|
|
1
1
|
require_relative "xcodebuild_raw"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
3
|
+
module PodPrebuild
|
4
|
+
class XcodebuildCommand # rubocop:disable Metrics/ClassLength
|
5
|
+
def initialize(options)
|
6
|
+
@options = options
|
7
|
+
case options[:targets][0].platform.name
|
8
|
+
when :ios
|
9
|
+
@options[:device] = "iphoneos"
|
10
|
+
@options[:simulator] = "iphonesimulator"
|
11
|
+
when :tvos
|
12
|
+
@options[:device] = "appletvos"
|
13
|
+
@options[:simulator] = "appletvsimulator"
|
14
|
+
when :watchos
|
15
|
+
@options[:device] = "watchos"
|
16
|
+
@options[:simulator] = "watchsimulator"
|
17
|
+
end
|
18
|
+
@build_args = make_up_build_args(options[:args] || {})
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
def run
|
22
|
+
sdks.each { |sdk| build_for_sdk(sdk) }
|
23
|
+
|
24
|
+
targets.each do |target|
|
25
|
+
if PodPrebuild.config.xcframework?
|
26
|
+
create_xcframework(target)
|
27
|
+
elsif sdks.count > 1
|
28
|
+
create_fat_framework(target)
|
29
|
+
else
|
30
|
+
collect_output(target, Dir[target_products_dir_of(target, sdks[0]) + "/*"])
|
31
|
+
end
|
32
|
+
end
|
28
33
|
end
|
29
|
-
collect_output(Dir[target_products_dir_of(simulator) + "/*"])
|
30
|
-
end
|
31
34
|
|
32
|
-
|
33
|
-
|
34
|
-
def make_up_build_args(args)
|
35
|
-
args_ = args.clone
|
36
|
-
args_[:default] ||= []
|
37
|
-
args_[:simulator] ||= []
|
38
|
-
args_[:device] ||= []
|
39
|
-
args_[:default] += ["BITCODE_GENERATION_MODE=bitcode"] if bitcode_enabled?
|
40
|
-
args_[:default] += ["DEBUG_INFORMATION_FORMAT=dwarf"] if disable_dsym?
|
41
|
-
args_[:simulator] += ["ARCHS=x86_64", "ONLY_ACTIVE_ARCH=NO"] if simulator == "iphonesimulator"
|
42
|
-
args_[:simulator] += args_[:default]
|
43
|
-
args_[:device] += args_[:default]
|
44
|
-
args_
|
45
|
-
end
|
35
|
+
private
|
46
36
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
sandbox: sandbox,
|
56
|
-
target: target.label,
|
57
|
-
configuration: configuration,
|
58
|
-
sdk: sdk,
|
59
|
-
deployment_target: target.platform.deployment_target.to_s,
|
60
|
-
args: sdk == simulator ? @build_args[:simulator] : @build_args[:device]
|
61
|
-
)
|
62
|
-
raise "Build framework failed: #{target.label}" unless succeeded
|
63
|
-
end
|
37
|
+
def sdks
|
38
|
+
@sdks ||= begin
|
39
|
+
sdks_ = []
|
40
|
+
sdks_ << simulator if build_types.include?(:simulator)
|
41
|
+
sdks_ << device if build_types.include?(:device)
|
42
|
+
sdks_
|
43
|
+
end
|
44
|
+
end
|
64
45
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
46
|
+
def build_types
|
47
|
+
@build_types ||= begin
|
48
|
+
# TODO (thuyen): Add DSL options `build_for_types` to specify build types
|
49
|
+
types = [:simulator]
|
50
|
+
types << :device if device_build_enabled?
|
51
|
+
types
|
52
|
+
end
|
53
|
+
end
|
71
54
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
55
|
+
def make_up_build_args(args)
|
56
|
+
# Note: The build arguments explicitly passed from config_cocoapods_binary_cache
|
57
|
+
# should be preceded by the default arguments so that they could take higher priority
|
58
|
+
# when there are argument collisions in the xcodebuild command.
|
59
|
+
# For ex. `xcodebuild AN_ARG=1 AN_ARG=2` should use `AN_ARG=2` instead.
|
60
|
+
args_ = args.clone
|
61
|
+
args_[:default] ||= []
|
62
|
+
args_[:simulator] ||= []
|
63
|
+
args_[:device] ||= []
|
64
|
+
args_[:default].prepend("BITCODE_GENERATION_MODE=bitcode") if bitcode_enabled?
|
65
|
+
args_[:default].prepend("DEBUG_INFORMATION_FORMAT=dwarf") if disable_dsym?
|
66
|
+
args_[:simulator].prepend("ARCHS=x86_64", "ONLY_ACTIVE_ARCH=NO") if simulator == "iphonesimulator"
|
67
|
+
args_[:simulator] += args_[:default]
|
68
|
+
args_[:device].prepend("ONLY_ACTIVE_ARCH=NO")
|
69
|
+
args_[:device] += args_[:default]
|
70
|
+
args_
|
71
|
+
end
|
76
72
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
73
|
+
def build_for_sdk(sdk)
|
74
|
+
PodPrebuild::XcodebuildCommand.xcodebuild(
|
75
|
+
sandbox: sandbox,
|
76
|
+
scheme: scheme,
|
77
|
+
targets: targets.map(&:label),
|
78
|
+
configuration: configuration,
|
79
|
+
sdk: sdk,
|
80
|
+
deployment_target: targets.map { |t| t.platform.deployment_target }.max.to_s,
|
81
|
+
args: sdk == simulator ? @build_args[:simulator] : @build_args[:device]
|
82
|
+
)
|
83
|
+
end
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
85
|
+
def create_xcframework(target)
|
86
|
+
non_framework_paths = Dir[target_products_dir_of(target, sdks[0]) + "/*"] \
|
87
|
+
- [framework_path_of(target, sdks[0])] \
|
88
|
+
- dsym_paths_of(target, sdks[0]) \
|
89
|
+
- bcsymbolmap_paths_of(target, sdks[0])
|
90
|
+
collect_output(target, non_framework_paths)
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
device_header_path = framework_path_of(device) + "/Headers/#{module_name}-Swift.h"
|
94
|
-
return unless File.exist?(simulator_header_path) && File.exist?(device_header_path)
|
95
|
-
|
96
|
-
merged_header = <<~HEREDOC
|
97
|
-
#if TARGET_OS_SIMULATOR // merged by cocoapods-binary
|
98
|
-
#{File.read(simulator_header_path)}
|
99
|
-
#else // merged by cocoapods-binary
|
100
|
-
#{File.read(device_header_path)}
|
101
|
-
#endif // merged by cocoapods-binary
|
102
|
-
HEREDOC
|
103
|
-
File.write(simulator_header_path, merged_header.strip)
|
104
|
-
end
|
92
|
+
output = "#{output_path(target)}/#{target.product_module_name}.xcframework"
|
93
|
+
FileUtils.rm_rf(output)
|
105
94
|
|
106
|
-
|
107
|
-
simulator_swift_module_path = framework_path_of(simulator) + "/Modules/#{module_name}.swiftmodule"
|
108
|
-
device_swift_module_path = framework_path_of(device) + "/Modules/#{module_name}.swiftmodule"
|
109
|
-
return unless File.exist?(simulator_swift_module_path) && File.exist?(device_swift_module_path)
|
95
|
+
cmd = ["xcodebuild", "-create-xcframework", "-allow-internal-distribution"]
|
110
96
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
97
|
+
# for each sdk, the order of params must be -framework then -debug-symbols
|
98
|
+
# to prevent duplicated file error when copying dSYMs
|
99
|
+
sdks.each do |sdk|
|
100
|
+
cmd << "-framework" << framework_path_of(target, sdk)
|
101
|
+
|
102
|
+
unless disable_dsym?
|
103
|
+
dsyms = dsym_paths_of(target, sdk)
|
104
|
+
cmd += dsyms.map { |dsym| "-debug-symbols #{dsym}" }
|
105
|
+
end
|
106
|
+
|
107
|
+
if bitcode_enabled?
|
108
|
+
bcsymbolmaps = bcsymbolmap_paths_of(target, sdk)
|
109
|
+
cmd += bcsymbolmaps.map { |bcsymbolmap| "-debug-symbols #{bcsymbolmap}" }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
cmd << "-output" << output
|
116
114
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
FileUtils.mv(path, output_path)
|
115
|
+
Pod::UI.puts "- Create xcframework: #{target}".magenta
|
116
|
+
Pod::UI.puts_indented "$ #{cmd.join(' ')}" unless PodPrebuild.config.silent_build?
|
117
|
+
|
118
|
+
`#{cmd.join(" ")}`
|
122
119
|
end
|
123
|
-
end
|
124
120
|
|
125
|
-
|
126
|
-
|
127
|
-
|
121
|
+
def create_fat_framework(target)
|
122
|
+
# When merging contents of `simulator` & `device`, prefer contents of `device` over `simulator`
|
123
|
+
# https://github.com/grab/cocoapods-binary-cache/issues/25
|
124
|
+
collect_output(target, Dir[target_products_dir_of(target, device) + "/*"])
|
128
125
|
|
129
|
-
|
130
|
-
|
131
|
-
|
126
|
+
merge_framework_binary(target)
|
127
|
+
merge_framework_dsym(target)
|
128
|
+
merge_swift_headers(target)
|
129
|
+
merge_swift_modules(target)
|
130
|
+
end
|
132
131
|
|
133
|
-
|
134
|
-
|
135
|
-
|
132
|
+
def merge_framework_binary(target)
|
133
|
+
merge_contents(target, "/#{target.product_module_name}", &method(:create_fat_binary))
|
134
|
+
end
|
136
135
|
|
137
|
-
|
138
|
-
|
139
|
-
|
136
|
+
def merge_framework_dsym(target)
|
137
|
+
merge_contents(
|
138
|
+
target,
|
139
|
+
".dSYM/Contents/Resources/DWARF/#{target.product_module_name}",
|
140
|
+
&method(:create_fat_binary)
|
141
|
+
)
|
142
|
+
end
|
140
143
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
+
def merge_swift_headers(target)
|
145
|
+
merge_contents(target, "/Headers/#{target.product_module_name}-Swift.h") do |options|
|
146
|
+
merged_header = <<~HEREDOC
|
147
|
+
#if TARGET_OS_SIMULATOR // merged by cocoapods-binary
|
148
|
+
#{File.read(options[:simulator])}
|
149
|
+
#else // merged by cocoapods-binary
|
150
|
+
#{File.read(options[:device])}
|
151
|
+
#endif // merged by cocoapods-binary
|
152
|
+
HEREDOC
|
153
|
+
File.write(options[:output], merged_header.strip)
|
154
|
+
end
|
155
|
+
end
|
144
156
|
|
145
|
-
|
146
|
-
|
147
|
-
|
157
|
+
def merge_swift_modules(target)
|
158
|
+
merge_contents(target, "/Modules/#{target.product_module_name}.swiftmodule") do |options|
|
159
|
+
# Note: swiftmodules of `device` were copied beforehand,
|
160
|
+
# here, we only need to copy swiftmodules of `simulator`
|
161
|
+
FileUtils.cp_r(options[:simulator] + "/.", options[:output])
|
162
|
+
end
|
163
|
+
end
|
148
164
|
|
149
|
-
|
150
|
-
|
151
|
-
|
165
|
+
def merge_contents(target, path_suffix, &merger)
|
166
|
+
simulator_, device_, output_ = [
|
167
|
+
framework_path_of(target, simulator),
|
168
|
+
framework_path_of(target, device),
|
169
|
+
"#{output_path(target)}/#{target.product_module_name}.framework"
|
170
|
+
].map { |p| p + path_suffix }
|
171
|
+
return unless File.exist?(simulator_) && File.exist?(device_)
|
152
172
|
|
153
|
-
|
154
|
-
|
155
|
-
end
|
173
|
+
merger.call(simulator: simulator_, device: device_, output: output_)
|
174
|
+
end
|
156
175
|
|
157
|
-
|
158
|
-
|
159
|
-
|
176
|
+
def create_fat_binary(options)
|
177
|
+
cmd = ["lipo", " -create"]
|
178
|
+
cmd << "-output" << options[:output]
|
179
|
+
cmd << options[:simulator] << options[:device]
|
180
|
+
`#{cmd.join(" ")}`
|
181
|
+
end
|
160
182
|
|
161
|
-
|
162
|
-
|
163
|
-
|
183
|
+
def collect_output(target, paths)
|
184
|
+
FileUtils.mkdir_p(output_path(target))
|
185
|
+
paths = [paths] unless paths.is_a?(Array)
|
186
|
+
paths.each do |path|
|
187
|
+
FileUtils.rm_rf(File.join(output_path(target), File.basename(path)))
|
188
|
+
FileUtils.cp_r(path, output_path(target))
|
189
|
+
end
|
190
|
+
end
|
164
191
|
|
165
|
-
|
166
|
-
|
167
|
-
|
192
|
+
def target_products_dir_of(target, sdk)
|
193
|
+
"#{build_dir}/#{configuration}-#{sdk}/#{target.name}"
|
194
|
+
end
|
168
195
|
|
169
|
-
|
170
|
-
|
171
|
-
|
196
|
+
def framework_path_of(target, sdk)
|
197
|
+
"#{target_products_dir_of(target, sdk)}/#{target.product_module_name}.framework"
|
198
|
+
end
|
172
199
|
|
173
|
-
|
174
|
-
|
200
|
+
def dsym_paths_of(target, sdk)
|
201
|
+
Dir["#{target_products_dir_of(target, sdk)}/*.dSYM"]
|
202
|
+
end
|
203
|
+
|
204
|
+
def bcsymbolmap_paths_of(target, sdk)
|
205
|
+
Dir["#{target_products_dir_of(target, sdk)}/*.bcsymbolmap"]
|
206
|
+
end
|
207
|
+
|
208
|
+
def sandbox
|
209
|
+
@options[:sandbox]
|
210
|
+
end
|
211
|
+
|
212
|
+
def build_dir
|
213
|
+
@options[:build_dir]
|
214
|
+
end
|
215
|
+
|
216
|
+
def output_path(target)
|
217
|
+
"#{@options[:output_path]}/#{target.label}"
|
218
|
+
end
|
219
|
+
|
220
|
+
def scheme
|
221
|
+
@options[:scheme]
|
222
|
+
end
|
223
|
+
|
224
|
+
def targets
|
225
|
+
@options[:targets]
|
226
|
+
end
|
227
|
+
|
228
|
+
def configuration
|
229
|
+
@options[:configuration]
|
230
|
+
end
|
231
|
+
|
232
|
+
def bitcode_enabled?
|
233
|
+
@options[:bitcode_enabled]
|
234
|
+
end
|
235
|
+
|
236
|
+
def device_build_enabled?
|
237
|
+
@options[:device_build_enabled]
|
238
|
+
end
|
239
|
+
|
240
|
+
def device
|
241
|
+
@options[:device] || "iphoneos"
|
242
|
+
end
|
243
|
+
|
244
|
+
def simulator
|
245
|
+
@options[:simulator] || "iphonesimulator"
|
246
|
+
end
|
247
|
+
|
248
|
+
def disable_dsym?
|
249
|
+
@options[:disable_dsym]
|
250
|
+
end
|
175
251
|
end
|
176
252
|
end
|
@@ -1,43 +1,56 @@
|
|
1
1
|
require "fourflusher"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module PodPrebuild
|
4
|
+
class XcodebuildCommand
|
5
|
+
PLATFORM_OF_SDK = {
|
6
|
+
"iphonesimulator" => "iOS",
|
7
|
+
"appletvsimulator" => "tvOS",
|
8
|
+
"watchsimulator" => "watchOS"
|
9
|
+
}.freeze
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
DESTINATION_OF_SDK = {
|
12
|
+
"iphoneos" => "\"generic/platform=iOS\"",
|
13
|
+
"iphonesimulator" => "\"generic/platform=iOS Simulator\""
|
14
|
+
}.freeze
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
cmd << "-sdk" << sdk
|
18
|
-
cmd << Fourflusher::SimControl.new.destination(:oldest, platform, options[:deployment_target]) unless platform.nil?
|
19
|
-
cmd += options[:args] if options[:args]
|
20
|
-
cmd << "2>&1"
|
21
|
-
cmd = cmd.join(" ")
|
16
|
+
def self.xcodebuild(options)
|
17
|
+
sdk = options[:sdk] || "iphonesimulator"
|
18
|
+
targets = options[:targets] || [options[:target]]
|
19
|
+
platform = PLATFORM_OF_SDK[sdk]
|
22
20
|
|
23
|
-
|
24
|
-
|
21
|
+
cmd = ["xcodebuild"]
|
22
|
+
cmd << "-project" << options[:sandbox].project_path.realdirpath.shellescape
|
23
|
+
targets.each { |target| cmd << "-target" << target }
|
24
|
+
cmd << "-configuration" << options[:configuration]
|
25
|
+
cmd << "-sdk" << sdk
|
26
|
+
if DESTINATION_OF_SDK.key?(sdk)
|
27
|
+
cmd << "-destination" << DESTINATION_OF_SDK[sdk]
|
28
|
+
else
|
29
|
+
cmd << Fourflusher::SimControl.new.destination(:oldest, platform, options[:deployment_target]) unless platform.nil?
|
30
|
+
end
|
31
|
+
cmd += options[:args] if options[:args]
|
32
|
+
cmd << "build"
|
33
|
+
cmd << "2>&1"
|
34
|
+
cmd = cmd.join(" ")
|
35
|
+
|
36
|
+
Pod::UI.puts_indented "$ #{cmd}" unless PodPrebuild.config.silent_build?
|
25
37
|
|
26
|
-
|
27
|
-
|
28
|
-
begin
|
29
|
-
raise "Unexpected error" unless log.include?("** BUILD FAILED **")
|
38
|
+
log = `#{cmd}`
|
39
|
+
return if $?.exitstatus.zero? # rubocop:disable Style/SpecialGlobalVars
|
30
40
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
41
|
+
begin
|
42
|
+
require "xcpretty" # TODO (thuyen): Revise this dependency
|
43
|
+
# use xcpretty to print build log
|
44
|
+
# 64 represent command invalid. http://www.manpagez.com/man/3/sysexits/
|
45
|
+
printer = XCPretty::Printer.new({:formatter => XCPretty::Simple, :colorize => "auto"})
|
46
|
+
log.each_line do |line|
|
47
|
+
printer.pretty_print(line)
|
48
|
+
end
|
49
|
+
rescue
|
50
|
+
Pod::UI.puts log.red
|
51
|
+
ensure
|
52
|
+
raise "Fail to build targets: #{targets}"
|
37
53
|
end
|
38
|
-
rescue
|
39
|
-
puts log.red
|
40
54
|
end
|
41
55
|
end
|
42
|
-
[succeeded, log]
|
43
56
|
end
|