pod-builder 1.9.2 → 2.0.0.beta.19

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -0
  3. data/Example/Frameworks/.gitignore +6 -0
  4. data/Example/Frameworks/.pod_builder/pod_builder +0 -0
  5. data/Example/Frameworks/PodBuilder.json +10 -4
  6. data/Example/Frameworks/Podfile +23 -0
  7. data/Example/Frameworks/Podfile.restore +40 -0
  8. data/Example/PodBuilderExample.xcodeproj/project.pbxproj +3 -8
  9. data/Example/{PodBuilderExample.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/xcschememanagement.plist → PodBuilderExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist} +2 -8
  10. data/Example/PodBuilderExample/AppDelegate.swift +4 -0
  11. data/Example/Podfile +44 -1
  12. data/Example/Podfile.lock +426 -7
  13. data/Example/Pods-acknowledgements.md +210 -0
  14. data/Example/Pods-acknowledgements.plist +206 -0
  15. data/README.md +38 -1
  16. data/exe/pod_builder +14 -14
  17. data/lib/pod_builder/analyze.rb +32 -7
  18. data/lib/pod_builder/analyzer.rb +16 -0
  19. data/lib/pod_builder/command/build.rb +110 -96
  20. data/lib/pod_builder/command/clean.rb +9 -11
  21. data/lib/pod_builder/command/clear_lldbinit.rb +1 -1
  22. data/lib/pod_builder/command/deintegrate.rb +2 -1
  23. data/lib/pod_builder/command/generate_lfs.rb +2 -2
  24. data/lib/pod_builder/command/install_sources.rb +1 -1
  25. data/lib/pod_builder/command/switch.rb +99 -99
  26. data/lib/pod_builder/command/sync_podfile.rb +2 -1
  27. data/lib/pod_builder/command/update.rb +1 -1
  28. data/lib/pod_builder/command/update_lldbinit.rb +2 -2
  29. data/lib/pod_builder/configuration.rb +62 -7
  30. data/lib/pod_builder/core.rb +60 -5
  31. data/lib/pod_builder/info.rb +24 -90
  32. data/lib/pod_builder/install.rb +149 -83
  33. data/lib/pod_builder/podfile.rb +87 -14
  34. data/lib/pod_builder/podfile/post_actions.rb +0 -1
  35. data/lib/pod_builder/podfile_item.rb +152 -74
  36. data/lib/pod_builder/podspec.rb +125 -133
  37. data/lib/pod_builder/rome/post_install.rb +248 -0
  38. data/lib/pod_builder/rome/pre_install.rb +6 -0
  39. data/lib/pod_builder/templates/build_podfile.template +1 -1
  40. data/lib/pod_builder/version.rb +1 -1
  41. data/pod-builder.gemspec +4 -4
  42. metadata +32 -64
  43. data/Example/Pods/Alamofire/LICENSE +0 -19
  44. data/Example/Pods/Alamofire/README.md +0 -242
  45. data/Example/Pods/Alamofire/Source/AFError.swift +0 -460
  46. data/Example/Pods/Alamofire/Source/Alamofire.swift +0 -465
  47. data/Example/Pods/Alamofire/Source/DispatchQueue+Alamofire.swift +0 -37
  48. data/Example/Pods/Alamofire/Source/MultipartFormData.swift +0 -580
  49. data/Example/Pods/Alamofire/Source/NetworkReachabilityManager.swift +0 -233
  50. data/Example/Pods/Alamofire/Source/Notifications.swift +0 -55
  51. data/Example/Pods/Alamofire/Source/ParameterEncoding.swift +0 -483
  52. data/Example/Pods/Alamofire/Source/Request.swift +0 -654
  53. data/Example/Pods/Alamofire/Source/Response.swift +0 -567
  54. data/Example/Pods/Alamofire/Source/ResponseSerialization.swift +0 -715
  55. data/Example/Pods/Alamofire/Source/Result.swift +0 -300
  56. data/Example/Pods/Alamofire/Source/ServerTrustPolicy.swift +0 -307
  57. data/Example/Pods/Alamofire/Source/SessionDelegate.swift +0 -725
  58. data/Example/Pods/Alamofire/Source/SessionManager.swift +0 -896
  59. data/Example/Pods/Alamofire/Source/TaskDelegate.swift +0 -466
  60. data/Example/Pods/Alamofire/Source/Timeline.swift +0 -136
  61. data/Example/Pods/Alamofire/Source/Validation.swift +0 -315
  62. data/Example/Pods/Manifest.lock +0 -16
  63. data/Example/Pods/Pods.xcodeproj/project.pbxproj +0 -673
  64. data/Example/Pods/Pods.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/Alamofire.xcscheme +0 -60
  65. data/Example/Pods/Pods.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/Pods-PodBuilderExample.xcscheme +0 -60
  66. data/Example/Pods/Pods.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/xcschememanagement.plist +0 -21
  67. data/Example/Pods/Target Support Files/Alamofire/Alamofire-dummy.m +0 -5
  68. data/Example/Pods/Target Support Files/Alamofire/Alamofire-prefix.pch +0 -12
  69. data/Example/Pods/Target Support Files/Alamofire/Alamofire-umbrella.h +0 -16
  70. data/Example/Pods/Target Support Files/Alamofire/Alamofire.modulemap +0 -6
  71. data/Example/Pods/Target Support Files/Alamofire/Alamofire.xcconfig +0 -9
  72. data/Example/Pods/Target Support Files/Alamofire/Info.plist +0 -26
  73. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Info.plist +0 -26
  74. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-acknowledgements.markdown +0 -26
  75. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-acknowledgements.plist +0 -58
  76. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-dummy.m +0 -5
  77. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-frameworks.sh +0 -153
  78. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-resources.sh +0 -118
  79. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-umbrella.h +0 -16
  80. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample.debug.xcconfig +0 -11
  81. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample.modulemap +0 -6
  82. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample.release.xcconfig +0 -11
  83. data/lib/pod_builder/cocoapods/specification.rb +0 -27
