cocoapods-packager-next 2.0.0

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.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +4 -0
  4. data/.rubocop-cocoapods.yml +71 -0
  5. data/.rubocop.yml +38 -0
  6. data/.travis.yml +17 -0
  7. data/Gemfile +12 -0
  8. data/Gemfile.lock +129 -0
  9. data/LICENSE +22 -0
  10. data/README.md +39 -0
  11. data/Rakefile +29 -0
  12. data/cocoapods-packager-next.gemspec +22 -0
  13. data/lib/cocoapods-packager/builder.rb +334 -0
  14. data/lib/cocoapods-packager/framework.rb +66 -0
  15. data/lib/cocoapods-packager/mangle.rb +32 -0
  16. data/lib/cocoapods-packager/pod_utils.rb +250 -0
  17. data/lib/cocoapods-packager/spec_builder.rb +63 -0
  18. data/lib/cocoapods-packager/symbols.rb +42 -0
  19. data/lib/cocoapods-packager/user_interface/build_failed_report.rb +15 -0
  20. data/lib/cocoapods_packager.rb +5 -0
  21. data/lib/cocoapods_plugin.rb +8 -0
  22. data/lib/pod/command/package.rb +177 -0
  23. data/scripts/lstconst.sh +9 -0
  24. data/scripts/lstsym.sh +8 -0
  25. data/spec/command/error_spec.rb +81 -0
  26. data/spec/command/package_spec.rb +420 -0
  27. data/spec/command/subspecs_spec.rb +30 -0
  28. data/spec/fixtures/Archs.podspec +13 -0
  29. data/spec/fixtures/Builder.podspec +25 -0
  30. data/spec/fixtures/CPDColors.podspec +19 -0
  31. data/spec/fixtures/FH.podspec +18 -0
  32. data/spec/fixtures/KFData.podspec +73 -0
  33. data/spec/fixtures/LibraryConsumerDemo/.gitignore +22 -0
  34. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/AppDelegate.h +17 -0
  35. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/AppDelegate.m +27 -0
  36. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/Info.plist +40 -0
  37. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/main.m +16 -0
  38. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/project.pbxproj +311 -0
  39. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  40. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/xcshareddata/xcschemes/LibraryConsumer.xcscheme +100 -0
  41. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcworkspace/contents.xcworkspacedata +10 -0
  42. data/spec/fixtures/LibraryConsumerDemo/Podfile +5 -0
  43. data/spec/fixtures/LibraryDemo.podspec +14 -0
  44. data/spec/fixtures/LocalSources/LICENSE +0 -0
  45. data/spec/fixtures/LocalSources/LocalNikeKit.h +4 -0
  46. data/spec/fixtures/LocalSources/LocalNikeKit.m +9 -0
  47. data/spec/fixtures/LocalSources/LocalNikeKit.podspec +19 -0
  48. data/spec/fixtures/NikeKit.podspec +19 -0
  49. data/spec/fixtures/OpenSans.podspec +18 -0
  50. data/spec/fixtures/PackagerTest/.gitignore +21 -0
  51. data/spec/fixtures/PackagerTest/PackagerTest/CPDAppDelegate.h +15 -0
  52. data/spec/fixtures/PackagerTest/PackagerTest/CPDAppDelegate.m +49 -0
  53. data/spec/fixtures/PackagerTest/PackagerTest/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  54. data/spec/fixtures/PackagerTest/PackagerTest/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  55. data/spec/fixtures/PackagerTest/PackagerTest/PackagerTest-Info.plist +38 -0
  56. data/spec/fixtures/PackagerTest/PackagerTest/PackagerTest-Prefix.pch +16 -0
  57. data/spec/fixtures/PackagerTest/PackagerTest/en.lproj/InfoPlist.strings +2 -0
  58. data/spec/fixtures/PackagerTest/PackagerTest/main.m +18 -0
  59. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/project.pbxproj +507 -0
  60. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  61. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/xcshareddata/xcschemes/PackagerTest.xcscheme +110 -0
  62. data/spec/fixtures/PackagerTest/PackagerTest.xcworkspace/contents.xcworkspacedata +1 -0
  63. data/spec/fixtures/PackagerTest/PackagerTestTests/PackagerTestTests-Info.plist +22 -0
  64. data/spec/fixtures/PackagerTest/PackagerTestTests/PackagerTestTests.m +34 -0
  65. data/spec/fixtures/PackagerTest/PackagerTestTests/en.lproj/InfoPlist.strings +2 -0
  66. data/spec/fixtures/PackagerTest/Podfile +10 -0
  67. data/spec/fixtures/PackagerTest/Podfile.lock +36 -0
  68. data/spec/fixtures/Weakly.podspec +13 -0
  69. data/spec/fixtures/a.podspec +19 -0
  70. data/spec/fixtures/foo-bar.podspec +19 -0
  71. data/spec/fixtures/layer-client-messaging-schema.podspec +13 -0
  72. data/spec/integration/project_spec.rb +70 -0
  73. data/spec/spec_helper.rb +79 -0
  74. data/spec/unit/pod/utils_spec.rb +58 -0
  75. data/spec/unit/specification/builder_spec.rb +62 -0
  76. data/spec/unit/specification/spec_builder_spec.rb +61 -0
  77. data/spec/unit/user_interface/build_failed_report_spec.rb +11 -0
  78. metadata +223 -0
