pod-builder 2.2.1 → 3.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3d87c061e79af94ca1274b3d60765a3ba850c8a0d2b443fbd810dbb0585d0e0
4
- data.tar.gz: d2db90c765d618eada490386fa07ffe412d69afefae36aef4f0a183e43019d71
3
+ metadata.gz: '09cbb24dc2fb49946058f0459990c762afd54e93dfe280289203348162272611'
4
+ data.tar.gz: 87fc03146c5a8a7fbe2adcc895e8a45c8b24b517b00c557236245902df543267
5
5
  SHA512:
6
- metadata.gz: 5a6664929a3eb5d564fe8e83345bddf9a746abda7c88adc8600e2fece2b4d3b9ce22d864ae4d363bd0e5fd5fa80bb0b083cbb648ec2cdb04c3f0c01c72a237aa
7
- data.tar.gz: ff51be1741b388ba51cbb494203d5c1d6c9f593926ab1b5d0a86940f271dab9423c5f43b7866668007d7393a2d44c94a671205a1a61bfc5dfee2fa06b0b3a04f
6
+ metadata.gz: 221ccda81fbd9b41d4439ebaa6a8ea3776e4c1d91ea3b24d268fa54203e67e757160ad0e42595527e0e610845ec1faf546aa9d480463f808aae28c94df4710e4
7
+ data.tar.gz: ef65cce139a54a6ae93e5262e480a3608e9b268a51cf413da58e314d29568c6981f5b198dc1061d93d102ec112935dc890d7e5b009fabd0cc4cc88cce52e9650
data/README.md CHANGED
@@ -216,7 +216,7 @@ As an example here we're setting `module_name` in Google's Advertising SDK:
216
216
  }
217
217
  ```
218
218
 
219
- ### `skip_pods`
219
+ #### `skip_pods`
220
220
 
221
221
  You may want to skip some pods to be prebuilt, you can do that as follows:
222
222
 
@@ -229,7 +229,7 @@ You may want to skip some pods to be prebuilt, you can do that as follows:
229
229
  ```
230
230
 
231
231
 
232
- ### `force_prebuild_pods`
232
+ #### `force_prebuild_pods`
233
233
 
234
234
  You may want to force some pods to be prebuilt, this might be the case for prebuilt ones (pods with a single vendored .framework) which are dependencies of othere pods
235
235
 
@@ -244,7 +244,9 @@ You may want to force some pods to be prebuilt, this might be the case for prebu
244
244
 
245
245
  #### `build_settings`
246
246
 
247
- Xcode build settings to use. You can override the default values which are:
247
+ These settings allow you to specify the build settings to use when compiling prebuilt items. These values won't be reflected in your project once the pod has been built.
248
+
249
+ You can override the default values which are:
248
250
 
249
251
  ```json
250
252
  {
@@ -280,9 +282,17 @@ Like `build_settings` but per pod. Pod name can also refer to subspec.
280
282
 
281
283
  Specify which build system to use to compile frameworks. Either `Legacy` (standard build system) or `Latest` (new build system). Default value: `Latest`.
282
284
 
283
- #### `build_xcframeworks`
285
+ #### `build_xcframeworks_all`
286
+
287
+ Specify if PodBuilder should build all pods as .xcframeworks. Will enable `library_evolution_support`. Default value: false
288
+
289
+ #### `build_xcframeworks_exclude`
290
+
291
+ Specify which pods PodBuilder should NOT be built as .xcframeworks when `build_xcframeworks_all` is true. Default value: []
292
+
293
+ #### `build_xcframeworks_include`
284
294
 
285
- Specify if PodBuilder will build .xcframeworks. Will enable `library_evolution_support`. Default value: false
295
+ Specify which pods PodBuilder should be built as .xcframeworks. Will enable `library_evolution_support`. Default value: []
286
296
 
287
297
  #### `library_evolution_support`
288
298
 
@@ -327,11 +337,8 @@ The podspec of the Pod you're trying to build doesn't specify the swift_version
327
337
 
328
338
  ```json
329
339
  "spec_overrides": {
330
- "Google-Mobile-Ads-SDK": {
331
- "module_name": "GoogleMobileAds"
332
- },
333
340
  "PodWithError": {
334
- "swift_version": "5.0"
341
+ "swift_version": "5.3"
335
342
  }
336
343
  }
337
344
  ```
@@ -357,7 +364,7 @@ Please open an issue here. You may also add the name of the pod to the [`skip_po
357
364
 
358
365
  # Git LFS
359
366
 
360
- We high encourage to use PodBuilder in combination with Git LFS. Tacking PodBuilder/Prebuilt/**/*.framework/* and PodBuilder/Prebuilt/**/*.a and PodBuilder/dSYM/**/* will ensure that your repo size stays under control with all the benefits of having prebuilt dependencies ready to use.
367
+ We high encourage to use PodBuilder in combination with Git LFS. Tacking `PodBuilder/Prebuilt/**/*.framework/*` and `PodBuilder/Prebuilt/**/*.a` and `PodBuilder/dSYM/**/*` will ensure that your repo size stays under control with all the benefits of having prebuilt dependencies ready to use.
361
368
 
362
369
 
363
370
  # Try it out!
data/exe/pod_builder CHANGED
@@ -76,9 +76,6 @@ Options:
76
76
  opts.on("-w", "--allow-warnings", "Allow warnings") do |o|
77
77
  OPTIONS[:allow_warnings] = o
78
78
  end
79
- opts.on("-r", "--parent-deps", "Include all pods that depend on the specified <PODNAME...>") do |o|
80
- OPTIONS[:resolve_parent_dependencies] = true
81
- end
82
79
  opts.on("-s", "--no-stdin", "Never request interaction with sdtin (e.g. in CI environment)") do |o|
83
80
  OPTIONS[:no_stdin_available] = o
84
81
  end
@@ -32,8 +32,6 @@ module PodBuilder
32
32
  argument_pods = all_buildable_items.map(&:root_name).uniq
33
33
  else
34
34
  argument_pods = Podfile::resolve_pod_names(argument_pods, all_buildable_items)
35
- deps = all_buildable_items.select { |t| argument_pods.include?(t.root_name) }.map(&:dependency_names).flatten.map { |t| t.split("/").first }
36
- argument_pods += deps
37
35
  argument_pods.uniq!
38
36
  end
39
37
 
@@ -43,8 +41,6 @@ module PodBuilder
43
41
  }
44
42
  argument_pods = available_argument_pods.uniq
45
43
 
46
- prebuilt_pods_to_install = prebuilt_items.select { |x| argument_pods.include?(x.root_name) }
47
-
48
44
  Podfile.restore_podfile_clean(all_buildable_items)
49
45
 
50
46
  restore_file_error = Podfile.restore_file_sanity_check
@@ -54,28 +50,53 @@ module PodBuilder
54
50
  pods_to_build = resolve_pods_to_build(argument_pods, buildable_items)
55
51
  buildable_items -= pods_to_build
56
52
 
57
- # We need to split pods to build in 3 groups
53
+ argument_pods += pods_to_build.map(&:root_name)
54
+ argument_pods.uniq!
55
+
56
+ # We need to split pods to build in 4 groups
58
57
  # 1. pods to build in release
59
58
  # 2. pods to build in debug
59
+ # 3. pods to build in release as xcframeworks
60
+ # 4. pods to build in debug as xcframeworks
60
61
 
61
62
  check_not_building_development_pods(pods_to_build)
62
63
 
64
+ # We need to recursively add dependencies to properly split pods in groups.
65
+ # Example:
66
+ # 1. PodA has a dep to PodB
67
+ # 2. PodB is marked to be built as xcframework
68
+ # 3. We rebuild PodA only (pods_to_build contains only PodA)
69
+ # 4. We need to add dependencies recursively so that PodB is is added to pods_to_build_release_xcframework
70
+ pods_to_build = pods_to_build.map { |t| t.recursive_dependencies(all_buildable_items) }.flatten.uniq
71
+
63
72
  pods_to_build_debug = pods_to_build.select { |x| x.build_configuration == "debug" }
64
73
  pods_to_build_release = pods_to_build - pods_to_build_debug
65
74
 
75
+ pods_to_build_debug_xcframework = pods_to_build_debug.select { |x| x.build_xcframework }
76
+ pods_to_build_debug -= pods_to_build_debug_xcframework
77
+
78
+ pods_to_build_release_xcframework = pods_to_build_release.select { |x| x.build_xcframework }
79
+ pods_to_build_release -= pods_to_build_release_xcframework
80
+
66
81
  check_dependencies_build_configurations(all_buildable_items)
