cocoapods-hd 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb80241605ac54c86b3a1770e0cd87fa7d63a5e7e84040301d55199f4190bf5b
4
- data.tar.gz: 85f2e7154ef052f35bd40655d6861f0102958bab7bb1c2235e2582bcfcc6f563
3
+ metadata.gz: 7e8b9d1f1fd6f4b04751faac0ac3a6ed4ea5d819095007d4a5cb955bdfce7bb2
4
+ data.tar.gz: 85d409df189fed53fe5cb0cc92d8198928360a27b9ead0f2f573d45d5ecd8476
5
5
  SHA512:
6
- metadata.gz: a5f23b369a48b02bb6b8ef60b02860bfe5f589aa260f75d1647e1e16f38efc69a700286b3d30e41f55c8e943333e908d4b019a0dbb5ba61efd581603263bc362
7
- data.tar.gz: 2c5ffa3f1739c93f7b459a4732493ae6da54ea90a3458ce89a06dae219475d25f0c039bf8adf83b86f7a6ae1bacb90e82f942f02caeedff50e039f87676bb9f1
6
+ metadata.gz: 2605374c2c6c36cadb810b316a34dcd02976f5eb045430ff6fc00d074d1e9f462291d771698d3dd5661c3972f7b57912dc53f0607dc8834d3380c6d350b04f0b
7
+ data.tar.gz: 8dfaefcd7a30dfec524fac14bee7bb4612ffdf67e1e3e2f4644b77dfdd97810539a366839135a5bec1f97ab2a05eea4c6e92dd2b6a4a7a9e4d1a2e2e5959e9f0
@@ -0,0 +1,283 @@
1
+ require_relative 'helper/podfile_options'
2
+ require_relative 'helper/feature_switches'
3
+ require_relative 'helper/prebuild_sandbox'
4
+ require_relative 'helper/passer'
5
+ require_relative 'helper/names'
6
+ require_relative 'helper/target_checker'
7
+
8
+ # NOTE:
9
+ # This file will only be loaded on normal pod install step
10
+ # so there's no need to check is_prebuild_stage
11
+
12
+ # Provide a special "download" process for prebuilded pods.
13
+ #
14
+ # As the frameworks is already exsited in local folder. We
15
+ # just create a symlink to the original target folder.
16
+ #
17
+ module Pod
18
+ class Installer
19
+ class PodSourceInstaller
20
+
21
+ def install_for_prebuild!(standard_sanbox)
22
+ return if standard_sanbox.local? self.name
23
+
24
+ # make a symlink to target folder
25
+ prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sanbox)
26
+ # if spec used in multiple platforms, it may return multiple paths
27
+ target_names = prebuild_sandbox.existed_target_names_for_pod_name(self.name)
28
+
29
+ def walk(path, &action)
30
+ return unless path.exist?
31
+ path.children.each do |child|
32
+ result = action.call(child, &action)
33
+ if child.directory?
34
+ walk(child, &action) if result
35
+ end
36
+ end
37
+ end
38
+
39
+ def make_link(source, target)
40
+ source = Pathname.new(source)
41
+ target = Pathname.new(target)
42
+ target.parent.mkpath unless target.parent.exist?
43
+ relative_source = source.relative_path_from(target.parent)
44
+ FileUtils.ln_sf(relative_source, target)
45
+ end
46
+
47
+ def mirror_with_symlink(source, basefolder, target_folder)
48
+ target = target_folder + source.relative_path_from(basefolder)
49
+ make_link(source, target)
50
+ end
51
+
52
+ target_names.each do |name|
53
+
54
+ # symbol link copy all substructure
55
+ real_file_folder = prebuild_sandbox.framework_folder_path_for_target_name(name)
56
+
57
+ # If have only one platform, just place int the root folder of this pod.
58
+ # If have multiple paths, we use a sperated folder to store different
59
+ # platform frameworks. e.g. AFNetworking/AFNetworking-iOS/AFNetworking.framework
60
+
61
+ target_folder = standard_sanbox.pod_dir(self.name)
62
+ if target_names.count > 1
63
+ target_folder += real_file_folder.basename
64
+ end
65
+ target_folder.rmtree if target_folder.exist?
66
+ target_folder.mkpath
67
+
68
+ walk(real_file_folder) do |child|
69
+ source = child
70
+ # only make symlink to file and `.framework` folder
71
+ if child.directory? and [".framework", ".dSYM"].include? child.extname
72
+ mirror_with_symlink(source, real_file_folder, target_folder)
73
+ next false # return false means don't go deeper
74
+ elsif child.file?
75
+ mirror_with_symlink(source, real_file_folder, target_folder)
76
+ next true
77
+ else
78
+ next true
79
+ end
80
+ end
81
+
82
+ # symbol link copy resource for static framework
83
+ hash = Prebuild::Passer.resources_to_copy_for_static_framework || {}
84
+
85
+ path_objects = hash[name]
86
+ if path_objects != nil
87
+ path_objects.each do |object|
88
+ make_link(object.real_file_path, object.target_file_path)
89
+ end
90
+ end
91
+ end # of for each
92
+
93
+ end
94
+
95
+ # of method
96
+
97
+ end
98
+ end
99
+ end
100
+
101
+ # Let cocoapods use the prebuild framework files in install process.
102
+ #
103
+ # the code only effect the second pod install process.
104
+ #
105
+ module Pod
106
+ class Installer
107
+
108
+ # Remove the old target files if prebuild frameworks changed
109
+ # def remove_target_files_if_needed
110
+ #
111
+ # changes = Pod::Prebuild::Passer.prebuild_pods_changes
112
+ # updated_names = []
113
+ # if changes == nil
114
+ # updated_names = PrebuildSandbox.from_standard_sandbox(self.sandbox).exsited_framework_pod_names
115
+ # else
116
+ # added = changes.added
117
+ # changed = changes.changed
118
+ # deleted = changes.deleted
119
+ # updated_names = added + changed + deleted
120
+ # end
121
+ #
122
+ # updated_names.each do |name|
123
+ # root_name = Specification.root_name(name)
124
+ # next if self.sandbox.local?(root_name)
125
+ #
126
+ # # delete the cached files
127
+ # target_path = self.sandbox.pod_dir(root_name)
128
+ # target_path.rmtree if target_path.exist?
129
+ #
130
+ # support_path = sandbox.target_support_files_dir(root_name)
131
+ # support_path.rmtree if support_path.exist?
132
+ # end
133
+ #
134
+ # end
135
+
136
+ # Modify specification to use only the prebuild framework after analyzing
137
+ old_method2 = instance_method(:resolve_dependencies)
138
+ define_method(:resolve_dependencies) do
139
+
140
+ # Remove the old target files, else it will not notice file changes
141
+ # self.remove_target_files_if_needed
142
+
143
+ # call original
144
+ old_method2.bind(self).()
145
+ # ...
146
+ # ...
147
+ # ...
148
+ # after finishing the very complex orginal function
149
+
150
+ # check the pods
151
+ # Although we have did it in prebuild stage, it's not sufficient.
152
+ # Same pod may appear in another target in form of source code.
153
+ # Prebuild.check_one_pod_should_have_only_one_target(self.prebuild_pod_targets)
154
+ # self.validate_every_pod_only_have_one_form
155
+ #
156
+ #
157
+ # # prepare
158
+ # cache = []
159
+ #
160
+ # def add_vendered_framework(spec, platform, added_framework_file_path)
161
+ # if spec.attributes_hash[platform] == nil
162
+ # spec.attributes_hash[platform] = {}
163
+ # end
164
+ # vendored_frameworks = spec.attributes_hash[platform]["vendored_frameworks"] || []
165
+ # vendored_frameworks = [vendored_frameworks] if vendored_frameworks.kind_of?(String)
166
+ # vendored_frameworks += [added_framework_file_path]
167
+ # spec.attributes_hash[platform]["vendored_frameworks"] = vendored_frameworks
168
+ # end
169
+ # def empty_source_files(spec)
170
+ # spec.attributes_hash["source_files"] = []
171
+ # ["ios", "watchos", "tvos", "osx"].each do |plat|
172
+ # if spec.attributes_hash[plat] != nil
173
+ # spec.attributes_hash[plat]["source_files"] = []
174
+ # end
175
+ # end
176
+ # end
177
+ #
178
+ #
179
+ # specs = self.analysis_result.specifications
180
+ # prebuilt_specs = (specs.select do |spec|
181
+ # self.prebuild_pod_names.include? spec.root.name
182
+ # end)
183
+ #
184
+ # prebuilt_specs.each do |spec|
185
+ #
186
+ # # Use the prebuild framworks as vendered frameworks
187
+ # # get_corresponding_targets
188
+ # targets = Pod.fast_get_targets_for_pod_name(spec.root.name, self.pod_targets, cache)
189
+ # targets.each do |target|
190
+ # # the framework_file_path rule is decided when `install_for_prebuild`,
191
+ # # as to compitable with older version and be less wordy.
192
+ # framework_file_path = target.framework_name
193
+ # framework_file_path = target.name + "/" + framework_file_path if targets.count > 1
194
+ # add_vendered_framework(spec, target.platform.name.to_s, framework_file_path)
195
+ # end
196
+ # # Clean the source files
197
+ # # we just add the prebuilt framework to specific platform and set no source files
198
+ # # for all platform, so it doesn't support the sence that 'a pod perbuild for one
199
+ # # platform and not for another platform.'
200
+ # empty_source_files(spec)
201
+ #
202
+ # # to remove the resurce bundle target.
203
+ # # When specify the "resource_bundles" in podspec, xcode will generate a bundle
204
+ # # target after pod install. But the bundle have already built when the prebuit
205
+ # # phase and saved in the framework folder. We will treat it as a normal resource
206
+ # # file.
207
+ # # https://github.com/leavez/cocoapods-binary/issues/29
208
+ # if spec.attributes_hash["resource_bundles"]
209
+ # bundle_names = spec.attributes_hash["resource_bundles"].keys
210
+ # spec.attributes_hash["resource_bundles"] = nil
211
+ # spec.attributes_hash["resources"] ||= []
212
+ # spec.attributes_hash["resources"] += bundle_names.map{|n| n+".bundle"}
213
+ # end
214
+ #
215
+ # # to avoid the warning of missing license
216
+ # spec.attributes_hash["license"] = {}
217
+ #
218
+ # end
219
+
220
+ end
221
+
222
+ # Override the download step to skip download and prepare file in target folder
223
+ old_method = instance_method(:install_source_of_pod)
224
+ define_method(:install_source_of_pod) do |pod_name|
225
+
226
+ # copy from original
227
+ pod_installer = create_pod_installer(pod_name)
228
+ # \copy from original
229
+
230
+ # if self.prebuild_pod_names.include? pod_name
231
+ # pod_installer.install_for_prebuild!(self.sandbox)
232
+ # else
233
+ pod_installer.install!
234
+ # end
235
+
236
+ # copy from original
237
+ @installed_specs.concat(pod_installer.specs_by_platform.values.flatten.uniq)
238
+ # \copy from original
239
+ end
240
+
241
+ end
242
+ end
243
+
244
+ # A fix in embeded frameworks script.
245
+ #
246
+ # The framework file in pod target folder is a symblink. The EmbedFrameworksScript use `readlink`
247
+ # to read the read path. As the symlink is a relative symlink, readlink cannot handle it well. So
248
+ # we override the `readlink` to a fixed version.
249
+ #
250
+ module Pod
251
+ module Generator
252
+ class EmbedFrameworksScript
253
+
254
+ old_method = instance_method(:script)
255
+ define_method(:script) do
256
+
257
+ script = old_method.bind(self).()
258
+ patch = <<-SH.strip_heredoc
259
+ #!/bin/sh
260
+
261
+ # ---- this is added by cocoapods-binary ---
262
+ # Readlink cannot handle relative symlink well, so we override it to a new one
263
+ # If the path isn't an absolute path, we add a realtive prefix.
264
+ old_read_link=`which readlink`
265
+ readlink () {
266
+ path=`$old_read_link "$1"`;
267
+ if [ $(echo "$path" | cut -c 1-1) = '/' ]; then
268
+ echo $path;
269
+ else
270
+ echo "`dirname $1`/$path";
271
+ fi
272
+ }
273
+ # ---
274
+ SH
275
+
276
+ # patch the rsync for copy dSYM symlink
277
+ script = script.gsub "rsync --delete", "rsync --copy-links --delete"
278
+
279
+ patch + script
280
+ end
281
+ end
282
+ end
283
+ end
@@ -0,0 +1,205 @@
1
+ require 'fourflusher'
2
+ require 'xcpretty'
3
+
4
+ CONFIGURATION = "Release"
5
+ PLATFORMS = { 'iphonesimulator' => 'iOS',
6
+ 'appletvsimulator' => 'tvOS',
7
+ 'watchsimulator' => 'watchOS' }
8
+
9
+ # Build specific target to framework file
10
+ # @param [PodTarget] target
11
+ # a specific pod target
12
+ #
13
+ def build_for_iosish_platform(sandbox,
14
+ build_dir,
15
+ output_path,
16
+ target,
17
+ device,
18
+ simulator,
19
+ bitcode_enabled,
20
+ custom_build_options = [], # Array<String>
21
+ custom_build_options_simulator = [] # Array<String>
22
+ )
23
+
24
+ deployment_target = target.platform.deployment_target.to_s
25
+
26
+ target_label = target.label # name with platform if it's used in multiple platforms
27
+ Pod::UI.puts "Prebuilding-------- #{target_label}..."
28
+
29
+ other_options = []
30
+ # bitcode enabled
31
+ other_options += ['BITCODE_GENERATION_MODE=bitcode'] if bitcode_enabled
32
+ # make less arch to iphone simulator for faster build
33
+ custom_build_options_simulator += ['ARCHS=x86_64', 'ONLY_ACTIVE_ARCH=NO'] if simulator == 'iphonesimulator'
34
+
35
+ is_succeed, _ = xcodebuild(sandbox, target_label, device, deployment_target, other_options + custom_build_options)
36
+ exit 1 unless is_succeed
37
+ is_succeed, _ = xcodebuild(sandbox, target_label, simulator, deployment_target, other_options + custom_build_options_simulator)
38
+ exit 1 unless is_succeed
39
+
40
+ # paths
41
+ target_name = target.name # equals target.label, like "AFNeworking-iOS" when AFNetworking is used in multiple platforms.
42
+ module_name = target.product_module_name
43
+ device_framework_path = "#{build_dir}/#{CONFIGURATION}-#{device}/#{target_name}/#{module_name}.framework"
44
+ simulator_framework_path = "#{build_dir}/#{CONFIGURATION}-#{simulator}/#{target_name}/#{module_name}.framework"
45
+
46
+ device_binary = device_framework_path + "/#{module_name}"
47
+ simulator_binary = simulator_framework_path + "/#{module_name}"
48
+ return unless File.file?(device_binary) && File.file?(simulator_binary)
49
+
50
+ # the device_lib path is the final output file path
51
+ # combine the binaries
52
+ tmp_lipoed_binary_path = "#{build_dir}/#{target_name}"
53
+ lipo_log = `lipo -create -output #{tmp_lipoed_binary_path} #{device_binary} #{simulator_binary}`
54
+ puts lipo_log unless File.exist?(tmp_lipoed_binary_path)
55
+ FileUtils.mv tmp_lipoed_binary_path, device_binary, :force => true
56
+
57
+ # collect the swiftmodule file for various archs.
58
+ device_swiftmodule_path = device_framework_path + "/Modules/#{module_name}.swiftmodule"
59
+ simulator_swiftmodule_path = simulator_framework_path + "/Modules/#{module_name}.swiftmodule"
60
+ if File.exist?(device_swiftmodule_path)
61
+ FileUtils.cp_r simulator_swiftmodule_path + "/.", device_swiftmodule_path
62
+ end
63
+
64
+ # combine the generated swift headers
65
+ # (In xcode 10.2, the generated swift headers vary for each archs)
66
+ # https://github.com/leavez/cocoapods-binary/issues/58
67
+ simulator_generated_swift_header_path = simulator_framework_path + "/Headers/#{module_name}-Swift.h"
68
+ device_generated_swift_header_path = device_framework_path + "/Headers/#{module_name}-Swift.h"
69
+ if File.exist? simulator_generated_swift_header_path
70
+ device_header = File.read(device_generated_swift_header_path)
71
+ simulator_header = File.read(simulator_generated_swift_header_path)
72
+ # https://github.com/Carthage/Carthage/issues/2718#issuecomment-473870461
73
+ combined_header_content = %Q{
74
+ #if TARGET_OS_SIMULATOR // merged by cocoapods-binary
75
+
76
+ #{simulator_header}
77
+
78
+ #else // merged by cocoapods-binary
79
+
80
+ #{device_header}
81
+
82
+ #endif // merged by cocoapods-binary
83
+ }
84
+ File.write(device_generated_swift_header_path, combined_header_content.strip)
85
+ end
86
+
87
+ # handle the dSYM files
88
+ device_dsym = "#{device_framework_path}.dSYM"
89
+ if File.exist? device_dsym
90
+ # lipo the simulator dsym
91
+ simulator_dsym = "#{simulator_framework_path}.dSYM"
92
+ if File.exist? simulator_dsym
93
+ tmp_lipoed_binary_path = "#{output_path}/#{module_name}.draft"
94
+ lipo_log = `lipo -create -output #{tmp_lipoed_binary_path} #{device_dsym}/Contents/Resources/DWARF/#{module_name} #{simulator_dsym}/Contents/Resources/DWARF/#{module_name}`
95
+ puts lipo_log unless File.exist?(tmp_lipoed_binary_path)
96
+ FileUtils.mv tmp_lipoed_binary_path, "#{device_framework_path}.dSYM/Contents/Resources/DWARF/#{module_name}", :force => true
97
+ end
98
+ # move
99
+ FileUtils.mv device_dsym, output_path, :force => true
100
+ end
101
+
102
+ # output
103
+ output_path.mkpath unless output_path.exist?
104
+ FileUtils.mv device_framework_path, output_path, :force => true
105
+
106
+ end
107
+
108
+ def xcodebuild(sandbox, target, sdk = 'macosx', deployment_target = nil, other_options = [])
109
+ args = %W(-project #{sandbox.project_path.realdirpath} -scheme #{target} -configuration #{CONFIGURATION} -sdk #{sdk} )
110
+ platform = PLATFORMS[sdk]
111
+ args += Fourflusher::SimControl.new.destination(:oldest, platform, deployment_target) unless platform.nil?
112
+ args += other_options
113
+ log = `xcodebuild #{args.join(" ")} 2>&1`
114
+ exit_code = $?.exitstatus # Process::Status
115
+ is_succeed = (exit_code == 0)
116
+
117
+ if !is_succeed
118
+ begin
119
+ if log.include?('** BUILD FAILED **')
120
+ # use xcpretty to print build log
121
+ # 64 represent command invalid. http://www.manpagez.com/man/3/sysexits/
122
+ printer = XCPretty::Printer.new({ :formatter => XCPretty::Simple, :colorize => 'auto' })
123
+ log.each_line do |line|
124
+ printer.pretty_print(line)
125
+ end
126
+ else
127
+ raise "shouldn't be handle by xcpretty"
128
+ end
129
+ rescue
130
+ puts log.red
131
+ end
132
+ end
133
+ [is_succeed, log]
134
+ end
135
+
136
+ module Pod
137
+ class Prebuild
138
+
139
+ # Build the frameworks with sandbox and targets
140
+ #
141
+ # @param [String] sandbox_root_path
142
+ # The sandbox root path where the targets project place
143
+ #
144
+ # [PodTarget] target
145
+ # The pod targets to build
146
+ #
147
+ # [Pathname] output_path
148
+ # output path for generated frameworks
149
+ #
150
+ def self.build(sandbox_root_path, target, output_path, bitcode_enabled = false, custom_build_options = [], custom_build_options_simulator = [])
151
+
152
+ return if target.nil?
153
+
154
+ sandbox_root = Pathname(sandbox_root_path)
155
+ sandbox = Pod::Sandbox.new(sandbox_root)
156
+ build_dir = self.build_dir(sandbox_root)
157
+
158
+ # -- build the framework
159
+ case target.platform.name
160
+ when :ios then
161
+ build_for_iosish_platform(sandbox, build_dir, output_path, target, 'iphoneos', 'iphonesimulator', bitcode_enabled, custom_build_options, custom_build_options_simulator)
162
+ when :osx then
163
+ xcodebuild(sandbox, target.label, 'macosx', nil, custom_build_options)
164
+ # when :tvos then build_for_iosish_platform(sandbox, build_dir, target, 'appletvos', 'appletvsimulator')
165
+ when :watchos then
166
+ build_for_iosish_platform(sandbox, build_dir, output_path, target, 'watchos', 'watchsimulator', true, custom_build_options, custom_build_options_simulator)
167
+ else
168
+ raise "Unsupported platform for '#{target.name}': '#{target.platform.name}'"
169
+ end
170
+
171
+ raise Pod::Informative, 'The build directory was not found in the expected location.' unless build_dir.directory?
172
+
173
+ # # --- copy the vendored libraries and framework
174
+ # frameworks = build_dir.children.select{ |path| File.extname(path) == ".framework" }
175
+ # Pod::UI.puts "Built #{frameworks.count} #{'frameworks'.pluralize(frameworks.count)}"
176
+
177
+ # pod_target = target
178
+ # consumer = pod_target.root_spec.consumer(pod_target.platform.name)
179
+ # file_accessor = Pod::Sandbox::FileAccessor.new(sandbox.pod_dir(pod_target.pod_name), consumer)
180
+ # frameworks += file_accessor.vendored_libraries
181
+ # frameworks += file_accessor.vendored_frameworks
182
+
183
+ # frameworks.uniq!
184
+
185
+ # frameworks.each do |framework|
186
+ # FileUtils.mkdir_p destination
187
+ # FileUtils.cp_r framework, destination, :remove_destination => true
188
+ # end
189
+ # build_dir.rmtree if build_dir.directory?
190
+ end
191
+
192
+ def self.remove_build_dir(sandbox_root)
193
+ path = build_dir(sandbox_root)
194
+ path.rmtree if path.exist?
195
+ end
196
+
197
+ private
198
+
199
+ def self.build_dir(sandbox_root)
200
+ # don't know why xcode chose this folder
201
+ sandbox_root.parent + 'build'
202
+ end
203
+
204
+ end
205
+ end