@@ -0,0 +1,334 @@
1
+ module Pod
2
+ class Builder
3
+ def initialize(platform, static_installer, source_dir, static_sandbox_root, dynamic_sandbox_root, public_headers_root, spec, embedded, mangle, dynamic, config, bundle_identifier, exclude_deps)
4
+ @platform = platform
5
+ @static_installer = static_installer
6
+ @source_dir = source_dir
7
+ @static_sandbox_root = static_sandbox_root
8
+ @dynamic_sandbox_root = dynamic_sandbox_root
9
+ @public_headers_root = public_headers_root
10
+ @spec = spec
11
+ @embedded = embedded
12
+ @mangle = mangle
13
+ @dynamic = dynamic
14
+ @config = config
15
+ @bundle_identifier = bundle_identifier
16
+ @exclude_deps = exclude_deps
17
+
18
+ @file_accessors = @static_installer.pod_targets.select { |t| t.pod_name == @spec.name }.flat_map(&:file_accessors)
19
+ end
20
+
21
+ def build(package_type)
22
+ case package_type
23
+ when :static_library
24
+ build_static_library
25
+ when :static_framework
26
+ build_static_framework
27
+ when :dynamic_framework
28
+ build_dynamic_framework
29
+ end
30
+ end
31
+
32
+ def build_static_library
33
+ UI.puts("Building static library #{@spec} with configuration #{@config}")
34
+
35
+ defines = compile
36
+ build_sim_libraries(defines)
37
+
38
+ platform_path = Pathname.new(@platform.name.to_s)
39
+ platform_path.mkdir unless platform_path.exist?
40
+
41
+ output = platform_path + "lib#{@spec.name}.a"
42
+
43
+ if @platform.name == :ios
44
+ build_static_library_for_ios(output)
45
+ else
46
+ build_static_library_for_mac(output)
47
+ end
48
+ end
49
+
50
+ def build_static_framework
51
+ UI.puts("Building static framework #{@spec} with configuration #{@config}")
52
+
53
+ defines = compile
54
+ build_sim_libraries(defines)
55
+
56
+ create_framework
57
+ output = @fwk.versions_path + Pathname.new(@spec.name)
58
+
59
+ if @platform.name == :ios
60
+ build_static_library_for_ios(output)
61
+ else
62
+ build_static_library_for_mac(output)
63
+ end
64
+
65
+ copy_headers
66
+ copy_license
67
+ copy_resources
68
+ end
69
+
70
+ def link_embedded_resources
71
+ target_path = @fwk.root_path + Pathname.new('Resources')
72
+ target_path.mkdir unless target_path.exist?
73
+
74
+ Dir.glob(@fwk.resources_path.to_s + '/*').each do |resource|
75
+ resource = Pathname.new(resource).relative_path_from(target_path)
76
+ `ln -sf #{resource} #{target_path}`
77
+ end
78
+ end
79
+
80
+ def build_dynamic_framework
81
+ UI.puts("Building dynamic framework #{@spec} with configuration #{@config}")
82
+
83
+ defines = compile
84
+ build_sim_libraries(defines)
85
+
86
+ if @bundle_identifier
87
+ defines = "#{defines} PRODUCT_BUNDLE_IDENTIFIER='#{@bundle_identifier}'"
88
+ end
89
+
90
+ output = "#{@dynamic_sandbox_root}/build/#{@spec.name}.framework/#{@spec.name}"
91
+
92
+ clean_directory_for_dynamic_build
93
+ if @platform.name == :ios
94
+ build_dynamic_framework_for_ios(defines, output)
95
+ else
96
+ build_dynamic_framework_for_mac(defines, output)
97
+ end
98
+
99
+ copy_resources
100
+ end
101
+
102
+ def build_dynamic_framework_for_ios(defines, output)
103
+ # Specify frameworks to link and search paths
104
+ linker_flags = static_linker_flags_in_sandbox
105
+ defines = "#{defines} OTHER_LDFLAGS='$(inherited) #{linker_flags.join(' ')}'"
106
+
107
+ # Build Target Dynamic Framework for both device and Simulator
108
+ device_defines = "#{defines} LIBRARY_SEARCH_PATHS=\"#{Dir.pwd}/#{@static_sandbox_root}/build\""
109
+ device_options = ios_build_options << ' -sdk iphoneos'
110
+ xcodebuild(device_defines, device_options, 'build', @spec.name.to_s, @dynamic_sandbox_root.to_s)
111
+
112
+ sim_defines = "#{defines} LIBRARY_SEARCH_PATHS=\"#{Dir.pwd}/#{@static_sandbox_root}/build-sim\" ONLY_ACTIVE_ARCH=NO"
113
+ xcodebuild(sim_defines, '-sdk iphonesimulator', 'build-sim', @spec.name.to_s, @dynamic_sandbox_root.to_s)
114
+
115
+ # Combine architectures
116
+ `lipo #{@dynamic_sandbox_root}/build/#{@spec.name}.framework/#{@spec.name} #{@dynamic_sandbox_root}/build-sim/#{@spec.name}.framework/#{@spec.name} -create -output #{output}`
117
+
118
+ FileUtils.mkdir(@platform.name.to_s)
119
+ `mv #{@dynamic_sandbox_root}/build/#{@spec.name}.framework #{@platform.name}`
120
+ `mv #{@dynamic_sandbox_root}/build/#{@spec.name}.framework.dSYM #{@platform.name}`
121
+ end
122
+
123
+ def build_dynamic_framework_for_mac(defines, _output)
124
+ # Specify frameworks to link and search paths
125
+ linker_flags = static_linker_flags_in_sandbox
126
+ defines = "#{defines} OTHER_LDFLAGS=\"#{linker_flags.join(' ')}\""
127
+
128
+ # Build Target Dynamic Framework for osx
129
+ defines = "#{defines} LIBRARY_SEARCH_PATHS=\"#{Dir.pwd}/#{@static_sandbox_root}/build\""
130
+ xcodebuild(defines, nil, 'build', @spec.name.to_s, @dynamic_sandbox_root.to_s)
131
+
132
+ FileUtils.mkdir(@platform.name.to_s)
133
+ `mv #{@dynamic_sandbox_root}/build/#{@spec.name}.framework #{@platform.name}`
134
+ `mv #{@dynamic_sandbox_root}/build/#{@spec.name}.framework.dSYM #{@platform.name}`
135
+ end
136
+
137
+ def build_sim_libraries(defines)
138
+ if @platform.name == :ios
139
+ xcodebuild(defines, '-sdk iphonesimulator', 'build-sim')
140
+ end
141
+ end
142
+
143
+ def build_static_library_for_ios(output)
144
+ static_libs = static_libs_in_sandbox('build') + static_libs_in_sandbox('build-sim') + vendored_libraries
145
+ libs = ios_architectures.map do |arch|
146
+ library = "#{@static_sandbox_root}/build/package-#{arch}.a"
147
+ `libtool -arch_only #{arch} -static -o #{library} #{static_libs.join(' ')}`
148
+ library
149
+ end
150
+
151
+ `lipo -create -output #{output} #{libs.join(' ')}`
152
+ end
153
+
154
+ def build_static_library_for_mac(output)
155
+ static_libs = static_libs_in_sandbox + vendored_libraries
156
+ `libtool -static -o #{output} #{static_libs.join(' ')}`
157
+ end
158
+
159
+ def build_with_mangling(options)
160
+ UI.puts 'Mangling symbols'
161
+ defines = Symbols.mangle_for_pod_dependencies(@spec.name, @static_sandbox_root)
162
+ defines << ' ' << @spec.consumer(@platform).compiler_flags.join(' ')
163
+
164
+ UI.puts 'Building mangled framework'
165
+ xcodebuild(defines, options)
166
+ defines
167
+ end
168
+
169
+ def clean_directory_for_dynamic_build
170
+ # Remove static headers to avoid duplicate declaration conflicts
171
+ FileUtils.rm_rf("#{@static_sandbox_root}/Headers/Public/#{@spec.name}")
172
+ FileUtils.rm_rf("#{@static_sandbox_root}/Headers/Private/#{@spec.name}")
173
+
174
+ # Equivalent to removing derrived data
175
+ FileUtils.rm_rf('Pods/build')
176
+ end
177
+
178
+ def compile
179
+ defines = "GCC_PREPROCESSOR_DEFINITIONS='$(inherited) PodsDummy_Pods_#{@spec.name}=PodsDummy_PodPackage_#{@spec.name}'"
180
+ defines << ' ' << @spec.consumer(@platform).compiler_flags.join(' ')
181
+
182
+ if @platform.name == :ios
183
+ options = ios_build_options
184
+ end
185
+
186
+ xcodebuild(defines, options)
187
+
188
+ if @mangle
189
+ return build_with_mangling(options)
190
+ end
191
+
192
+ defines
193
+ end
194
+
195
+ def copy_headers
196
+ headers_source_root = "#{@public_headers_root}/#{@spec.name}"
197
+
198
+ Dir.glob("#{headers_source_root}/**/*.h").
199
+ each { |h| `ditto #{h} #{@fwk.headers_path}/#{h.sub(headers_source_root, '')}` }
200
+
201
+ # If custom 'module_map' is specified add it to the framework distribution
202
+ # otherwise check if a header exists that is equal to 'spec.name', if so
203
+ # create a default 'module_map' one using it.
204
+ if !@spec.module_map.nil?
205
+ module_map_file = @file_accessors.flat_map(&:module_map).first
206
+ module_map = File.read(module_map_file) if Pathname(module_map_file).exist?
207
+ elsif File.exist?("#{@public_headers_root}/#{@spec.name}/#{@spec.name}.h")
208
+ module_map = <<MAP
209
+ framework module #{@spec.name} {
210
+ umbrella header "#{@spec.name}.h"
211
+
212
+ export *
213
+ module * { export * }
214
+ }
215
+ MAP
216
+ end
217
+
218
+ unless module_map.nil?
219
+ @fwk.module_map_path.mkpath unless @fwk.module_map_path.exist?
220
+ File.write("#{@fwk.module_map_path}/module.modulemap", module_map)
221
+ end
222
+ end
223
+
224
+ def copy_license
225
+ license_file = @spec.license[:file] || 'LICENSE'
226
+ license_file = Pathname.new("#{@static_sandbox_root}/#{@spec.name}/#{license_file}")
227
+ FileUtils.cp(license_file, '.') if license_file.exist?
228
+ end
229
+
230
+ def copy_resources
231
+ bundles = Dir.glob("#{@static_sandbox_root}/build/*.bundle")
232
+ if @dynamic
233
+ resources_path = "ios/#{@spec.name}.framework"
234
+ `cp -rp #{@static_sandbox_root}/build/*.bundle #{resources_path} 2>&1`
235
+ else
236
+ `cp -rp #{@static_sandbox_root}/build/*.bundle #{@fwk.resources_path} 2>&1`
237
+ resources = expand_paths(@spec.consumer(@platform).resources)
238
+ if resources.count == 0 && bundles.count == 0
239
+ @fwk.delete_resources
240
+ return
241
+ end
242
+ if resources.count > 0
243
+ `cp -rp #{resources.join(' ')} #{@fwk.resources_path}`
244
+ end
245
+ end
246
+ end
247
+
248
+ def create_framework
249
+ @fwk = Framework::Tree.new(@spec.name, @platform.name.to_s, @embedded)
250
+ @fwk.make
251
+ end
252
+
253
+ def dependency_count
254
+ count = @spec.dependencies.count
255
+
256
+ @spec.subspecs.each do |subspec|
257
+ count += subspec.dependencies.count
258
+ end
259
+
260
+ count
261
+ end
262
+
263
+ def expand_paths(path_specs)
264
+ path_specs.map do |path_spec|
265
+ Dir.glob(File.join(@source_dir, path_spec))
266
+ end
267
+ end
268
+
269
+ def static_libs_in_sandbox(build_dir = 'build')
270
+ if @exclude_deps
271
+ UI.puts 'Excluding dependencies'
272
+ Dir.glob("#{@static_sandbox_root}/#{build_dir}/lib#{@spec.name}.a")
273
+ else
274
+ Dir.glob("#{@static_sandbox_root}/#{build_dir}/lib*.a")
275
+ end
276
+ end
277
+
278
+ def vendored_libraries
279
+ if @vendored_libraries
280
+ @vendored_libraries
281
+ end
282
+ file_accessors = if @exclude_deps
283
+ @file_accessors
284
+ else
285
+ @static_installer.pod_targets.flat_map(&:file_accessors)
286
+ end
287
+ libs = file_accessors.flat_map(&:vendored_static_frameworks).map { |f| f + f.basename('.*') } || []
288
+ libs += file_accessors.flat_map(&:vendored_static_libraries)
289
+ @vendored_libraries = libs.compact.map(&:to_s)
290
+ @vendored_libraries
291
+ end
292
+
293
+ def static_linker_flags_in_sandbox
294
+ linker_flags = static_libs_in_sandbox.map do |lib|
295
+ lib.slice!('lib')
296
+ lib_flag = lib.chomp('.a').split('/').last
297
+ "-l#{lib_flag}"
298
+ end
299
+ linker_flags.reject { |e| e == "-l#{@spec.name}" || e == '-lPods-packager' }
300
+ end
301
+
302
+ def ios_build_options
303
+ "ARCHS=\'$(ARCHS_STANDARD)\' OTHER_CFLAGS=\'-fembed-bitcode -Qunused-arguments\'"
304
+ end
305
+
306
+ def ios_architectures
307
+ archs = %w(x86_64 i386 arm64 armv7 armv7s)
308
+ vendored_libraries.each do |library|
309
+ archs = `lipo -info #{library}`.split & archs
310
+ end
311
+ archs
312
+ end
313
+
314
+ def xcodebuild(defines = '', args = '', build_dir = 'build', target = 'Pods-packager', project_root = @static_sandbox_root, config = @config)
315
+ if defined?(Pod::DONT_CODESIGN)
316
+ args = "#{args} CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_REQUIRED=NO"
317
+ end
318
+
319
+ command = "xcodebuild #{defines} #{args} CONFIGURATION_BUILD_DIR=#{build_dir} clean build -configuration #{config} -target #{target} -project #{project_root}/Pods.xcodeproj 2>&1"
320
+ output = `#{command}`.lines.to_a
321
+
322
+ if $?.exitstatus != 0
323
+ puts UI::BuildFailedReport.report(command, output)
324
+
325
+ # Note: We use `Process.exit` here because it fires a `SystemExit`
326
+ # exception, which gives the caller a chance to clean up before the
327
+ # process terminates.
328
+ #
329
+ # See http://ruby-doc.org/core-1.9.3/Process.html#method-c-exit
330
+ Process.exit
331
+ end
332
+ end
333
+ end
334
+ end
@@ -0,0 +1,66 @@
1
+ module Framework
2
+ class Tree
3
+ attr_reader :headers_path
4
+ attr_reader :module_map_path
5
+ attr_reader :resources_path
6
+ attr_reader :root_path
7
+ attr_reader :versions_path
8
+
9
+ def delete_resources
10
+ Pathname.new(@resources_path).rmtree
11
+ (Pathname.new(@fwk_path) + Pathname.new('Resources')).delete
12
+ end
13
+
14
+ def initialize(name, platform, embedded)
15
+ @name = name
16
+ @platform = platform
17
+ @embedded = embedded
18
+ end
19
+
20
+ def make
21
+ make_root
22
+ make_framework
23
+ make_headers
24
+ make_resources
25
+ make_current_version
26
+ end
27
+
28
+ private
29
+
30
+ def make_current_version
31
+ current_version_path = @versions_path + Pathname.new('../Current')
32
+ `ln -sf A #{current_version_path}`
33
+ `ln -sf Versions/Current/Headers #{@fwk_path}/`
34
+ `ln -sf Versions/Current/Resources #{@fwk_path}/`
35
+ `ln -sf Versions/Current/#{@name} #{@fwk_path}/`
36
+ end
37
+
38
+ def make_framework
39
+ @fwk_path = @root_path + Pathname.new(@name + '.framework')
40
+ @fwk_path.mkdir unless @fwk_path.exist?
41
+
42
+ @module_map_path = @fwk_path + Pathname.new('Modules')
43
+ @versions_path = @fwk_path + Pathname.new('Versions/A')
44
+ end
45
+
46
+ def make_headers
47
+ @headers_path = @versions_path + Pathname.new('Headers')
48
+ @headers_path.mkpath unless @headers_path.exist?
49
+ end
50
+
51
+ def make_resources
52
+ @resources_path = @versions_path + Pathname.new('Resources')
53
+ @resources_path.mkpath unless @resources_path.exist?
54
+ end
55
+
56
+ def make_root
57
+ @root_path = Pathname.new(@platform)
58
+
59
+ if @embedded
60
+ @root_path += Pathname.new(@name + '.embeddedframework')
61
+ end
62
+
63
+ @root_path.mkpath unless @root_path.exist?
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,32 @@
1
+ module Symbols
2
+ #
3
+ # performs symbol aliasing
4
+ #
5
+ # for each dependency:
6
+ # - determine symbols for classes and global constants
7
+ # - alias each symbol to Pod#{pod_name}_#{symbol}
8
+ # - put defines into `GCC_PREPROCESSOR_DEFINITIONS` for passing to Xcode
9
+ #
10
+ def mangle_for_pod_dependencies(pod_name, sandbox_root)
11
+ pod_libs = Dir.glob("#{sandbox_root}/build/lib*.a").select do |file|
12
+ file !~ /lib#{pod_name}.a$/
13
+ end
14
+
15
+ dummy_alias = alias_symbol "PodsDummy_#{pod_name}", pod_name
16
+ all_syms = [dummy_alias]
17
+
18
+ pod_libs.each do |pod_lib|
19
+ syms = Symbols.symbols_from_library(pod_lib)
20
+ all_syms += syms.map! { |sym| alias_symbol sym, pod_name }
21
+ end
22
+
23
+ "GCC_PREPROCESSOR_DEFINITIONS='$(inherited) #{all_syms.uniq.join(' ')}'"
24
+ end
25
+
26
+ def alias_symbol(sym, pod_name)
27
+ pod_name = pod_name.tr('-', '_')
28
+ sym + "=Pod#{pod_name}_" + sym
29
+ end
30
+
31
+ module_function :mangle_for_pod_dependencies, :alias_symbol
32
+ end
@@ -0,0 +1,250 @@
1
+ module Pod
2
+ class Command
3
+ class Package < Command
4
+ private
5
+
6
+ def build_static_sandbox(dynamic)
7
+ static_sandbox_root = if dynamic
8
+ Pathname.new(config.sandbox_root + '/Static')
9
+ else
10
+ Pathname.new(config.sandbox_root)
11
+ end
12
+ Sandbox.new(static_sandbox_root)
13
+ end
14
+
15
+ def install_pod(platform_name, sandbox)
16
+ podfile = podfile_from_spec(
17
+ @path,
18
+ @spec.name,
19
+ platform_name,
20
+ @spec.deployment_target(platform_name),
21
+ @subspecs,
22
+ @spec_sources
23
+ )
24
+
25
+ static_installer = Installer.new(sandbox, podfile)
26
+ static_installer.install!
27
+
28
+ unless static_installer.nil?
29
+ static_installer.pods_project.targets.each do |target|
30
+ target.build_configurations.each do |config|
31
+ config.build_settings['CLANG_MODULES_AUTOLINK'] = 'NO'
32
+ config.build_settings['GCC_GENERATE_DEBUGGING_SYMBOLS'] = 'NO'
33
+ # 临时屏蔽模拟器arm64,后续应切换为xcframework格式以同时支持真机和模拟器arm64
34
+ config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
35
+ # 如下解决签名报错问题
36
+ config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
37
+ config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
38
+ config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
39
+ end
40
+ end
41
+ static_installer.pods_project.save
42
+ end
43
+
44
+ static_installer
45
+ end
46
+
47
+ def podfile_from_spec(path, spec_name, platform_name, deployment_target, subspecs, sources)
48
+ options = {}
49
+ if path
50
+ if @local
51
+ options[:path] = path
52
+ else
53
+ options[:podspec] = path
54
+ end
55
+ end
56
+ options[:subspecs] = subspecs if subspecs
57
+ Pod::Podfile.new do
58
+ sources.each { |s| source s }
59
+ platform(platform_name, deployment_target)
60
+ pod(spec_name, options)
61
+
62
+ install!('cocoapods',
63
+ :integrate_targets => false,
64
+ :deterministic_uuids => false)
65
+
66
+ target('packager') do
67
+ inherit! :complete
68
+ end
69
+ end
70
+ end
71
+
72
+ def binary_only?(spec)
73
+ deps = spec.dependencies.map { |dep| spec_with_name(dep.name) }
74
+ [spec, *deps].each do |specification|
75
+ %w(vendored_frameworks vendored_libraries).each do |attrib|
76
+ if specification.attributes_hash[attrib]
77
+ return true
78
+ end
79
+ end
80
+ end
81
+
82
+ false
83
+ end
84
+
85
+ def spec_with_name(name)
86
+ return if name.nil?
87
+
88
+ set = Pod::Config.instance.sources_manager.search(Dependency.new(name))
89
+ return nil if set.nil?
90
+
91
+ set.specification.root
92
+ end
93
+
94
+ def spec_with_path(path)
95
+ return if path.nil?
96
+ path = Pathname.new(path)
97
+ path = Pathname.new(Dir.pwd).join(path) unless path.absolute?
98
+ return unless path.exist?
99
+
100
+ @path = path.expand_path
101
+
102
+ if @path.directory?
103
+ help! @path + ': is a directory.'
104
+ return
105
+ end
106
+
107
+ unless ['.podspec', '.json'].include? @path.extname
108
+ help! @path + ': is not a podspec.'
109
+ return
110
+ end
111
+
112
+ Specification.from_file(@path)
113
+ end
114
+
115
+ #----------------------
116
+ # Dynamic Project Setup
117
+ #----------------------
118
+
119
+ def build_dynamic_sandbox(_static_sandbox, _static_installer)
120
+ dynamic_sandbox_root = Pathname.new(config.sandbox_root + '/Dynamic')
121
+ dynamic_sandbox = Sandbox.new(dynamic_sandbox_root)
122
+
123
+ dynamic_sandbox
124
+ end
125
+
126
+ # @param [Pod::Sandbox] dynamic_sandbox
127
+ #
128
+ # @param [Pod::Sandbox] static_sandbox
129
+ #
130
+ # @param [Pod::Installer] static_installer
131
+ #
132
+ # @param [Pod::Platform] platform
133
+ #
134
+ def install_dynamic_pod(dynamic_sandbox, static_sandbox, static_installer, platform)
135
+ # 1 Create a dynamic target for only the spec pod.
136
+ dynamic_target = build_dynamic_target(dynamic_sandbox, static_installer, platform)
137
+
138
+ # 2. Build a new xcodeproj in the dynamic_sandbox with only the spec pod as a target.
139
+ project = prepare_pods_project(dynamic_sandbox, dynamic_target.name, static_installer)
140
+
141
+ # 3. Copy the source directory for the dynamic framework from the static sandbox.
142
+ copy_dynamic_target(static_sandbox, dynamic_target, dynamic_sandbox)
143
+
144
+ # 4. Create the file references.
145
+ install_file_references(dynamic_sandbox, [dynamic_target], project)
146
+
147
+ # 5. Install the target.
148
+ install_library(dynamic_sandbox, dynamic_target, project)
149
+
150
+ # 6. Write the actual .xcodeproj to the dynamic sandbox.
151
+ write_pod_project(project, dynamic_sandbox)
152
+ end
153
+
154
+ # @param [Pod::Installer] static_installer
155
+ #
156
+ # @return [Pod::PodTarget]
157
+ #
158
+ def build_dynamic_target(dynamic_sandbox, static_installer, platform)
159
+ spec_targets = static_installer.pod_targets.select do |target|
160
+ target.name == @spec.name
161
+ end
162
+ static_target = spec_targets[0]
163
+
164
+ file_accessors = create_file_accessors(static_target, dynamic_sandbox)
165
+
166
+ archs = []
167
+ dynamic_target = Pod::PodTarget.new(dynamic_sandbox, true, static_target.user_build_configurations, archs, platform, static_target.specs, static_target.target_definitions, file_accessors)
168
+ dynamic_target
169
+ end
170
+
171
+ # @param [Pod::Sandbox] dynamic_sandbox
172
+ #
173
+ # @param [String] spec_name
174
+ #
175
+ # @param [Pod::Installer] installer
176
+ #
177
+ def prepare_pods_project(dynamic_sandbox, spec_name, installer)
178
+ # Create a new pods project
179
+ pods_project = Pod::Project.new(dynamic_sandbox.project_path)
180
+
181
+ # Update build configurations
182
+ installer.analysis_result.all_user_build_configurations.each do |name, type|
183
+ pods_project.add_build_configuration(name, type)
184
+ end
185
+
186
+ # Add the pod group for only the dynamic framework
187
+ local = dynamic_sandbox.local?(spec_name)
188
+ path = dynamic_sandbox.pod_dir(spec_name)
189
+ was_absolute = dynamic_sandbox.local_path_was_absolute?(spec_name)
190
+ pods_project.add_pod_group(spec_name, path, local, was_absolute)
191
+ pods_project
192
+ end
193
+
194
+ def copy_dynamic_target(static_sandbox, _dynamic_target, dynamic_sandbox)
195
+ command = "cp -a #{static_sandbox.root}/#{@spec.name} #{dynamic_sandbox.root}"
196
+ `#{command}`
197
+ end
198
+
199
+ def create_file_accessors(target, dynamic_sandbox)
200
+ pod_root = dynamic_sandbox.pod_dir(target.root_spec.name)
201
+
202
+ path_list = Sandbox::PathList.new(pod_root)
203
+ target.specs.map do |spec|
204
+ Sandbox::FileAccessor.new(path_list, spec.consumer(target.platform))
205
+ end
206
+ end
207
+
208
+ def install_file_references(dynamic_sandbox, pod_targets, pods_project)
209
+ installer = Pod::Installer::Xcode::PodsProjectGenerator::FileReferencesInstaller.new(dynamic_sandbox, pod_targets, pods_project)
210
+ installer.install!
211
+ end
212
+
213
+ def install_library(dynamic_sandbox, dynamic_target, project)
214
+ return if dynamic_target.target_definitions.flat_map(&:dependencies).empty?
215
+ target_installer = Pod::Installer::Xcode::PodsProjectGenerator::PodTargetInstaller.new(dynamic_sandbox, project, dynamic_target)
216
+ result = target_installer.install!
217
+ native_target = result.native_target
218
+
219
+ # Installs System Frameworks
220
+ if dynamic_target.should_build?
221
+ dynamic_target.file_accessors.each do |file_accessor|
222
+ file_accessor.spec_consumer.frameworks.each do |framework|
223
+ native_target.add_system_framework(framework)
224
+ end
225
+ file_accessor.spec_consumer.libraries.each do |library|
226
+ native_target.add_system_library(library)
227
+ end
228
+ end
229
+ end
230
+ end
231
+
232
+ def write_pod_project(dynamic_project, dynamic_sandbox)
233
+ UI.message "- Writing Xcode project file to #{UI.path dynamic_sandbox.project_path}" do
234
+ dynamic_project.pods.remove_from_project if dynamic_project.pods.empty?
235
+ dynamic_project.development_pods.remove_from_project if dynamic_project.development_pods.empty?
236
+ dynamic_project.sort(:groups_position => :below)
237
+ dynamic_project.recreate_user_schemes(false)
238
+
239
+ # Edit search paths so that we can find our dependency headers
240
+ dynamic_project.targets.first.build_configuration_list.build_configurations.each do |config|
241
+ config.build_settings['HEADER_SEARCH_PATHS'] = "$(inherited) #{Dir.pwd}/Pods/Static/Headers/**"
242
+ config.build_settings['USER_HEADER_SEARCH_PATHS'] = "$(inherited) #{Dir.pwd}/Pods/Static/Headers/**"
243
+ config.build_settings['OTHER_LDFLAGS'] = '$(inherited) -ObjC'
244
+ end
245
+ dynamic_project.save
246
+ end
247
+ end
248
+ end
249
+ end
250
+ end