67
82
 
68
- podfiles_items = [pods_to_build_debug] + [pods_to_build_release]
83
+ # When building mixed framwork/xcframeworks pods xcframeworks should be built last
84
+ # so that the .xcframework overwrite the .framwork if the same pod needs to be built
85
+ # in both ways.
86
+ # For example we might have configured to build onlt PodA as xcframework, another pod
87
+ # PodB has a dependency to PodA. When Building PodB, PodA gets rebuilt as .framework
88
+ # but then PodA gets rebuilt again as .xcframework overwriting the .framework.
89
+ podfiles_items = [pods_to_build_debug] + [pods_to_build_release] + [pods_to_build_debug_xcframework] + [pods_to_build_release_xcframework]
69
90
 
70
91
  install_using_frameworks = Podfile::install_using_frameworks(analyzer)
71
92
  if Configuration.react_native_project
72
93
  if install_using_frameworks
73
- raise "\n\nOnly static library packaging currently supported for react native projects. Please remove 'use_frameworks!' in #{PodBuilder::basepath("Podfile")}".red
94
+ raise "\n\nOnly static library packaging currently supported for react native projects. Please remove 'use_frameworks!' in #{PodBuilder::basepath("Podfile")}\n".red
74
95
  end
75
96
  prepare_defines_modules_override(all_buildable_items)
76
97
  else
77
98
  unless install_using_frameworks
78
- raise "\n\nOnly framework packaging currently supported. Please add 'use_frameworks!' at root level (not nested in targets) in #{PodBuilder::basepath("Podfile")}".red
99
+ raise "\n\nOnly framework packaging currently supported. Please add 'use_frameworks!' at root level (not nested in targets) in #{PodBuilder::basepath("Podfile")}\n".red
79
100
  end
80
101
  end
81
102
 
@@ -84,11 +105,17 @@ module PodBuilder
84
105
  install_result = InstallResult.new
85
106
  podfiles_items.reject { |x| x.empty? }.each do |podfile_items|
86
107
  build_configuration = podfile_items.map(&:build_configuration).uniq.first
87
-
108
+
109
+ # We need to recursively find dependencies again because some of the required dependencies might have been moved to a separate group
110
+ # Example:
111
+ # 1. PodA has a dep to PodB
112
+ # 2. PodB is marked to be built as xcframework -> PodB will be added to pods_to_build_release_xcframework and won't be present in
113
+ # pods_to_build_release and therefore build will fail
88
114
  podfile_items = podfile_items.map { |t| t.recursive_dependencies(all_buildable_items) }.flatten.uniq
89
- podfile_content = Podfile.from_podfile_items(podfile_items, analyzer, build_configuration, install_using_frameworks, build_catalyst, Configuration.build_xcframeworks)
90
115
 
91
- install_result += Install.podfile(podfile_content, podfile_items, podfile_items.first.build_configuration)
116
+ podfile_content = Podfile.from_podfile_items(podfile_items, analyzer, build_configuration, install_using_frameworks, build_catalyst, podfile_items.first.build_xcframework)
117
+
118
+ install_result += Install.podfile(podfile_content, podfile_items, argument_pods, podfile_items.first.build_configuration)
92
119
 
93
120
  FileUtils.rm_f(PodBuilder::basepath("Podfile.lock"))
94
121
  end
@@ -106,6 +133,7 @@ module PodBuilder
106
133
  builded_pods_and_deps = podfiles_items.flatten.map { |t| t.recursive_dependencies(all_buildable_items) }.flatten.uniq
107
134
  builded_pods_and_deps.select! { |x| !x.is_prebuilt }
108
135
 
136
+ prebuilt_pods_to_install = prebuilt_items.select { |x| argument_pods.include?(x.root_name) }
109
137
  Podfile::write_restorable(builded_pods_and_deps + prebuilt_pods_to_install, all_buildable_items, analyzer)
110
138
  if !OPTIONS.has_key?(:skip_prebuild_update)
111
139
  Podfile::write_prebuilt(all_buildable_items, analyzer)
@@ -129,7 +157,7 @@ module PodBuilder
129
157
  build_settings = installer.analysis_result.targets.map { |t| t.user_project.root_object.targets.map { |u| u.build_configuration_list.build_configurations.map { |v| v.build_settings } } }.flatten
130
158
  build_catalyst = build_settings.detect { |t| t["SUPPORTS_MACCATALYST"] == "YES" } != nil
131
159
 
132
- puts "\nTo support Catalyst you should enable 'build_xcframeworks' in PodBuilder.json\n".red if build_catalyst && !Configuration.build_xcframeworks
160
+ puts "\nTo support Catalyst you should enable 'build_xcframeworks' in PodBuilder.json\n".red if build_catalyst && !Configuration.build_xcframeworks_all
133
161
 
134
162
  return build_catalyst
135
163
  end
@@ -151,11 +179,11 @@ module PodBuilder
151
179
  end
152
180
 
153
181
  def self.check_pods_exists(pods, buildable_items)
154
- raise "\n\nEmpty Podfile?".red if buildable_items.nil?
182
+ raise "\n\nEmpty Podfile?\n".red if buildable_items.nil?
155
183
 
156
184
  buildable_items = buildable_items.map(&:root_name)
157
185
  pods.each do |pod|
158
- raise "\n\nPod `#{pod}` wasn't found in Podfile.\n\nFound:\n#{buildable_items.join("\n")}\n\n".red if !buildable_items.include?(pod)
186
+ raise "\n\nPod `#{pod}` wasn't found in Podfile.\n\nFound:\n#{buildable_items.join("\n")}\n".red if !buildable_items.include?(pod)
159
187
  end
160
188
  end
161
189
 
@@ -169,7 +197,7 @@ module PodBuilder
169
197
  pods_with_unaligned_build_configuration = pods_with_common_deps.select { |x| x.build_configuration != pod.build_configuration }
170
198
  pods_with_unaligned_build_configuration.map!(&:name)
171
199
 
172
- raise "\n\nDependencies of `#{pod.name}` don't have the same build configuration (#{pod.build_configuration}) of `#{pods_with_unaligned_build_configuration.join(",")}`'s dependencies".red if pods_with_unaligned_build_configuration.count > 0
200
+ raise "\n\nDependencies of `#{pod.name}` don't have the same build configuration (#{pod.build_configuration}) of `#{pods_with_unaligned_build_configuration.join(",")}`'s dependencies\n".red if pods_with_unaligned_build_configuration.count > 0
173
201
  end
174
202
  end
175
203
 
@@ -200,7 +228,7 @@ module PodBuilder
200
228
  if OPTIONS[:allow_warnings]
201
229
  puts "\n\n#{warn_message}".yellow
202
230
  else
203
- raise "\n\n#{warn_message}".red
231
+ raise "\n\n#{warn_message}\n".red
204
232
  end
205
233
  end
206
234
  end
@@ -211,15 +239,17 @@ module PodBuilder
211
239
  pods_to_build = buildable_items.select { |x| argument_pods.include?(x.root_name) }
212
240
  pods_to_build += other_subspecs(pods_to_build, buildable_items)
213
241
 
214
- if OPTIONS[:resolve_parent_dependencies]
215
- dependencies = []
216
- buildable_items.each do |pod|
217
- if !(pod.dependencies(buildable_items) & pods_to_build).empty?
218
- dependencies.push(pod)
219
- end
242
+ # Build all pods that depend on the those that were explictly passed by the user
243
+ dependencies = []
244
+ buildable_items.each do |pod|
245
+ if !(pod.dependencies(buildable_items) & pods_to_build).empty?
246
+ dependencies.push(pod)
220
247
  end
221
- pods_to_build += dependencies
222
248
  end
249
+ log = dependencies.reject { |t| pods_to_build.map(&:root_name).include?(t.root_name) }.map(&:root_name)
250
+ puts "Adding inverse dependencies: #{log.join(", ")}".blue
251
+
252
+ pods_to_build += dependencies
223
253
 
224
254
  return pods_to_build.uniq
225
255
  end
@@ -19,7 +19,7 @@ module PodBuilder
19
19
  end
20
20
  source_path = File.expand_path(source_path)
21
21
 
22
- raise "\n\nSpecified path does not exists" unless File.directory?(source_path)
22
+ raise "\n\nSpecified path does not exists\n".red unless File.directory?(source_path)
23
23
  end