@@ -1,38 +1,5 @@
1
1
  module PodBuilder
2
2
  class Podspec
3
- class PodspecItem
4
- attr_accessor :name
5
- attr_accessor :module_name
6
- attr_accessor :vendored_frameworks
7
- attr_accessor :vendored_items
8
- attr_accessor :frameworks
9
- attr_accessor :weak_frameworks
10
- attr_accessor :libraries
11
- attr_accessor :resources
12
- attr_accessor :exclude_files
13
- attr_accessor :xcconfig
14
- attr_accessor :dependencies
15
-
16
- def initialize
17
- @name = ""
18
- @module_name = ""
19
- @vendored_frameworks = []
20
- @vendored_items = []
21
- @frameworks = []
22
- @weak_frameworks = []
23
- @libraries = []
24
- @resources = []
25
- @exclude_files = []
26
- @xcconfig = {}
27
- @dependencies = []
28
- end
29
-
30
- def to_s
31
- @name
32
- end
33
- end
34
- private_constant :PodspecItem
35
-
36
3
  def self.generate(all_buildable_items, analyzer)
37
4
  unless all_buildable_items.count > 0
38
5
  return
@@ -40,142 +7,167 @@ module PodBuilder
40
7
 
41
8
  puts "Generating PodBuilder's local podspec".yellow
42
9
 
43
- podspec_items = podspec_items_from(all_buildable_items)
44
-
45
10
  platform = analyzer.instance_variable_get("@result").targets.first.platform
46
- generate_podspec_from(podspec_items, platform)
11
+ generate_podspec_from(all_buildable_items, platform)
47
12
  end
48
13
 
49
14
  def self.include?(pod_name)
