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