24
24
 
25
25
  base_path = PodBuilder::basepath
@@ -122,11 +122,11 @@ module PodBuilder
122
122
  # React-Core.podspec
123
123
  file = "React-Core.podspec"
124
124
  paths = Dir.glob("#{PodBuilder::git_rootpath}/node_modules/**/#{file}")
125
- raise "Unexpected number of #{file} found" if paths.count != 1
125
+ raise "\n\nUnexpected number of #{file} found\n".red if paths.count != 1
126
126
 
127
127
  content = File.read(paths[0])
128
128
  expected_header_search_path_prefix = "s.pod_target_xcconfig = { \"HEADER_SEARCH_PATHS\" => \""
129
- raise "Expected header search path entry not found" unless content.include?(expected_header_search_path_prefix)
129
+ raise "\n\nExpected header search path entry not found\n".red unless content.include?(expected_header_search_path_prefix)
130
130
 
131
131
  content.sub!(expected_header_search_path_prefix, "#{expected_header_search_path_prefix}\\\"$(PODS_ROOT)/Headers/Public/Flipper-Folly\\\" ")
132
132
  File.write(paths[0], content)
@@ -134,11 +134,11 @@ module PodBuilder
134
134
  # React-CoreModules.podspec
135
135
  file = "React-CoreModules.podspec"
136
136
  paths = Dir.glob("#{PodBuilder::git_rootpath}/node_modules/**/#{file}")
137
- raise "Unexpected number of #{file} found" if paths.count != 1
137
+ raise "\n\nUnexpected number of #{file} found\n".red if paths.count != 1
138
138
 
139
139
  content = File.read(paths[0])
140
140
  expected_header_search_path_prefix = "\"HEADER_SEARCH_PATHS\" => \""
141
- raise "Expected header search path entry not found" unless content.include?(expected_header_search_path_prefix)
141
+ raise "\n\nExpected header search path entry not found\n".red unless content.include?(expected_header_search_path_prefix)
142
142
 
143
143
  content.sub!(expected_header_search_path_prefix, "#{expected_header_search_path_prefix}\\\"$(PODS_ROOT)/Headers/Public/Flipper-Folly\\\" ")
144
144
  File.write(paths[0], content)
@@ -13,19 +13,23 @@ module PodBuilder
13
13
  return -1
14
14
  end
15
15
 
16
+ pods_not_found = []
16
17
  pod_names_to_switch = []
17
18
  argument_pods.each do |pod|
18
19
  pod_name_to_switch = pod
19
20
  pod_name_to_switch = Podfile::resolve_pod_names_from_podfile([pod_name_to_switch]).first
20
- raise "\n\nDid not find pod '#{pod}'".red if pod_name_to_switch.nil?
21
-
22
- check_not_building_subspec(pod_name_to_switch)
23
21
 
24
- pod_names_to_switch.push(pod_name_to_switch)
22
+ if pod_name_to_switch.nil?
23
+ raise "\n\n'#{pod}' not found in PodBuilder's Podfile.\n\nYou might need to explictly add:\n\n pod '#{pod}'\n\nto #{PodBuilder::basepath("Podfile")}\n".red
24
+ else
25
+ check_not_building_subspec(pod_name_to_switch)
26
+
27
+ pod_names_to_switch.push(pod_name_to_switch)
28
+ end
25
29
  end
26
30
 
27
31
  if OPTIONS[:resolve_parent_dependencies] == true
28
- install_update_repo = OPTIONS.fetch(:update_repos, true)
32
+ install_update_repo = OPTIONS.fetch(:update_repos, false)
29
33
  installer, analyzer = Analyze.installer_at(PodBuilder::basepath, install_update_repo)
30
34
 
31
35
  all_buildable_items = Analyze.podfile_items(installer, analyzer)
@@ -55,7 +59,7 @@ module PodBuilder
55
59
 
56
60
  podspec_content = File.read(podspec_path)
57
61
 
58
- regex = "p\\d\\.dependency '(.*)'"
62
+ regex = "p\\d\\.dependency ['|\"](.*)['|\"]"
59
63
 
60
64
  podspec_content.each_line do |line|
61
65
  matches = line.match(/#{regex}/)
@@ -107,15 +111,15 @@ module PodBuilder
107
111
  next
108
112
  end
109
113
 
110
- matches = line.gsub("\"", "'").match(/pod '(.*?)',(.*)/)
111
- if matches&.size == 3
114
+ matches = line.gsub("\"", "'").match(/pod '(.*?)'/)
115
+ if matches&.size == 2
112
116
  if matches[1].split("/").first == pod_name_to_switch
113
117
  default_entries[current_section] = line
114
118
  end
115
119
  end
116
120
  end
117
121
 
118
- raise "\n\n'#{pod_name_to_switch}' not found in #{podfile_path}".red if default_entries.keys.count == 0
122
+ raise "\n\n'#{pod_name_to_switch}' not found in PodBuilder's Podfile.\n\nYou might need to explictly add:\n\n pod '#{pod_name_to_switch}'\n\nto #{podfile_path}\n".red if default_entries.keys.count == 0
119
123
  end
120
124
 
121
125
  if development_path.nil?
@@ -137,8 +141,8 @@ module PodBuilder
137
141
  current_section = line.split(" ")[1]
138
142
  end
139
143
 
140
- matches = line.gsub("\"", "'").match(/pod '(.*?)',(.*)/)
141
- if matches&.size == 3
144
+ matches = line.gsub("\"", "'").match(/pod '(.*?)'/)
145
+ if matches&.size == 2
142
146
  if matches[1].split("/").first == pod_name_to_switch
143
147
  case OPTIONS[:switch_mode]
144
148
  when "prebuilt"
@@ -166,6 +170,14 @@ module PodBuilder
166
170
  if line.include?("# pb<") && marker = line.split("# pb<").last
167
171
  default_line = default_line.chomp("\n") + " # pb<#{marker}"
168
172
  end
173
+ if (path_match = default_line.match(/:path => '(.*?)'/)) && path_match&.size == 2
174
+ original_path = path_match[1]
175
+ if !is_absolute_path(original_path)
176
+ updated_path = Pathname.new(PodBuilder::basepath(original_path)).relative_path_from(Pathname.new(PodBuilder::project_path)).to_s
177
+ default_line.gsub!(":path => '#{original_path}'", ":path => '#{updated_path}'")
178
+ end
179
+ end
180
+
169
181
  lines.append(default_line)
170
182
  next
171
183
  elsif
@@ -190,7 +202,11 @@ module PodBuilder
190
202
  return 0
191
203
  end
192
204
 
193
- private
205
+ private
206
+
207
+ def self.is_absolute_path(path)
208
+ return ["~", "/"].any? { |t| path.start_with?(t) }
209
+ end
194
210
 
195
211
  def self.find_podspec(podname)
196
212
  unless Configuration.development_pods_paths.count > 0
@@ -216,7 +232,7 @@ module PodBuilder
216
232
 
217
233
  def self.check_not_building_subspec(pod_to_switch)
218
234
  if pod_to_switch.include?("/")
219
- raise "\n\nCan't switch subspec #{pod_to_switch} refer to podspec name.\n\nUse `pod_builder switch #{pod_to_switch.split("/").first}` instead\n\n".red
235
+ raise "\n\nCan't switch subspec #{pod_to_switch} refer to podspec name.\n\nUse `pod_builder switch #{pod_to_switch.split("/").first}` instead\n".red
220
236
  end
221
237
  end
222
238
  end
@@ -35,7 +35,6 @@ module PodBuilder
35
35
  ARGV.clear
36
36
  pods_to_update.each { |x| ARGV << x }
37
37
 
38
- # OPTIONS[:resolve_parent_dependencies] = true
39
38
  return PodBuilder::Command::Build.call
40
39
  end
41
40
  end
@@ -39,19 +39,10 @@ module PodBuilder
39
39
  "ENABLE_BITCODE": "NO"
40
40
  }
41
41
  }.freeze