50
- podspec_path = PodBuilder::basepath("PodBuilder.podspec")
51
- unless File.exist?(podspec_path)
52
- return false
53
- end
54
-
55
- if Configuration.subspecs_to_split.include?(pod_name)
56
- pod_name = pod_name.gsub("/", "_")
57
- else
58
- pod_name = pod_name.split("/").first
59
- end
60
-
61
- podspec_content = File.read(podspec_path)
62
-
63
- # (_.*) will include prebuild podnames like s.subspec 'Podname_Subspec' do |p|
64
- subspec_regex = "s.subspec '#{pod_name}(_.*)?' do |p|"
65
- return (podspec_content.match(/#{subspec_regex}/) != nil)
15
+ return File.exist?(PodBuilder::prebuiltpath("#{pod_name}.podspec"))
66
16
  end
67
17
 
68
18
  private
69
19
 
70
- def self.generate_podspec_from(podspec_items, platform)
71
- podspecs = []
72
- podspec_items.each do |item|
73
- vendored_frameworks = item.vendored_frameworks.map { |x| x.vendored_framework_path }.compact
74
- vendored_frameworks += item.vendored_items.map { |x| File.basename(x) }.select { |x| File.exist?(PodBuilder::basepath(PodfileItem::vendored_name_framework_path(x))) }.map { |x| "Rome/#{x}" }
75
- vendored_frameworks.uniq!
76
- vendored_libraries = Dir.glob(PodBuilder::basepath("Rome/#{item.module_name}/**/*.a")).map { |x| x.to_s.gsub(PodBuilder::basepath, "")[1..-1] }
20
+ def self.generate_spec_keys_for(item, name, all_buildable_items)
21
+ podspec = ""
22
+ valid = false
77
23
 
78
- non_prebuilt_dependencies = item.dependencies.select { |x| x.vendored_framework_path.nil? }
79
-
80
- podspec = " s.subspec '#{item.name.gsub("/", "_")}' do |p|\n"
24
+ slash_count = name.count("/") + 1
25
+ indentation = " " * slash_count
26
+ spec_var = "p#{slash_count}"
81
27
 
28
+ if item.name == name
29
+ vendored_frameworks = item.vendored_frameworks + ["#{item.module_name}.framework"]
30
+ existing_vendored_frameworks = vendored_frameworks.select { |t| File.exist?(PodBuilder::prebuiltpath(t) || "") }
31
+ existing_vendored_frameworks_basename = vendored_frameworks.map { |t| File.basename(t) }.select { |t| File.exist?(PodBuilder::prebuiltpath(t) || "") }
32
+ vendored_frameworks = (existing_vendored_frameworks + existing_vendored_frameworks_basename).uniq
33
+
34
+ vendored_libraries = item.vendored_libraries
35
+ existing_vendored_libraries = vendored_libraries.map { |t| "#{item.module_name}/#{t}" }.select { |t| File.exist?(PodBuilder::prebuiltpath(t) || "") }
36
+ existing_vendored_libraries_basename = vendored_libraries.map { |t| File.basename("#{item.module_name}/#{t}") }.select { |t| File.exist?(PodBuilder::prebuiltpath(t) || "") }
37
+ vendored_libraries = (existing_vendored_libraries + existing_vendored_libraries_basename).uniq
38
+
39
+ # .a are static libraries and should not be included again in the podspec to prevent duplicated symbols (in the app and in the prebuilt framework)
40
+ vendored_libraries.select! { |t| !t.end_with?(".a") }
41
+
42
+ frameworks = all_buildable_items.select { |t| vendored_frameworks.include?("#{t.module_name}.framework") }.uniq
43
+ static_frameworks = frameworks.select { |x| x.is_static }
44
+
45
+ resources = static_frameworks.map { |x| x.vendored_framework_path.nil? ? nil : "#{x.vendored_framework_path}/*.{nib,bundle,xcasset,strings,png,jpg,tif,tiff,otf,ttf,ttc,plist,json,caf,wav,p12,momd}" }.compact.flatten.uniq
46
+ exclude_files = static_frameworks.map { |x| x.vendored_framework_path.nil? ? nil : "#{x.vendored_framework_path}/Info.plist" }.compact.flatten.uniq
47
+ exclude_files += frameworks.map { |x| x.vendored_framework_path.nil? ? nil : "#{x.vendored_framework_path}/#{Configuration.framework_plist_filename}" }.compact.flatten.uniq.sort
48
+
82
49
  if vendored_frameworks.count > 0
83
- podspec += " p.vendored_frameworks = '#{vendored_frameworks.join("','")}'\n"
84
- end
50
+ podspec += "#{indentation}#{spec_var}.vendored_frameworks = '#{vendored_frameworks.uniq.sort.join("','")}'\n"
51
+ end
85
52
  if vendored_libraries.count > 0
86
- podspec += " p.vendored_libraries = '#{vendored_libraries.join("','")}'\n"
53
+ podspec += "#{indentation}#{spec_var}.vendored_libraries = '#{vendored_libraries.uniq.sort.join("','")}'\n"
87
54
  end
88
55
  if item.frameworks.count > 0
89
- podspec += " p.frameworks = '#{item.frameworks.join("', '")}'\n"
56
+ podspec += "#{indentation}#{spec_var}.frameworks = '#{item.frameworks.uniq.sort.join("', '")}'\n"
90
57
  end
91
58
  if item.libraries.count > 0
92
- podspec += " p.libraries = '#{item.libraries.join("', '")}'\n"
59
+ podspec += "#{indentation}#{spec_var}.libraries = '#{item.libraries.uniq.sort.join("', '")}'\n"
93
60
  end
94
- if item.resources.count > 0
95
- podspec += " p.resources = '#{item.resources.join("', '")}'\n"
61
+ if resources.count > 0
62
+ podspec += "#{indentation}#{spec_var}.resources = '#{resources.uniq.sort.join("', '")}'\n"
96
63
  end
97
- if item.resources.count > 0
98
- podspec += " p.exclude_files = '#{item.exclude_files.join("', '")}'\n"
64
+ if exclude_files.count > 0
65
+ podspec += "#{indentation}#{spec_var}.exclude_files = '#{exclude_files.uniq.sort.join("', '")}'\n"
99
66
  end
100
67
  if item.xcconfig.keys.count > 0
101
- podspec += " p.xcconfig = #{item.xcconfig.to_s}\n"
102
- end
103
- non_prebuilt_dependencies.each do |non_prebuilt_dependency|
104
- podspec += " p.dependency '#{non_prebuilt_dependency.name}'\n"
105
- end
106
-
107
- podspec += " end"
108
-
109
- podspecs.push(podspec)
110
- end
111
-
112
- cwd = File.dirname(File.expand_path(__FILE__))
113
- podspec_file = File.read("#{cwd}/templates/build_podspec.template")
114
- podspec_file.gsub!("%%%podspecs%%%", podspecs.join("\n\n"))
115
-
116
- podspec_file.sub!("%%%platform_name%%%", platform.name.to_s)
117
- podspec_file.sub!("%%%deployment_version%%%", platform.deployment_target.version)
118
-
119
- File.write(PodBuilder::basepath("PodBuilder.podspec"), podspec_file)
120
- end
121
-
122
- def self.podspec_items_from(buildable_items)
123
- podspec_items = []
124
-
125
- buildable_items.each do |pod|
126
- spec_exists = File.exist?(PodBuilder::basepath(pod.vendored_spec_framework_path))
127
- subspec_exists = File.exist?(PodBuilder::basepath(pod.vendored_subspec_framework_path))
128
-
129
- unless spec_exists || subspec_exists
130
- puts "Skipping `#{pod.name}`, not prebuilt".blue
131
- next
132
- end
133
-
134
- pod_name = Configuration.subspecs_to_split.include?(pod.name) ? pod.name : pod.root_name
135
- unless podspec_item = podspec_items.detect { |x| x.name == pod_name }
136
- podspec_item = PodspecItem.new
137
- podspec_items.push(podspec_item)
138
- podspec_item.name = pod_name
139
- podspec_item.module_name = pod.module_name
140
- podspec_item.vendored_items = pod.vendored_items
141
- end
142
-
143
- podspec_item.vendored_frameworks += [pod] + pod.dependencies(buildable_items)
144
-
145
- podspec_item.frameworks = podspec_item.vendored_frameworks.map { |x| x.frameworks }.flatten.uniq.sort
146
- podspec_item.weak_frameworks = podspec_item.vendored_frameworks.map { |x| x.weak_frameworks }.flatten.uniq.sort
147
- podspec_item.libraries = podspec_item.vendored_frameworks.map { |x| x.libraries }.flatten.uniq.sort
148
-
149
- static_vendored_frameworks = podspec_item.vendored_frameworks.select { |x| x.is_static }
150
-
151
- podspec_item.resources = static_vendored_frameworks.map { |x| x.vendored_framework_path.nil? ? nil : "#{x.vendored_framework_path}/*.{nib,bundle,xcasset,strings,png,jpg,tif,tiff,otf,ttf,ttc,plist,json,caf,wav,p12,momd}" }.compact.flatten.uniq
152
- podspec_item.exclude_files = static_vendored_frameworks.map { |x| x.vendored_framework_path.nil? ? nil : "#{x.vendored_framework_path}/Info.plist" }.compact.flatten.uniq
153
- podspec_item.exclude_files += podspec_item.vendored_frameworks.map { |x| x.vendored_framework_path.nil? ? nil : "#{x.vendored_framework_path}/#{Configuration.framework_plist_filename}" }.compact.flatten.uniq.sort
154
-
155
- # Merge xcconfigs
156
- if !pod.xcconfig.empty?
157
- pod.xcconfig.each do |k, v|
68
+ xcconfig = Hash.new
69
+ item.xcconfig.each do |k, v|
158
70
  unless v != "$(inherited)"
71
+ xcconfig[k] = item.xcconfig[k]
159
72
  next
160
73
  end
161
74
  unless k == "OTHER_LDFLAGS"
162
75
  next # For the time being limit to OTHER_LDFLAGS key
163
76
  end
164
-
165
- if podspec_values = podspec_item.xcconfig[k]
77
+
78
+ if podspec_values = item.xcconfig[k]
166
79
  podspec_values_arr = podspec_values.split(" ")
167
80
  podspec_values_arr.push(v)
168
81
  v = podspec_values_arr.join(" ")
169
82
  end
170
83
 
171
- podspec_item.xcconfig[k] = v
84
+ xcconfig[k] = item.xcconfig[k]
85
+ end
86
+
87
+ if xcconfig.keys.count > 0
88
+ podspec += "#{indentation}#{spec_var}.xcconfig = #{xcconfig.to_s}\n"
89
+ end
90
+ end
91
+
92
+ deps = item.dependency_names.sort
93
+ if name == item.root_name
94
+ deps.reject! { |t| t.split("/").first == item.root_name }
95
+ end
96
+
97
+ if deps.count > 0
98
+ if podspec.count("\n") > 1
99
+ podspec += "\n"
100
+ end
101
+ deps.each do |dependency|
102
+ podspec += "#{indentation}#{spec_var}.dependency '#{dependency}'\n"
172
103
  end
173
104
  end
174
105
 
175
- podspec_item.dependencies = buildable_items.select { |x| pod.dependency_names.include?(x.name) }
106
+ valid = valid || vendored_frameworks.count > 0
176
107
  end
108
+
109
+ subspec_names = all_buildable_items.map(&:name).select { |t| t.start_with?("#{name}/") }
110
+ subspec_names_groups = subspec_names.group_by { |t| name + "/" + t.gsub("#{name}/", '').split("/").first }
111
+ subspec_names = subspec_names_groups.keys.uniq.sort
112
+
113
+ subspec_names.each do |subspec|
114
+ subspec_item = all_buildable_items.detect { |t| t.name == subspec } || item
177
115
 
178
- return podspec_items
116
+ if podspec.length > 0
117
+ podspec += "\n"
118
+ end
119
+
120
+ subspec_keys, subspec_valid = generate_spec_keys_for(subspec_item, subspec, all_buildable_items)
121
+ valid = valid || subspec_valid
122
+
123
+ if subspec_keys.length > 0
124
+ podspec += "#{indentation}#{spec_var}.subspec '#{subspec.split("/").last}' do |p#{slash_count + 1}|\n"
125
+ podspec += subspec_keys
126
+ podspec += "#{indentation}end\n"
127
+ end
128
+ end
129
+
130
+ return podspec, valid
131
+ end
132
+
133
+ def self.generate_podspec_from(all_buildable_items, platform)
134
+ specs = Dir.glob(PodBuilder::prebuiltpath("*.podspec"))
135
+ specs.each do |s|
136
+ FileUtils.rm(s)
137
+ end
138
+
139
+ all_buildable_items.each do |item|
140
+ if item.name != item.root_name
141
+ if all_buildable_items.map(&:name).include?(item.root_name)
142
+ next # will process root spec, skip subspecs
143
+ end
144
+ end
145
+
146
+ podspec = "Pod::Spec.new do |p1|\n"
147
+
148
+ podspec += " p1.name = '#{item.root_name}'\n"
149
+ podspec += " p1.version = '#{item.version}'\n"
150
+ podspec += " p1.summary = '#{item.summary.gsub("'", "\\'")}'\n"
151
+ podspec += " p1.homepage = '#{item.homepage}'\n"
152
+ podspec += " p1.author = 'PodBuilder'\n"
153
+ podspec += " p1.source = { 'git' => '#{item.source['git']}'}\n"
154
+ podspec += " p1.license = { :type => '#{item.license}' }\n"
155
+
156
+ podspec += "\n"
157
+ podspec += " p1.#{platform.safe_string_name.downcase}.deployment_target = '#{platform.deployment_target.version}'\n"
158
+ podspec += "\n"
159
+
160
+ main_keys, valid = generate_spec_keys_for(item, item.root_name, all_buildable_items)
161
+ if !valid
162
+ next
163
+ end
164
+
165
+ podspec += main_keys
166
+ podspec += "end"
167
+
168
+ spec_path = PodBuilder::prebuiltpath("#{item.root_name}.podspec")
169
+ File.write(spec_path, podspec)
170
+ end
179
171
  end
180
172
  end
181
173
  end
@@ -0,0 +1,248 @@
1
+ require 'fourflusher'
2
+ require 'colored'
3
+
4
+ module PodBuilder
5
+ def self.build_for_iosish_platform(sandbox, build_dir, target, device, simulator, configuration, deterministic_build, build_for_apple_silicon)
6
+ raise "Apple silicon hardware still unsupported since it requires to migrate to xcframeworks" if build_for_apple_silicon
7
+
8
+ deployment_target = target.platform_deployment_target
9
+ target_label = target.cocoapods_target_label
10
+
11
+ xcodebuild(sandbox, target_label, device, deployment_target, configuration, deterministic_build, [])
12
+ excluded_archs = build_for_apple_silicon ? [] : ["arm64"]
13
+ xcodebuild(sandbox, target_label, simulator, deployment_target, configuration, deterministic_build, excluded_archs)
14
+
15
+ spec_names = target.specs.map { |spec| [spec.root.name, spec.root.module_name] }.uniq
16
+ spec_names.each do |root_name, module_name|
17
+ executable_path = "#{build_dir}/#{root_name}"
18
+ device_lib = "#{build_dir}/#{configuration}-#{device}/#{root_name}/#{module_name}.framework/#{module_name}"
19
+ device_framework_lib = File.dirname(device_lib)
20
+ device_swift_header_path = "#{device_framework_lib}/Headers/#{module_name}-Swift.h"
21
+
22
+ simulator_lib = "#{build_dir}/#{configuration}-#{simulator}/#{root_name}/#{module_name}.framework/#{module_name}"
23
+ simulator_framework_lib = File.dirname(simulator_lib)
24
+ simulator_swift_header_path = "#{simulator_framework_lib}/Headers/#{module_name}-Swift.h"
25
+
26
+ next unless File.file?(device_lib) && File.file?(simulator_lib)
27
+
28
+ # Starting with Xcode 12b3 the simulator binary contains an arm64 slice as well which conflict with the one in the device_lib
29
+ # when creating the fat library. A naive workaround is to remove the arm64 from the simulator_lib however this is wrong because
30
+ # we might actually need to have 2 separated arm64 slices, one for simulator and one for device each built with different
31
+ # compile time directives (e.g #if targetEnvironment(simulator))
32
+ #
33
+ # For the time being we remove the arm64 slice bacause otherwise the `xcrun lipo -create -output ...` would fail.
34
+ if `xcrun lipo -info #{simulator_lib}`.include?("arm64")
35
+ `xcrun lipo -remove arm64 #{simulator_lib} -o #{simulator_lib}`
36
+ end
37
+
38
+ lipo_log = `xcrun lipo -create -output #{executable_path} #{device_lib} #{simulator_lib}`
39
+ puts lipo_log unless File.exist?(executable_path)
40
+
41
+ # Merge swift headers as per Xcode 10.2 release notes
42
+ if File.exist?(device_swift_header_path) && File.exist?(simulator_swift_header_path)
43
+ device_content = File.read(device_swift_header_path)
44
+ simulator_content = File.read(simulator_swift_header_path)
45
+ merged_content = %{
46
+ #if TARGET_OS_SIMULATOR
47
+ #{simulator_content}
48
+ #else
49
+ #{device_content}
50
+ #endif
51
+ }
52
+ File.write(device_swift_header_path, merged_content)
53
+ end
54
+
55
+ FileUtils.mv executable_path, device_lib, :force => true
56
+ FileUtils.mv device_framework_lib, build_dir, :force => true
57
+ FileUtils.rm simulator_lib if File.file?(simulator_lib)
58
+ FileUtils.rm device_lib if File.file?(device_lib)
59
+ end
60
+ end
61
+
62
+ def self.xcodebuild(sandbox, target, sdk='macosx', deployment_target=nil, configuration, deterministic_build, exclude_archs)
63
+ args = %W(-project #{sandbox.project_path.realdirpath} -scheme #{target} -configuration #{configuration} -sdk #{sdk})
64
+ supported_platforms = { 'iphonesimulator' => 'iOS', 'appletvsimulator' => 'tvOS', 'watchsimulator' => 'watchOS' }
65
+ if platform = supported_platforms[sdk]
66
+ args += Fourflusher::SimControl.new.destination(:oldest, platform, deployment_target) unless platform.nil?
67
+ end
68
+
69
+ xcodebuild_version = `xcodebuild -version | head -n1 | awk '{print $2}'`.strip().to_f
70
+ if exclude_archs.count > 0 && xcodebuild_version >= 12.0
71
+ args += ["EXCLUDED_ARCHS=#{exclude_archs.join(" ")}"]
72
+ end
73
+
74
+ environmental_variables = {}
75
+ if deterministic_build
76
+ environmental_variables["ZERO_AR_DATE"] = "1"
77
+ end
78
+
79
+ execute_command 'xcodebuild', args, true, environmental_variables
80
+ end
81
+
82
+ # Copy paste implementation from CocoaPods internals to be able to call poopen3 passing environmental variables
83
+ def self.execute_command(executable, command, raise_on_failure = true, environmental_variables = {})
84
+ bin = Pod::Executable.which!(executable)
85
+
86
+ command = command.map(&:to_s)
87
+ full_command = "#{bin} #{command.join(' ')}"
88
+
89
+ stdout = Pod::Executable::Indenter.new
90
+ stderr = Pod::Executable::Indenter.new
91
+
92
+ status = popen3(bin, command, stdout, stderr, environmental_variables)
93
+ stdout = stdout.join
94
+ stderr = stderr.join
95
+ output = stdout + stderr
96
+ unless status.success?
97
+ if raise_on_failure
98
+ raise "#{full_command}\n\n#{output}"
99
+ else
100
+ UI.message("[!] Failed: #{full_command}".red)
101
+ end
102
+ end
103
+
104
+ output
105
+ end
106
+
107
+ def self.popen3(bin, command, stdout, stderr, environmental_variables)
108
+ require 'open3'
109
+ Open3.popen3(environmental_variables, bin, *command) do |i, o, e, t|
110
+ Pod::Executable::reader(o, stdout)
111
+ Pod::Executable::reader(e, stderr)
112
+ i.close
113
+
114
+ status = t.value
115
+
116
+ o.flush
117
+ e.flush
118
+ sleep(0.01)
119
+
120
+ status
121
+ end
122
+ end
123
+
124
+ def self.enable_debug_information(project_path, configuration)
125
+ project = Xcodeproj::Project.open(project_path)
126
+ project.targets.each do |target|
127
+ config = target.build_configurations.find { |config| config.name.eql? configuration }
128
+ config.build_settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf-with-dsym'
129
+ config.build_settings['ONLY_ACTIVE_ARCH'] = 'NO'
130
+ end
131
+ project.save
132
+ end
133
+
134
+ def self.copy_dsym_files(dsym_destination, configuration)
135
+ dsym_destination.rmtree if dsym_destination.directory?
136
+
137
+ platforms = Configuration.supported_platforms
138
+ platforms.each do |platform|
139
+ dsym = Pathname.glob("build/#{configuration}-#{platform}/**/*.dSYM")
140
+ dsym.each do |dsym|
141
+ destination = dsym_destination + platform
142
+ FileUtils.mkdir_p destination
143
+ FileUtils.cp_r dsym, destination, :remove_destination => true
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_context, user_options|
150
+ enable_dsym = user_options.fetch('dsym', true)
151
+ configuration = user_options.fetch('configuration', 'Debug')
152
+ if user_options["pre_compile"]
153
+ user_options["pre_compile"].call(installer_context)
154
+ end
155
+
156
+ sandbox_root = Pathname(installer_context.sandbox_root)
157
+ sandbox = Pod::Sandbox.new(sandbox_root)
158
+
159
+ PodBuilder::enable_debug_information(sandbox.project_path, configuration)
160
+
161
+ build_dir = sandbox_root.parent + 'build'
162
+ destination = sandbox_root.parent + 'Rome'
163
+
164
+ build_dir.rmtree if build_dir.directory?
165
+ targets = installer_context.umbrella_targets.select { |t| t.specs.any? }
166
+ targets.each do |target|
167
+ case target.platform_name
168
+ when :ios then PodBuilder::build_for_iosish_platform(sandbox, build_dir, target, 'iphoneos', 'iphonesimulator', configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon)
169
+ when :osx then PodBuilder::xcodebuild(sandbox, target.cocoapods_target_label, configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon)
170
+ when :tvos then PodBuilder::build_for_iosish_platform(sandbox, build_dir, target, 'appletvos', 'appletvsimulator', configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon)
171
+ when :watchos then PodBuilder::build_for_iosish_platform(sandbox, build_dir, target, 'watchos', 'watchsimulator', configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon)
172
+ else raise "Unknown platform '#{target.platform_name}'" end
173
+ end
174
+
175
+ raise Pod::Informative, 'The build directory was not found in the expected location.' unless build_dir.directory?
176
+
177
+ # Make sure the device target overwrites anything in the simulator build, otherwise iTunesConnect
178
+ # can get upset about Info.plist containing references to the simulator SDK
179
+ frameworks = Pathname.glob("build/*/*/*.framework").reject { |f| f.to_s =~ /Pods[^.]+\.framework/ }
180
+ frameworks += Pathname.glob("build/*.framework").reject { |f| f.to_s =~ /Pods[^.]+\.framework/ }
181
+
182
+ resources = []
183
+
184
+ Pod::UI.puts "Built #{frameworks.count} #{'frameworks'.pluralize(frameworks.count)}"
185
+
186
+ destination.rmtree if destination.directory?
187
+
188
+ installer_context.umbrella_targets.each do |umbrella|
189
+ umbrella.specs.each do |spec|
190
+ consumer = spec.consumer(umbrella.platform_name)
191
+ file_accessor = Pod::Sandbox::FileAccessor.new(sandbox.pod_dir(spec.root.name), consumer)
192
+ frameworks += file_accessor.vendored_libraries
193
+ frameworks += file_accessor.vendored_frameworks
194
+ resources += file_accessor.resources
195
+ end
196
+ end
197
+ frameworks.uniq!
198
+ resources.uniq!
199
+
200
+ Pod::UI.puts "Copying #{frameworks.count} #{'frameworks'.pluralize(frameworks.count)} " \
201
+ "to `#{destination.relative_path_from Pathname.pwd}`"
202
+
203
+ FileUtils.mkdir_p destination
204
+ (frameworks + resources).each do |file|
205
+ FileUtils.cp_r file, destination, :remove_destination => true
206
+ end
207
+
208
+ if enable_dsym
209
+ PodBuilder::copy_dsym_files(sandbox_root.parent + 'dSYM', configuration)
210
+ else
211
+ frameworks = Dir.glob(File.join(destination, "*.framework"))
212
+
213
+ dsym_base_path = sandbox_root.parent + 'dSYM'
214
+
215
+ # manually generate dSYMs
216
+ frameworks.each do |framework|
217
+ module_name = File.basename(framework, ".*")
218
+ is_static = `file #{File.join(framework, module_name)} | grep 'ar archive' | wc -l`.strip() != "0"
219
+
220
+ if !is_static
221
+ destination_dSYM = File.join(dsym_base_path, "#{module_name}.dSYM")
222
+ FileUtils.mkdir_p(dsym_base_path)
223
+
224
+ module_path = "#{File.join(framework, module_name)}"
225
+ system("xcrun dsymutil '#{module_path}' -no-swiftmodule-timestamp -o '#{destination_dSYM}' 2>/dev/null")
226
+ if `xcrun codesign -v #{module_path} 2>&1 | grep 'code object is not signed at all' | wc -l`.strip() == "1"
227
+ system("xcrun strip -x -S '#{module_path}'")
228
+ else
229
+ # Running strip on codesigned binaries triggers the following warning:
230
+ # 'strip: changes being made to the file will invalidate the code signature in: path to binary'
231
+ puts "#{module_name} appears to be codesigned, skipping stripping.".blue
232
+ end
233
+
234
+ # Sanity check
235
+ binary_uuid = `xcrun dwarfdump --uuid '#{module_path}' | cut -d" " -f2`
236
+ dsym_uuid = `xcrun dwarfdump --uuid '#{File.join(destination_dSYM, "Contents", "Resources", "DWARF", module_name)}' | cut -d" " -f2`
237
+
238
+ raise "dSYM sanity check failed for '#{framework}', UUID do not match!" unless binary_uuid == dsym_uuid
239
+ end
240
+ end
241
+ end
242
+
243
+ build_dir.rmtree if build_dir.directory?
244
+
245
+ if user_options["post_compile"]
246
+ user_options["post_compile"].call(installer_context)
247
+ end
248
+ end