42
- DEFAULT_SKIP_PODS = ["GoogleMaps", "React-RCTFabric", "React-Core", "React-CoreModules"] # Not including React-RCTNetwork might loose some debug warnings
43
-
44
- DEFAULT_FORCE_PREBUILD_PODS = []
45
- DEFAULT_BUILD_SYSTEM = "Latest".freeze # either Latest (New build system) or Legacy (Standard build system)
46
- DEFAULT_LIBRARY_EVOLUTION_SUPPORT = false
47
- DEFAULT_PLATFORMS = ["iphoneos", "iphonesimulator", "appletvos", "appletvsimulator"].freeze
48
- DEFAULT_BUILD_USING_REPO_PATHS = false
49
- DEFAULT_BUILD_XCFRAMEWORKS = false
50
42
 
51
43
  private_constant :DEFAULT_BUILD_SETTINGS
52
44
  private_constant :DEFAULT_BUILD_SETTINGS_OVERRIDES
53
- private_constant :DEFAULT_BUILD_SYSTEM
54
- private_constant :DEFAULT_LIBRARY_EVOLUTION_SUPPORT
45
+ private_constant :DEFAULT_SPEC_OVERRIDE
55
46
 
56
47
  class <<self
57
48
  attr_accessor :allow_building_development_pods
@@ -81,19 +72,22 @@ module PodBuilder
81
72
  attr_accessor :build_using_repo_paths
82
73
  attr_accessor :react_native_project
83
74
  attr_accessor :lldbinit_name
84
- attr_accessor :build_xcframeworks
75
+ attr_accessor :build_xcframeworks_all
76
+ attr_accessor :build_xcframeworks_include
77
+ attr_accessor :build_xcframeworks_exclude
85
78
  end
86
-
87
- @allow_building_development_pods = false
79
+
88
80
  @build_settings = DEFAULT_BUILD_SETTINGS
89
81
  @build_settings_overrides = DEFAULT_BUILD_SETTINGS_OVERRIDES
90
- @build_system = DEFAULT_BUILD_SYSTEM
91
- @library_evolution_support = DEFAULT_LIBRARY_EVOLUTION_SUPPORT
92
- @base_path = "PodBuilder" # Not nice. This value is used only for initial initization. Once config is loaded it will be an absolute path. FIXME
93
82
  @spec_overrides = DEFAULT_SPEC_OVERRIDE
83
+
84
+ @allow_building_development_pods = false
85
+ @build_system = "Latest".freeze # either Latest (New build system) or Legacy (Standard build system)
86
+ @library_evolution_support = false
87
+ @base_path = "PodBuilder" # Not nice. This value is used only for initial initization. Once config is loaded it will be an absolute path. FIXME
94
88
  @skip_licenses = []
95
- @skip_pods = DEFAULT_SKIP_PODS
96
- @force_prebuild_pods = DEFAULT_FORCE_PREBUILD_PODS
89
+ @skip_pods = ["GoogleMaps", "React-RCTFabric", "React-Core", "React-CoreModules"] # Not including React-RCTNetwork might loose some debug warnings
90
+ @force_prebuild_pods = []
97
91
  @license_filename = "Pods-acknowledgements"
98
92
  @development_pods_paths = []
99
93
  @build_base_path = "/tmp/pod_builder".freeze
@@ -110,11 +104,13 @@ module PodBuilder
110
104
  @use_bundler = false
111
105
  @deterministic_build = false
112
106
 
113
- @supported_platforms = DEFAULT_PLATFORMS
114
- @build_using_repo_paths = DEFAULT_BUILD_USING_REPO_PATHS
107
+ @supported_platforms = ["iphoneos", "iphonesimulator", "appletvos", "appletvsimulator"].freeze
108
+ @build_using_repo_paths = false
115
109
  @react_native_project = false
116
110
 
117
- @build_xcframeworks = DEFAULT_BUILD_XCFRAMEWORKS
111
+ @build_xcframeworks_all = false
112
+ @build_xcframeworks_include = []
113
+ @build_xcframeworks_exclude = []
118
114
 
119
115
  def self.check_inited
120
116
  raise "\n\nNot inited, run `pod_builder init`\n".red if podbuilder_path.nil?
@@ -218,12 +214,22 @@ module PodBuilder
218
214
  Configuration.react_native_project = value
219
215
  end
220
216
  end
221
- if value = json["build_xcframeworks"]
217
+ if value = json["build_xcframeworks_all"]
222
218
  if [TrueClass, FalseClass].include?(value.class)
223
- Configuration.build_xcframeworks = value
219
+ Configuration.build_xcframeworks_all = value
224
220
  end
225
221
  end
226
-
222
+ if value = json["build_xcframeworks_include"]
223
+ if value.is_a?(Array)
224
+ Configuration.build_xcframeworks_include = value
225
+ end
226
+ end
227
+ if value = json["build_xcframeworks_exclude"]
228
+ if value.is_a?(Array)
229
+ Configuration.build_xcframeworks_exclude = value
230
+ end
231
+ end
232
+
227
233
  Configuration.build_settings.freeze
228
234
 
229
235
  sanity_check()
@@ -279,6 +285,11 @@ module PodBuilder
279
285
  puts "PodBuilder.json contains '#{pod}' both in `force_prebuild_pods` and `skip_pods`. Will force prebuilding.".yellow
280
286
  end
281
287
  end
288
+ if Configuration.build_xcframeworks_all
289
+ raise "\n\nInvalid PodBuilder.json configuration: 'build_xcframeworks_all' is true and 'build_xcframeworks_include' is not empty\n".red if Configuration.build_xcframeworks_include.count > 0
290
+ else
291
+ raise "\n\nInvalid PodBuilder.json configuration: 'build_xcframeworks_all' is false and 'build_xcframeworks_exclude' is not empty\n".red if Configuration.build_xcframeworks_exclude.count > 0
292
+ end
282
293
  end
283
294
 
284
295
  def self.config_path
@@ -132,7 +132,7 @@ module PodBuilder
132
132
  folder_in_home = x.gsub(home, "")
133
133
  !folder_in_home.include?("/Pods/") && !x.include?(PodBuilder::basepath("Sources")) && !x.include?(PodBuilder::basepath + "/")
134
134
  }
135
- raise "\n\nxcodeproj not found!".red if xcodeprojects.count == 0
135
+ raise "\n\nxcodeproj not found!\n".red if xcodeprojects.count == 0
136
136
  raise "\n\nFound multiple xcodeproj:\n#{xcodeprojects.join("\n")}".red if xcodeprojects.count > 1
137
137
 
138
138
  @@xcodeproj_path = xcodeprojects.first
@@ -148,7 +148,7 @@ module PodBuilder
148
148
  folder_in_home = x.gsub(home, "")
149
149
  !folder_in_home.include?("/Pods/") && !x.include?(PodBuilder::basepath("Sources")) && !x.include?(PodBuilder::basepath + "/") && !x.include?(".xcodeproj/")
150
150
  }
151
- raise "\n\nxcworkspace not found!".red if xcworkspaces.count == 0
151
+ raise "\n\nxcworkspace not found!\n".red if xcworkspaces.count == 0
152
152
  raise "\n\nFound multiple xcworkspaces:\n#{xcworkspaces.join("\n")}".red if xcworkspaces.count > 1
153
153
 
154
154
  @@xcodeworkspace_path = xcworkspaces.first
@@ -179,7 +179,7 @@ module PodBuilder
179
179
 
180
180
  def self.system_swift_version
181
181
  swift_version = `swiftc --version | grep -o 'swiftlang-.*\s'`.strip()
182
- raise "\n\nUnsupported swift compiler version, expecting `swiftlang` keyword in `swiftc --version`".red if swift_version.length == 0
182
+ raise "\n\nUnsupported swift compiler version, expecting `swiftlang` keyword in `swiftc --version`\n".red if swift_version.length == 0
183
183
  return swift_version
184
184
  end
185
185
 
@@ -60,7 +60,7 @@ module PodBuilder
60
60
 
61
61
  return { "repo": "local" }
62
62
  else
63
- raise "\n\nFailed extracting version from line:\n#{line}\n\n".red
63
+ raise "\n\nFailed extracting version from line:\n#{line}\n".red
64
64
  end
65
65
  end
66
66
 
@@ -45,7 +45,7 @@ begin
45
45
  elsif defined?(Pod::Target::BuildType) # CocoaPods 1.7, 1.8
46
46
  Pod::Target::BuildType.new(linkage: :dynamic, packaging: :framework)
47
47
  else
48
- raise "\n\nBuildType not found. Open an issue reporting your CocoaPods version".red
48
+ raise "\n\nBuildType not found. Open an issue reporting your CocoaPods version\n".red
49
49
  end
50
50
  else
51
51
  swz_build_type()
@@ -139,7 +139,7 @@ module PodBuilder
139
139
 
140
140
  class Install
141
141
  # This method will generate prebuilt data by building from "/tmp/pod_builder/Podfile"
142
- def self.podfile(podfile_content, podfile_items, build_configuration)
142
+ def self.podfile(podfile_content, podfile_items, argument_pods, build_configuration)
143
143
  puts "Preparing build Podfile".yellow
144
144
 
145
145
  PodBuilder::safe_rm_rf(Configuration.build_path)
@@ -160,7 +160,7 @@ module PodBuilder
160
160
  lock_file = "#{Configuration.build_path}/pod_builder.lock"
161
161
  FileUtils.touch(lock_file)
162
162
 
163
- prebuilt_entries = use_prebuilt_entries_for_unchanged_pods(podfile_path, podfile_items)
163
+ prebuilt_entries = use_prebuilt_entries_for_unchanged_pods(podfile_path, podfile_items, argument_pods)
164
164
 
165
165
  install
166
166
 
@@ -247,7 +247,7 @@ module PodBuilder
247
247
  def self.license_specifiers
248
248
  acknowledge_file = "#{Configuration.build_path}/Pods/Target Support Files/Pods-DummyTarget/Pods-DummyTarget-acknowledgements.plist"
249
249
  unless File.exist?(acknowledge_file)
250
- raise "\n\nLicense file not found".red
250
+ raise "\n\nLicense file not found\n".red
251
251
  end
252
252
 
253
253
  plist = CFPropertyList::List.new(:file => acknowledge_file)
@@ -280,44 +280,66 @@ module PodBuilder
280
280
  return podfile_content
281
281
  end
282
282
 
283
- def self.use_prebuilt_entries_for_unchanged_pods(podfile_path, podfile_items)
283
+ def self.use_prebuilt_entries_for_unchanged_pods(podfile_path, podfile_items, argument_pods)
284
284
  podfile_content = File.read(podfile_path)
285
285
 
286
286
  replaced_items = []
287
287
 
288
- if OPTIONS.has_key?(:force_rebuild)
289
- podfile_content.gsub!("%%%prebuilt_root_paths%%%", "{}")
290
- else
291
- download # Copy files under #{Configuration.build_path}/Pods so that we can determine build folder hashes
288
+ download # Copy files under #{Configuration.build_path}/Pods so that we can determine build folder hashes
292
289
 
293
- gitignored_files = PodBuilder::gitignoredfiles
290
+ gitignored_files = PodBuilder::gitignoredfiles
294
291
 
295
- prebuilt_root_paths = Hash.new
292
+ prebuilt_root_paths = Hash.new
296
293
 
297
- # Replace prebuilt entries in Podfile for Pods that have no changes in source code which will avoid rebuilding them
298
- items = podfile_items.group_by { |t| t.root_name }.map { |k, v| v.first } # Return one podfile_item per root_name
299
- items.each do |item|
300
- podspec_path = item.prebuilt_podspec_path
301
- if last_build_folder_hash = build_folder_hash_in_prebuilt_info_file(item)
302
- if last_build_folder_hash == build_folder_hash(item, gitignored_files)
303
- puts "No changes detected to '#{item.root_name}', will skip rebuild".blue
294
+ puts "Optimizing build".yellow
295
+ puts "Build strategy".blue
304
296
 
305
- replaced_items.push(item)
297
+ prebuild_log = lambda { |item, reason|
298
+ if item.is_prebuilt
299
+ puts "#{item.root_name} is prebuilt"
300
+ else
301
+ puts "#{item.root_name} from source #{reason}".blue
302
+ end
303
+ }
306
304
 
307
- podfile_items.select { |t| t.root_name == item.root_name }.each do |replace_item|
308
- replace_regex = "pod '#{Regexp.quote(replace_item.name)}', .*"
309
- replace_line_found = podfile_content =~ /#{replace_regex}/i
310
- raise "\n\nFailed finding pod entry for '#{replace_item.name}'".red unless replace_line_found
311
- podfile_content.gsub!(/#{replace_regex}/, replace_item.prebuilt_entry(true, true))
305
+ # Replace prebuilt entries in Podfile for Pods that have no changes in source code which will avoid rebuilding them
306
+ items = podfile_items.group_by { |t| t.root_name }.map { |k, v| v.first }.sort_by { |t| t.root_name } # Return one podfile_item per root_name
307
+ if OPTIONS.has_key?(:force_rebuild)
308
+ rebuild_pods = items.select { |t| argument_pods.include?(t.root_name) }
312
309
 
313
- prebuilt_root_paths[replace_item.root_name] = PodBuilder::prebuiltpath
314
- end
315
- end
316
- end
310
+ rebuild_pods.each do |item|
311
+ prebuild_log.call(item, "")
317
312
  end
318
313
 
319
- podfile_content.gsub!("%%%prebuilt_root_paths%%%", prebuilt_root_paths.to_s)
314
+ items -= rebuild_pods
320
315
  end
316
+
317
+ items.each do |item|
318
+ podspec_path = item.prebuilt_podspec_path
319
+ unless last_build_folder_hash = build_folder_hash_in_prebuilt_info_file(item)
320
+ prebuild_log.call(item, "(folder hash missing)")
321
+ next
322
+ end
323
+
324
+ if last_build_folder_hash == build_folder_hash(item, gitignored_files)
325
+ puts "#{item.root_name} reuse PodBuilder cache"
326
+
327
+ replaced_items.push(item)
328
+
329
+ podfile_items.select { |t| t.root_name == item.root_name }.each do |replace_item|
330
+ replace_regex = "pod '#{Regexp.quote(replace_item.name)}', .*"
331
+ replace_line_found = podfile_content =~ /#{replace_regex}/i
332
+ raise "\n\nFailed finding pod entry for '#{replace_item.name}'\n".red unless replace_line_found
333
+ podfile_content.gsub!(/#{replace_regex}/, replace_item.prebuilt_entry(true, true))
334
+
335
+ prebuilt_root_paths[replace_item.root_name] = PodBuilder::prebuiltpath
336
+ end
337
+ else
338
+ prebuild_log.call(item, "(folder hash mismatch)")
339
+ end
340
+ end
341
+
342
+ podfile_content.gsub!("%%%prebuilt_root_paths%%%", prebuilt_root_paths.to_s)
321
343
 
322
344
  File.write(podfile_path, podfile_content)
323
345
 
@@ -379,6 +401,7 @@ module PodBuilder
379
401
  pod_names.each do |pod_name|
380
402
  root_name = pod_name.split("/").first
381
403
 
404
+ # Remove existing files
382
405
  items_to_delete = Dir.glob("#{PodBuilder::prebuiltpath(root_name)}/**/*")
383
406
  items_to_delete.each { |t| PodBuilder::safe_rm_rf(t) }
384
407
  end
@@ -393,6 +416,14 @@ module PodBuilder
393
416
  next
394
417
  end
395
418
 
419
+ if podfile_item = podfile_items.detect { |t| t.root_name == pod_name }
420
+ if Dir.glob("#{source_path}/**/Modules/**/*.swiftmodule/*.swiftinterface").count > 0
421
+ # We can safely remove .swiftmodule if .swiftinterface exists
422
+ swiftmodule_files = Dir.glob("#{source_path}/**/Modules/**/*.swiftmodule/*.swiftmodule")
423
+ swiftmodule_files.each { |t| PodBuilder::safe_rm_rf(t) }
424
+ end
425
+ end
426
+
396
427
  unless Dir.glob("#{source_path}/**/*").select { |t| File.file?(t) }.empty?
397
428
  destination_folder = PodBuilder::prebuiltpath(root_name)
398
429
  FileUtils.mkdir_p(destination_folder)
@@ -448,15 +479,16 @@ module PodBuilder
448
479
  unless File.file?(path)
449
480
  next
450
481
  end
451
-
482
+
452
483
  path = File.expand_path(path)
453
484
  rel_path = path.gsub(rootpath, "")[1..]
454
- unless exclude_files.include?(rel_path)
485
+
486
+ unless exclude_files.any? { |t| rel_path.start_with?(t) }
455
487
  file_hashes.push(Digest::MD5.hexdigest(File.read(path)))
456
488
  end
457
489
  end
458
490
 
459
- return Digest::MD5.hexdigest(file_hashes.join)
491
+ return Digest::MD5.hexdigest(file_hashes.sort.join)
460
492
  else
461
493
  # Pod folder might be under .gitignore
462
494
  item_path = "#{Configuration.build_path}/Pods/#{podfile_item.root_name}"
@@ -12,19 +12,19 @@
12
12
 
13
13
  if current_licenses.count > 0
14
14
  licenses_header = current_licenses.shift
15
- raise "\n\nUnexpected license found in header".red if licenses_header.has_key?("License")
15
+ raise "\n\nUnexpected license found in header\n".red if licenses_header.has_key?("License")
16
16
  end
17
17
  if current_licenses.count > 0
18
18
  license_footer = current_licenses.pop
19
- raise "\n\nUnexpected license found in footer".red if license_footer.has_key?("License")
19
+ raise "\n\nUnexpected license found in footer\n".red if license_footer.has_key?("License")
20
20
  end
21
21
  end
22
22
 
23
23
  if licenses.count > 0
24
24
  licenses_header = licenses.shift
25
- raise "\n\nUnexpected license found in header".red if licenses_header.has_key?("License")
25
+ raise "\n\nUnexpected license found in header\n".red if licenses_header.has_key?("License")
26
26
  license_footer = licenses.pop
27
- raise "\n\nUnexpected license found in footer".red if license_footer.has_key?("License")
27
+ raise "\n\nUnexpected license found in footer\n".red if license_footer.has_key?("License")
28
28
 
29
29
  lincenses_titles = licenses.map { |x| x["Title"] }
30
30
  current_licenses.select! { |x| !lincenses_titles.include?(x["Title"]) }
@@ -6,7 +6,7 @@ module PodBuilder
6
6
  PRE_INSTALL_ACTIONS = ["Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_duplicate_framework_and_library_names) {}", "require 'pod_builder/podfile/pre_actions_swizzles'"].freeze
7
7
 
8
8
  def self.from_podfile_items(items, analyzer, build_configuration, install_using_frameworks, build_catalyst, build_xcframeworks)
9
- raise "\n\nno items".red unless items.count > 0
9
+ raise "\n\nno items\n".red unless items.count > 0
10
10
 
11
11
  sources = analyzer.sources
12
12
 
@@ -41,6 +41,9 @@ module PodBuilder
41
41
  build_settings["ONLY_ACTIVE_ARCH"] = "NO"
42
42
  build_settings["DEBUG_INFORMATION_FORMAT"] = "dwarf-with-dsym"
43
43
 
44
+ # https://thi.imhttps://thi.im/posts/swift-serialize-debugging-options/
45
+ build_settings["SWIFT_SERIALIZE_DEBUGGING_OPTIONS"] = "NO"
46
+
44
47
  build_settings["IPHONEOS_DEPLOYMENT_TARGET"] = platform.deployment_target.version # Fix compilation warnings on Xcode 12
45
48
 
46
49
  # Don't store .pcm info in binary, see https://forums.swift.org/t/swift-behavior-of-gmodules-and-dsyms/23211/3
@@ -57,11 +60,7 @@ module PodBuilder
57
60
 
58
61
  if Configuration.build_system == "Legacy"
59
62
  build_settings["BUILD_LIBRARY_FOR_DISTRIBUTION"] = "NO"
60
- raise "\n\nCan't enable library evolution support with legacy build system!".red if Configuration.library_evolution_support
61
- elsif Configuration.library_evolution_support
62
- build_settings["BUILD_LIBRARY_FOR_DISTRIBUTION"] = "YES"
63
- end
64
- if Configuration.build_xcframeworks
63
+ elsif Configuration.library_evolution_support || item.build_xcframework
65
64
  build_settings["BUILD_LIBRARY_FOR_DISTRIBUTION"] = "YES"
66
65
  end
67
66
 
@@ -355,7 +354,7 @@ module PodBuilder
355
354
 
356
355
  if stripped_line.match(/(pod')(.*?)(')/) != nil
357
356
  starting_def_found = stripped_line.start_with?("def") && (line.match("\s*def\s") != nil)
358
- raise "\n\nUnsupported single line def/pod. `def` and `pod` shouldn't be on the same line, please modify the following line:\n#{line}".red if starting_def_found
357
+ raise "\n\nUnsupported single line def/pod. `def` and `pod` shouldn't be on the same line, please modify the following line:\n#{line}\n".red if starting_def_found
359
358
  end
360
359
  end
361
360
  end
@@ -397,9 +396,9 @@ module PodBuilder
397
396
  if target_settings.count == 1
398
397
  return target_settings.first
399
398
  elsif target_settings.count > 1
400
- raise "\n\n'use_frameworks!' should be declared only once at Podfile root level (not nested in targets)".red
399
+ raise "\n\n'use_frameworks!' should be declared only once at Podfile root level (not nested in targets)\n".red
401
400
  else
402
- raise "\n\nFailed detecting use_frameworks!"
401
+ raise "\n\nFailed detecting use_frameworks!\n".red
403
402
  end
404
403
 
405
404
  return true
@@ -444,13 +443,13 @@ module PodBuilder
444
443
  def self.project_swift_version(analyzer)
445
444
  swift_versions = analyzer.instance_variable_get("@result").targets.map { |x| x.target_definition.swift_version }.compact.uniq
446
445
 
447
- raise "\n\nFound different Swift versions in targets. Expecting one, got `#{swift_versions}`".red if swift_versions.count > 1
446
+ raise "\n\nFound different Swift versions in targets. Expecting one, got `#{swift_versions}`\n".red if swift_versions.count > 1
448
447
 
449
448
  return swift_versions.first || PodBuilder::system_swift_version
450
449
  end
451
450
 
452
451
  def self.podfile_items_at(podfile_path, include_prebuilt = false)
453
- raise "\n\nExpecting basepath folder!".red if !File.exist?(PodBuilder::basepath("Podfile"))
452
+ raise "\n\nExpecting basepath folder!\n".red if !File.exist?(PodBuilder::basepath("Podfile"))
454
453
 
455
454
  if File.basename(podfile_path) != "Podfile"
456
455
  File.rename(PodBuilder::basepath("Podfile"), PodBuilder::basepath("Podfile.tmp"))
@@ -608,12 +607,12 @@ module PodBuilder
608
607
  base = File.expand_path(File.join(PodBuilder::project_path, ".."))
609
608
  bin_js = Dir.glob("#{base}/node_modules/@react-native-community/cli/build/bin.js")
610
609
 
611
- raise "\n\nReact native cli bin_js not found! Did you run yarn install?".red unless bin_js.count == 1
610
+ raise "\n\nReact native cli bin_js not found! Did you run yarn install?\n".red unless bin_js.count == 1
612
611
  bin_js = bin_js.first
613
612
 
614
613
  config_dest_path = PodBuilder::basepath("rn_config.json")
615
614
 
616
- raise "\n\nFailed generating react native configuration file".red unless system("node '#{bin_js}' config > #{config_dest_path}")
615
+ raise "\n\nFailed generating react native configuration file\n".red unless system("node '#{bin_js}' config > #{config_dest_path}")
617
616
 
618
617
  content = File.read(config_dest_path)
619
618
 
@@ -625,7 +624,7 @@ module PodBuilder
625
624
  json["project"]["ios"]["sourceDir"] = "./"
626
625
  json["project"]["ios"]["podfile"] = "./"
627
626
  rescue => exception
628
- raise "\n\nFailed updating react native configuration json".red
627
+ raise "\n\nFailed updating react native configuration json\n".red
629
628
  end
630
629
 
631
630
  File.write(config_dest_path, JSON.pretty_generate(json))
@@ -24,7 +24,7 @@ class Pod::Generator::EmbedFrameworksScript
24
24
  alias_method :swz_initialize, :initialize
25
25
 
26
26
  def initialize(*args)
27
- raise "Unsupported CocoaPods version" if (args.count == 0 || args.count > 2)
27
+ raise "\n\nUnsupported CocoaPods version\n".red if (args.count == 0 || args.count > 2)
28
28
 
29
29
  frameworks_by_config = args[0]
30
30
  frameworks_by_config.keys.each do |key|
@@ -103,27 +103,27 @@ module PodBuilder
103
103
  #
104
104
  attr_accessor :libraries
105
105
 
106
- # @return [String] source_files
106
+ # @return [String] Source_files
107
107
  #
108
108
  attr_accessor :source_files
109
109
 
110
- # @return [String] license
110
+ # @return [String] License
111
111
  #
112
112
  attr_accessor :license
113
113
 
114
- # @return [String] summary
114
+ # @return [String] Summary
115
115
  #
116
116
  attr_accessor :summary
117
117
 
118
- # @return [Hash] source
118
+ # @return [Hash] Source
119
119
  #
120
120
  attr_accessor :source
121
121
 
122
- # @return [Hash] authors
122
+ # @return [Hash] Authors
123
123
  #
124
124
  attr_accessor :authors
125
125
 
126
- # @return [String] homepage
126
+ # @return [String] Homepage
127
127
  #
128
128
  attr_accessor :homepage
129
129
 
@@ -134,6 +134,14 @@ module PodBuilder
134
134
  # @return [Bool] Defines module
135
135
  #
136
136
  attr_accessor :defines_module
137
+
138
+ # @return [Bool] Should build as xcframework
139
+ #
140
+ attr_accessor :build_xcframework
141
+
142
+ # @return [Bool] True if it's a pod that doesn't provide source code (is already shipped as a prebuilt pod)
143
+ #
144
+ attr_accessor :is_prebuilt
137
145
 
138
146
  # Initialize a new instance
139
147
  #
@@ -235,6 +243,15 @@ module PodBuilder
235
243
  @source = spec.root.attributes_hash.fetch("source", { "git"=>"https://github.com/Subito-it/PodBuilder.git" })
236
244
  @authors = spec.root.attributes_hash.fetch("authors", {"PodBuilder"=>"pod@podbuilder.com"})
237
245
  @homepage = spec.root.attributes_hash.fetch("homepage", "https://github.com/Subito-it/PodBuilder")
246
+
247
+ if Configuration.build_xcframeworks_all
248
+ build_as_xcframework = !Configuration.build_xcframeworks_exclude.include?(@root_name)
249
+ else
250
+ build_as_xcframework = Configuration.build_xcframeworks_include.include?(@root_name)
251
+ end
252
+ @build_xcframework = build_as_xcframework
253
+
254
+ @is_prebuilt = extract_is_prebuilt(spec, all_specs, checkout_options, supported_platforms)
238
255
  end
239
256
 
240
257
  def pod_specification(all_poditems, parent_spec = nil)
@@ -324,33 +341,6 @@ module PodBuilder
324
341
  return deps
325
342
  end
326
343
 
327
- # @return [Bool] True if it's a pod that doesn't provide source code (is already shipped as a prebuilt pod)
328
- #
329
- def is_prebuilt
330
- if Configuration.force_prebuild_pods.include?(@root_name) || Configuration.force_prebuild_pods.include?(@name)
331
- return false
332
- end
333
-
334
- # We treat pods to skip like prebuilt ones
335
- if Configuration.skip_pods.include?(@root_name) || Configuration.skip_pods.include?(@name)
336
- return true
337
- end
338
-
339
- # Podspecs aren't always properly written (source_file key is often used instead of header_files)
340
- # Therefore it can become tricky to understand which pods are already precompiled by boxing a .framework or .a
341
- embedded_as_vendored = vendored_frameworks.map { |x| File.basename(x) }.include?("#{module_name}.framework")
342
- embedded_as_static_lib = vendored_libraries.map { |x| File.basename(x) }.include?("lib#{module_name}.a")
343
-
344
- only_headers = (source_files.count > 0 && @source_files.all? { |x| x.end_with?(".h") })
345
- no_sources = (@source_files.count == 0 || only_headers) && (@vendored_frameworks + @vendored_libraries).count > 0
346
-
347
- if !no_sources && !only_headers
348
- return false
349
- else
350
- return (no_sources || only_headers || embedded_as_static_lib || embedded_as_vendored)
351
- end
352
- end
353
-
354
344
  # @return [Bool] True if it's a subspec
355
345
  #
356
346
  def is_subspec
@@ -461,6 +451,44 @@ module PodBuilder
461
451
 
462
452
  private
463
453
 
454
+ # @return [Bool] True if it's a pod that doesn't provide source code (is already shipped as a prebuilt pod)
455
+ #
456
+ def extract_is_prebuilt(spec, all_specs, checkout_options, supported_platforms)
457
+ if Configuration.force_prebuild_pods.include?(@root_name) || Configuration.force_prebuild_pods.include?(@name)
458
+ return false
459
+ end
460
+
461
+ # We treat pods to skip like prebuilt ones
462
+ if Configuration.skip_pods.include?(@root_name) || Configuration.skip_pods.include?(@name)
463
+ return true
464
+ end
465
+
466
+ if default_subspecs != nil && default_subspecs.count > 0
467
+ default_subspecs.each do |default_subspec_name|
468
+ if (default_spec = all_specs.detect { |t| t.name == "#{root_name}/#{default_subspec_name}" })
469
+ default_item = PodfileItem.new(default_spec, all_specs, checkout_options, supported_platforms)
470
+ if default_item.is_prebuilt
471
+ return true
472
+ end
473
+ end
474
+ end
475
+ end
476
+
477
+ # Podspecs aren't always properly written (source_file key is often used instead of header_files)
478
+ # Therefore it can become tricky to understand which pods are already precompiled by boxing a .framework or .a
479
+ embedded_as_vendored = vendored_frameworks.map { |x| File.basename(x) }.include?("#{module_name}.framework")
480
+ embedded_as_static_lib = vendored_libraries.map { |x| File.basename(x) }.include?("lib#{module_name}.a")
481
+
482
+ only_headers = (source_files.count > 0 && @source_files.all? { |x| x.end_with?(".h") })
483
+ no_sources = (@source_files.count == 0 || only_headers) && (@vendored_frameworks + @vendored_libraries).count > 0
484
+
485
+ if !no_sources && !only_headers
486
+ return false
487
+ else
488
+ return (no_sources || only_headers || embedded_as_static_lib || embedded_as_vendored)
489
+ end
490
+ end
491
+
464
492
  def extract_vendored_frameworks(spec, all_specs)
465
493
  items = []
466
494
 
@@ -53,7 +53,11 @@ module PodBuilder
53
53
  resources = []
54
54
  exclude_files = []
55
55
  vendored_frameworks.each do |vendored_framework|
56
- binary_path = Dir.glob(PodBuilder::prebuiltpath("#{item.root_name}/#{vendored_framework}/**/#{File.basename(vendored_framework, ".*")}")).first
56
+ if vendored_framework.end_with?(".xcframework")
57
+ binary_path = Dir.glob(PodBuilder::prebuiltpath("#{item.root_name}/#{vendored_framework}/**/#{File.basename(vendored_framework, ".*")}")).reject { |t| t.include?("simulator") }.first
58
+ else
59
+ binary_path = Dir.glob(PodBuilder::prebuiltpath("#{item.root_name}/#{vendored_framework}/**/#{File.basename(vendored_framework, ".*")}")).first
60
+ end
57
61
 
58
62
  next if binary_path.nil?
59
63
 
@@ -138,7 +142,7 @@ module PodBuilder
138
142
  end
139
143
  if !install_using_frameworks && spec_var == "p1" && vendored_libraries.map { |t| File.basename(t) }.include?("lib#{item.root_name}.a" )
140
144
  module_path_files = Dir.glob(PodBuilder.prebuiltpath("#{item.root_name}/**/#{item.root_name}.modulemap"))
141
- raise "\n\nToo many module maps found for #{item.root_name}".red if module_path_files.count > 1
145
+ raise "\n\nToo many module maps found for #{item.root_name}\n".red if module_path_files.count > 1
142
146
 
143
147
  rel_path = Pathname.new(PodBuilder::prebuiltpath).relative_path_from(Pathname.new(PodBuilder::project_path("Pods"))).to_s
144
148
  prebuilt_root_var = "#{item.root_name.upcase.gsub("-", "_")}_PREBUILT_ROOT"
@@ -6,9 +6,11 @@ module PodBuilder
6
6
  class XcodeBuildSettings
7
7
  attr_reader :platform_name
8
8
  attr_reader :build_destination
9
+ attr_reader :configuration
9
10
 
10
- def initialize(platform_name)
11
+ def initialize(platform_name, configuration)
11
12
  @platform_name = platform_name
13
+ @configuration = configuration
12
14
 
13
15
  case platform_name
14
16
  when "iphoneos" then @build_destination = "generic/platform=iOS"
@@ -19,7 +21,7 @@ module PodBuilder
19
21
  when "tvossimulator" then @build_destination = "generic/platform=tvOS Simulator"
20
22
  when "watchos" then @build_destination = "generic/platform=watchOS"
21
23
  when "watchossimulator" then @build_destination = "generic/platform=watchOS Simulator"
22
- else raise "\n\nUnknown platform '#{platform_name}'".red end
24
+ else raise "\n\nUnknown platform '#{platform_name}'\n".red end
23
25
  end
24
26
  end
25
27
 
@@ -63,7 +65,7 @@ module PodBuilder
63
65
  `xcrun lipo -remove arm64 #{simulator_lib} -o #{simulator_lib}`
64
66
  end
65
67
 
66
- raise "Lipo failed on #{device_lib}" unless system("xcrun lipo -create -output #{device_lib} #{device_lib} #{simulator_lib}")
68
+ raise "\n\nLipo failed on #{device_lib}\n".red unless system("xcrun lipo -create -output #{device_lib} #{device_lib} #{simulator_lib}")
67
69
 
68
70
  merge_header_into(device_swift_header_path, simulator_swift_header_path)
69
71
 
@@ -114,7 +116,7 @@ module PodBuilder
114
116
  `xcrun lipo -remove arm64 #{simulator_lib} -o #{simulator_lib}`
115
117
  end
116
118
 
117
- raise "Lipo failed on #{device_lib}" unless system("xcrun lipo -create -output #{device_lib} #{device_lib} #{simulator_lib}")
119
+ raise "\n\nLipo failed on #{device_lib}\n".red unless system("xcrun lipo -create -output #{device_lib} #{device_lib} #{simulator_lib}")
118
120
 
119
121
  device_headers = Dir.glob("#{device_base}/**/*.h")
120
122
  simulator_headers = Dir.glob("#{simulator_base}/**/*.h")
@@ -245,7 +247,7 @@ module PodBuilder
245
247
  output = stdout + stderr
246
248
  unless status.success?
247
249
  if raise_on_failure
248
- raise "#{full_command}\n\n#{output}"
250
+ raise "\n\n#{full_command}\n\n#{output}\n".red
249
251
  else
250
252
  UI.message("[!] Failed: #{full_command}".red)
251
253
  end
@@ -305,7 +307,7 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
305
307
  build_dir.rmtree if build_dir.directory?
306
308
 
307
309
  targets = installer_context.umbrella_targets.select { |t| t.specs.any? }
308
- raise "\n\nUnsupported target count".red unless targets.count == 1
310
+ raise "\n\nUnsupported target count\n".red unless targets.count == 1
309
311
  target = targets.first
310
312
 
311
313
  if build_xcframeworks
@@ -313,18 +315,18 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
313
315
 
314
316
  case target.platform_name
315
317
  when :ios then
316
- xcodebuild_settings = [PodBuilder::XcodeBuildSettings.new("iphoneos"), PodBuilder::XcodeBuildSettings.new("iphonesimulator")]
318
+ xcodebuild_settings = [PodBuilder::XcodeBuildSettings.new("iphoneos", configuration), PodBuilder::XcodeBuildSettings.new("iphonesimulator", configuration)]
317
319
  if build_catalyst
318
- xcodebuild_settings += [PodBuilder::XcodeBuildSettings.new("catalyst")]
320
+ xcodebuild_settings += [PodBuilder::XcodeBuildSettings.new("catalyst", configuration)]
319
321
  end
320
- when :osx then xcodebuild_settings = [PodBuilder::XcodeBuildSettings.new("macos")]
321
- when :tvos then xcodebuild_settings = [PodBuilder::XcodeBuildSettings.new("tvos"), PodBuilder::XcodeBuildSettings.new("tvossimulator")]
322
- when :watchos then xcodebuild_settings = [PodBuilder::XcodeBuildSettings.new("watchos"), PodBuilder::XcodeBuildSettings.new("watchossimulator")]
323
- else raise "\n\nUnknown platform '#{target.platform_name}'".red end
322
+ when :osx then xcodebuild_settings = [PodBuilder::XcodeBuildSettings.new("macos", configuration)]
323
+ when :tvos then xcodebuild_settings = [PodBuilder::XcodeBuildSettings.new("tvos", configuration), PodBuilder::XcodeBuildSettings.new("tvossimulator", configuration)]
324
+ when :watchos then xcodebuild_settings = [PodBuilder::XcodeBuildSettings.new("watchos", configuration), PodBuilder::XcodeBuildSettings.new("watchossimulator", configuration)]
325
+ else raise "\n\nUnknown platform '#{target.platform_name}'\n".red end
324
326
 
325
327
  xcodebuild_settings.each do |xcodebuild_setting|
326
328
  puts "Building xcframeworks for #{xcodebuild_setting.platform_name}".yellow
327
- raise "\n\n#{build_destination} xcframework archive failed!".red if !system("xcodebuild archive -project #{project_path.to_s} -scheme Pods-DummyTarget -destination '#{xcodebuild_setting.build_destination}' -archivePath '#{build_dir}/#{xcodebuild_setting.platform_name}' SKIP_INSTALL=NO > /dev/null 2>&1")
329
+ raise "\n\n#{xcodebuild_setting.build_destination} xcframework archive failed!\n".red if !system("xcodebuild archive -project #{project_path.to_s} -scheme Pods-DummyTarget -configuration #{xcodebuild_setting.configuration} -destination '#{xcodebuild_setting.build_destination}' -archivePath '#{build_dir}/#{xcodebuild_setting.platform_name}' SKIP_INSTALL=NO > /dev/null 2>&1")
328
330
  end
329
331
 
330
332
  built_items = Dir.glob("#{build_dir}/#{xcodebuild_settings[0].platform_name}.xcarchive/Products/Library/Frameworks/*").reject { |t| File.basename(t, ".*") == "Pods_DummyTarget" }
@@ -346,7 +348,7 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
346
348
  framework_name = File.basename(built_item_paths.first, ".*")
347
349
  xcframework_path = "#{base_destination}/#{framework_name}/#{framework_name}.xcframework"
348
350
  framework_params = built_item_paths.map { |t| "-framework '#{t}'"}.join(" ")
349
- raise "\n\nFailed packing xcframework!".red if !system("xcodebuild -create-xcframework #{framework_params} -output '#{xcframework_path}' > /dev/null 2>&1")
351
+ raise "\n\nFailed packing xcframework!\n".red if !system("xcodebuild -create-xcframework #{framework_params} -output '#{xcframework_path}' > /dev/null 2>&1")
350
352
 
351
353
  if enable_dsym
352
354
  xcodebuild_settings.each do |xcodebuild_setting|
@@ -359,7 +361,7 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
359
361
  end
360
362
  end
361
363
  else
362
- raise "Not implemented"
364
+ raise "\n\nNot implemented\n".red
363
365
  end
364
366
  end
365
367
 
@@ -375,7 +377,7 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
375
377
  when [:osx, false] then PodBuilder::xcodebuild(sandbox, target.cocoapods_target_label, configuration, PodBuilder::Configuration.deterministic_build, prebuilt_root_paths)
376
378
  when [:tvos, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'appletvos', 'appletvsimulator', configuration, PodBuilder::Configuration.deterministic_build, prebuilt_root_paths)
377
379
  when [:watchos, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'watchos', 'watchsimulator', configuration, PodBuilder::Configuration.deterministic_build, prebuilt_root_paths)
378
- else raise "\n\nUnknown platform '#{target.platform_name}'".red end
380
+ else raise "\n\nUnknown platform '#{target.platform_name}'\n".red end
379
381
 
380
382
  raise Pod::Informative, 'The build directory was not found in the expected location.' unless build_dir.directory?
381
383
 
@@ -434,7 +436,7 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
434
436
  FileUtils.mv(dsym_source, sandbox_root.parent)
435
437
  end
436
438
  else
437
- raise "Not implemented"
439
+ raise "\n\nNot implemented\n".red
438
440
  end
439
441
  end
440
442
 
@@ -1,4 +1,4 @@
1
1
  module PodBuilder
2
- VERSION = "2.2.1"
2
+ VERSION = "3.2.0"
3
3
  end
4
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pod-builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomas Camin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-10 00:00:00.000000000 Z
11
+ date: 2021-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -233,7 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
233
233
  - !ruby/object:Gem::Version
234
234
  version: '0'
235
235
  requirements: []
236
- rubygems_version: 3.1.2
236
+ rubygems_version: 3.0.3
237
237
  signing_key:
238
238
  specification_version: 4
239
239
  summary: Prebuild CocoaPods pods