pod-builder 2.0.0.beta.24 → 2.0.0.beta.29
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 +4 -4
- data/README.md +10 -22
- data/exe/pod_builder +12 -34
- data/lib/pod_builder/command.rb +1 -3
- data/lib/pod_builder/command/build.rb +62 -15
- data/lib/pod_builder/command/clean.rb +14 -1
- data/lib/pod_builder/command/generate_lldbinit.rb +151 -0
- data/lib/pod_builder/command/generate_podspec.rb +3 -1
- data/lib/pod_builder/command/init.rb +23 -11
- data/lib/pod_builder/command/install_sources.rb +2 -2
- data/lib/pod_builder/configuration.rb +22 -22
- data/lib/pod_builder/install.rb +275 -126
- data/lib/pod_builder/podfile.rb +21 -22
- data/lib/pod_builder/podfile_cp.rb +10 -4
- data/lib/pod_builder/podfile_item.rb +32 -38
- data/lib/pod_builder/podspec.rb +82 -29
- data/lib/pod_builder/rome/post_install.rb +169 -42
- data/lib/pod_builder/templates/build_podfile.template +1 -1
- data/lib/pod_builder/version.rb +1 -1
- metadata +3 -5
- data/lib/pod_builder/command/clear_lldbinit.rb +0 -48
- data/lib/pod_builder/command/generate_lfs.rb +0 -70
- data/lib/pod_builder/command/update_lldbinit.rb +0 -162
data/lib/pod_builder/podfile.rb
CHANGED
@@ -7,7 +7,7 @@ module PodBuilder
|
|
7
7
|
PRE_INSTALL_ACTIONS = ["Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_duplicate_framework_and_library_names) {}"].freeze
|
8
8
|
private_constant :PRE_INSTALL_ACTIONS
|
9
9
|
|
10
|
-
def self.from_podfile_items(items, analyzer, build_configuration)
|
10
|
+
def self.from_podfile_items(items, analyzer, build_configuration, install_using_frameworks)
|
11
11
|
raise "\n\nno items".red unless items.count > 0
|
12
12
|
|
13
13
|
sources = analyzer.sources
|
@@ -17,9 +17,8 @@ module PodBuilder
|
|
17
17
|
|
18
18
|
platform = analyzer.instance_variable_get("@result").targets.first.platform
|
19
19
|
|
20
|
-
install_using_frameworks
|
21
|
-
|
22
|
-
podfile.sub!("%%%use_frameworks%%%", install_using_frameworks ? "use_frameworks!" : "")
|
20
|
+
podfile.sub!("%%%use_frameworks%%%", install_using_frameworks ? "use_frameworks!" : "use_modular_headers!")
|
21
|
+
podfile.sub!("%%%uses_frameworks%%%", install_using_frameworks ? "true" : "false")
|
23
22
|
|
24
23
|
podfile.sub!("%%%platform_name%%%", platform.name.to_s)
|
25
24
|
podfile.sub!("%%%deployment_version%%%", platform.deployment_target.version)
|
@@ -46,7 +45,7 @@ module PodBuilder
|
|
46
45
|
|
47
46
|
# Don't store .pcm info in binary, see https://forums.swift.org/t/swift-behavior-of-gmodules-and-dsyms/23211/3
|
48
47
|
build_settings['CLANG_ENABLE_MODULE_DEBUGGING'] = 'NO'
|
49
|
-
build_settings['OTHER_SWIFT_FLAGS'] = "-Xfrontend -no-clang-module-breadcrumbs"
|
48
|
+
build_settings['OTHER_SWIFT_FLAGS'] = "$(inherited) -Xfrontend -no-clang-module-breadcrumbs"
|
50
49
|
|
51
50
|
# Improve compile speed
|
52
51
|
build_settings['COMPILER_INDEX_STORE_ENABLE'] = 'NO'
|
@@ -385,6 +384,22 @@ module PodBuilder
|
|
385
384
|
resolved_names.uniq
|
386
385
|
end
|
387
386
|
|
387
|
+
def self.install_using_frameworks(analyzer)
|
388
|
+
target_settings = analyzer.podfile.target_definition_list.map(&:uses_frameworks?).uniq
|
389
|
+
if target_settings.count == 1
|
390
|
+
if target_settings.first == false && ENV['DEBUGGING'].nil?
|
391
|
+
raise "\n\nOnly framework packaging currently supported. Please add 'use_frameworks!' at Podfile root level (not nested in targets)".red
|
392
|
+
end
|
393
|
+
return target_settings.first
|
394
|
+
elsif target_settings.count > 1
|
395
|
+
raise "\n\n'use_frameworks!' should be declared only once at Podfile root level (not nested in targets)".red
|
396
|
+
else
|
397
|
+
raise "\n\nFailed detecting use_frameworks!"
|
398
|
+
end
|
399
|
+
|
400
|
+
return true
|
401
|
+
end
|
402
|
+
|
388
403
|
private
|
389
404
|
|
390
405
|
def self.podfile_path_transform(path)
|
@@ -592,7 +607,7 @@ module PodBuilder
|
|
592
607
|
base = File.expand_path(File.join(PodBuilder::project_path, ".."))
|
593
608
|
bin_js = Dir.glob("#{base}/node_modules/@react-native-community/cli/build/bin.js")
|
594
609
|
|
595
|
-
raise "\n\nReact native cli bin_js not found!".red unless bin_js.count == 1
|
610
|
+
raise "\n\nReact native cli bin_js not found! Did you run yarn install?".red unless bin_js.count == 1
|
596
611
|
bin_js = bin_js.first
|
597
612
|
|
598
613
|
config_dest_path = PodBuilder::basepath("rn_config.json")
|
@@ -677,21 +692,5 @@ module PodBuilder
|
|
677
692
|
|
678
693
|
return podfile_content
|
679
694
|
end
|
680
|
-
|
681
|
-
def self.install_using_frameworks(analyzer)
|
682
|
-
target_settings = analyzer.podfile.target_definition_list.map(&:uses_frameworks?).uniq
|
683
|
-
if target_settings.count == 1
|
684
|
-
if target_settings.first == false
|
685
|
-
raise "\n\nOnly framework packaging currently supported. Please add 'use_frameworks!' at Podfile root level (not nested in targets)".red
|
686
|
-
end
|
687
|
-
return target_settings.first
|
688
|
-
elsif target_settings.count > 1
|
689
|
-
raise "\n\n'use_frameworks!' should be declared only once at Podfile root level (not nested in targets)".red
|
690
|
-
else
|
691
|
-
raise "\n\nFailed detecting use_frameworks!"
|
692
|
-
end
|
693
|
-
|
694
|
-
return true
|
695
|
-
end
|
696
695
|
end
|
697
696
|
end
|
@@ -3,7 +3,7 @@ require 'cocoapods/podfile.rb'
|
|
3
3
|
module Pod
|
4
4
|
class Podfile
|
5
5
|
class TargetDefinition
|
6
|
-
def pb_to_s(all_buildable_items, indent_level = 0)
|
6
|
+
def pb_to_s(all_buildable_items, indent_level = 0, parent_pods = [])
|
7
7
|
indentation = " " * indent_level
|
8
8
|
target_s = "#{indentation}target '#{self.name}' do\n"
|
9
9
|
|
@@ -15,7 +15,8 @@ module Pod
|
|
15
15
|
prebuild_entries = []
|
16
16
|
self.dependencies.each do |dep|
|
17
17
|
if podfile_item = all_buildable_items.detect { |t| t.name == dep.name }
|
18
|
-
|
18
|
+
is_prebuilt = all_buildable_items.select { |t| t.root_name == dep.root_name}.all?(&:is_prebuilt)
|
19
|
+
if File.exist?(podfile_item.prebuilt_podspec_path) && !is_prebuilt
|
19
20
|
prebuild_entries.push(podfile_item)
|
20
21
|
else
|
21
22
|
pod_entries.push(podfile_item)
|
@@ -34,7 +35,8 @@ module Pod
|
|
34
35
|
non_explicit_dependencies.each do |dep|
|
35
36
|
dep_item = all_buildable_items.detect { |x| x.name == dep.name }
|
36
37
|
|
37
|
-
|
38
|
+
is_prebuilt = all_buildable_items.select { |t| t.root_name == dep.root_name}.all?(&:is_prebuilt)
|
39
|
+
if File.exist?(dep_item.prebuilt_podspec_path) && !is_prebuilt
|
38
40
|
prebuild_entries.push(dep_item)
|
39
41
|
else
|
40
42
|
pod_entries.push(dep_item)
|
@@ -47,6 +49,10 @@ module Pod
|
|
47
49
|
|
48
50
|
prebuild_entries = prebuild_entries.uniq.sort_by { |t| t.name }
|
49
51
|
pod_entries = pod_entries.uniq.sort_by { |t| t.name }
|
52
|
+
|
53
|
+
# Don't include inherited pods
|
54
|
+
prebuild_entries.reject! { |t| parent_pods.include?(t) }
|
55
|
+
pod_entries.reject! { |t| parent_pods.include?(t) }
|
50
56
|
|
51
57
|
prebuild_entries.each do |pod|
|
52
58
|
target_s += "#{child_indentation}#{pod.prebuilt_entry(false, false)}\n"
|
@@ -57,7 +63,7 @@ module Pod
|
|
57
63
|
|
58
64
|
if self.children.count > 0
|
59
65
|
target_s += "\n"
|
60
|
-
target_s += @children.map { |t| t.pb_to_s(all_buildable_items, indent_level + 1) }.join("\n\n")
|
66
|
+
target_s += @children.map { |t| t.pb_to_s(all_buildable_items, indent_level + 1, parent_pods + pod_entries + prebuild_entries) }.join("\n\n")
|
61
67
|
end
|
62
68
|
|
63
69
|
target_s += "#{indentation}end\n"
|
@@ -79,6 +79,10 @@ module PodBuilder
|
|
79
79
|
#
|
80
80
|
attr_accessor :build_configuration
|
81
81
|
|
82
|
+
# @return [Array<String>] When building static frameworks we sometimes have to remove module maps from Other C flags to make compilation succeed
|
83
|
+
#
|
84
|
+
attr_accessor :remove_module_maps
|
85
|
+
|
82
86
|
# @return [String] The pod's vendored frameworks
|
83
87
|
#
|
84
88
|
attr_accessor :vendored_frameworks
|
@@ -180,7 +184,11 @@ module PodBuilder
|
|
180
184
|
|
181
185
|
@default_subspecs = extract_array(spec, "default_subspecs")
|
182
186
|
if default_subspec = spec.attributes_hash["default_subspec"]
|
183
|
-
@default_subspecs.push(default_subspec)
|
187
|
+
@default_subspecs.push(default_subspec)
|
188
|
+
end
|
189
|
+
|
190
|
+
if @name == @root_name && @default_subspecs.empty?
|
191
|
+
@default_subspecs += all_specs.select { |t| t.name.include?("/") && t.name.split("/").first == @root_name }.map { |t| t.name.split("/").last }
|
184
192
|
end
|
185
193
|
|
186
194
|
@dependency_names = spec.attributes_hash.fetch("dependencies", {}).keys + default_subspecs.map { |t| "#{@root_name}/#{t}" }
|
@@ -194,11 +202,18 @@ module PodBuilder
|
|
194
202
|
@is_static = spec.root.attributes_hash["static_framework"] || false
|
195
203
|
@xcconfig = spec.root.attributes_hash["xcconfig"] || {}
|
196
204
|
|
197
|
-
|
205
|
+
default_subspecs_specs ||= begin
|
206
|
+
subspecs = all_specs.select { |t| t.name.split("/").first == @root_name }
|
207
|
+
subspecs.select { |t| @default_subspecs.include?(t.name.split("/").last) }
|
208
|
+
end
|
209
|
+
root_spec = all_specs.detect { |t| t.name == @root_name } || spec
|
210
|
+
@source_files = source_files_from([spec, root_spec] + default_subspecs_specs)
|
198
211
|
|
199
212
|
@build_configuration = spec.root.attributes_hash.dig("pod_target_xcconfig", "prebuild_configuration") || "release"
|
200
213
|
@build_configuration.downcase!
|
201
214
|
|
215
|
+
@remove_module_maps = spec.root.attributes_hash["remove_module_maps"] || []
|
216
|
+
|
202
217
|
default_license = "MIT"
|
203
218
|
@license = spec.root.attributes_hash.fetch("license", {"type"=>"#{default_license}"})["type"] || default_license
|
204
219
|
@summary = spec.root.attributes_hash.fetch("summary", "A summary for #{@name}")
|
@@ -280,14 +295,16 @@ module PodBuilder
|
|
280
295
|
|
281
296
|
root_names = deps.map(&:root_name).uniq
|
282
297
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
298
|
+
unless Configuration.subspecs_to_split.include?(name)
|
299
|
+
# We need to build all other common subspecs to properly build the item
|
300
|
+
# Ex.
|
301
|
+
# PodA depends on DepA/subspec1
|
302
|
+
# PodB depends on DepA/subspec2
|
303
|
+
#
|
304
|
+
# When building PodA we need to build both DepA subspecs because they might
|
305
|
+
# contain different code
|
306
|
+
deps += available_pods.select { |t| root_names.include?(t.root_name) && t.root_name != t.name && !Configuration.subspecs_to_split.include?(t.name) }
|
307
|
+
end
|
291
308
|
|
292
309
|
deps.uniq!
|
293
310
|
|
@@ -390,7 +407,7 @@ module PodBuilder
|
|
390
407
|
|
391
408
|
def prebuilt_rel_path
|
392
409
|
if is_subspec && Configuration.subspecs_to_split.include?(name)
|
393
|
-
return "
|
410
|
+
return "Subspecs/#{podspec_name}/#{module_name}.framework"
|
394
411
|
else
|
395
412
|
return "#{module_name}.framework"
|
396
413
|
end
|
@@ -408,11 +425,7 @@ module PodBuilder
|
|
408
425
|
def prebuilt_entry(include_pb_entry = true, absolute_path = false)
|
409
426
|
podspec_dirname = File.dirname(prebuilt_podspec_path(absolute_path = absolute_path))
|
410
427
|
|
411
|
-
|
412
|
-
entry = "pod '#{podspec_name}', :path => '#{podspec_dirname}'"
|
413
|
-
else
|
414
|
-
entry = "pod '#{name}', :path => '#{podspec_dirname}'"
|
415
|
-
end
|
428
|
+
entry = "pod '#{name}', :path => '#{podspec_dirname}'"
|
416
429
|
|
417
430
|
if include_pb_entry && !is_prebuilt
|
418
431
|
entry += prebuilt_marker()
|
@@ -518,28 +531,9 @@ module PodBuilder
|
|
518
531
|
end
|
519
532
|
end
|
520
533
|
|
521
|
-
def source_files_from(
|
522
|
-
files =
|
523
|
-
|
524
|
-
|
525
|
-
files = spec.attributes_hash.fetch("source_files", [])
|
526
|
-
source_files = source_files_from_string(files)
|
527
|
-
|
528
|
-
subspec_source_files = []
|
529
|
-
if spec.name == spec.root.name
|
530
|
-
default_podspecs = spec.attributes_hash.fetch("default_subspecs", [])
|
531
|
-
if default_podspecs.is_a? String
|
532
|
-
default_podspecs = [default_podspecs]
|
533
|
-
end
|
534
|
-
default_podspecs.each do |subspec_name|
|
535
|
-
if subspec = spec.subspecs.detect { |x| x.name == "#{spec.root.name}/#{subspec_name}" }
|
536
|
-
files = subspec.attributes_hash.fetch("source_files", [])
|
537
|
-
subspec_source_files += source_files_from_string(files)
|
538
|
-
end
|
539
|
-
end
|
540
|
-
end
|
541
|
-
|
542
|
-
return source_files + root_source_files + subspec_source_files
|
534
|
+
def source_files_from(specs)
|
535
|
+
files = specs.map { |t| t.attributes_hash.fetch("source_files", []) }.flatten
|
536
|
+
return source_files_from_string(files).uniq
|
543
537
|
end
|
544
538
|
end
|
545
539
|
end
|
data/lib/pod_builder/podspec.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
module PodBuilder
|
5
5
|
class Podspec
|
6
|
-
def self.generate(all_buildable_items, analyzer)
|
6
|
+
def self.generate(all_buildable_items, analyzer, install_using_frameworks)
|
7
7
|
unless all_buildable_items.count > 0
|
8
8
|
return
|
9
9
|
end
|
@@ -11,12 +11,12 @@ module PodBuilder
|
|
11
11
|
puts "Generating PodBuilder's local podspec".yellow
|
12
12
|
|
13
13
|
platform = analyzer.instance_variable_get("@result").targets.first.platform
|
14
|
-
generate_podspec_from(all_buildable_items, platform)
|
14
|
+
generate_podspec_from(all_buildable_items, platform, install_using_frameworks)
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
-
def self.generate_spec_keys_for(item, name, all_buildable_items)
|
19
|
+
def self.generate_spec_keys_for(item, name, all_buildable_items, install_using_frameworks)
|
20
20
|
podspec = ""
|
21
21
|
valid = false
|
22
22
|
|
@@ -24,46 +24,84 @@ module PodBuilder
|
|
24
24
|
indentation = " " * slash_count
|
25
25
|
spec_var = "p#{slash_count}"
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
subspec_prefix = Configuration.subspecs_to_split.include?(item.name) ? "Subspecs/#{item.podspec_name}/" : ""
|
28
|
+
|
29
|
+
if spec_var == "p1" && item.default_subspecs.count > 0
|
30
|
+
podspec += "#{indentation}#{spec_var}.default_subspecs = '#{item.default_subspecs.join("', '")}'\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
if subspec_prefix.length > 0 && Dir["#{PodBuilder::prebuiltpath("#{item.root_name}/#{subspec_prefix}")}/*"].empty?
|
34
|
+
podspec += "#{indentation}#{spec_var}.source_files = '*.splittedspec'\n"
|
35
|
+
elsif item.name == name
|
36
|
+
if_exists = lambda { |t| File.exist?(PodBuilder::prebuiltpath("#{item.root_name}/#{subspec_prefix}#{t}") || "") }
|
37
|
+
|
38
|
+
vendored_frameworks = item.vendored_frameworks
|
39
|
+
if item.default_subspecs.count == 0 && install_using_frameworks
|
40
|
+
vendored_frameworks += ["#{item.module_name}.framework"]
|
41
|
+
end
|
29
42
|
|
30
|
-
vendored_frameworks = item.vendored_frameworks + ["#{item.module_name}.framework"]
|
31
43
|
existing_vendored_frameworks = vendored_frameworks.select(&if_exists)
|
32
44
|
existing_vendored_frameworks_basename = vendored_frameworks.map { |t| File.basename(t) }.select(&if_exists)
|
33
45
|
vendored_frameworks = (existing_vendored_frameworks + existing_vendored_frameworks_basename).uniq
|
34
46
|
|
35
47
|
vendored_libraries = item.vendored_libraries
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
if install_using_frameworks
|
49
|
+
existing_vendored_libraries = vendored_libraries.map { |t| "#{item.module_name}/#{t}" }.select(&if_exists)
|
50
|
+
existing_vendored_libraries_basename = vendored_libraries.map { |t| File.basename(t) }.select(&if_exists)
|
51
|
+
vendored_libraries = (existing_vendored_libraries + existing_vendored_libraries_basename).uniq
|
52
|
+
|
53
|
+
# .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)
|
54
|
+
vendored_libraries.reject! { |t| t.end_with?(".a") }
|
55
|
+
|
56
|
+
frameworks = all_buildable_items.select { |t| vendored_frameworks.include?("#{t.module_name}.framework") }.uniq
|
57
|
+
static_frameworks = frameworks.select { |x| x.is_static }
|
58
|
+
|
59
|
+
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
|
60
|
+
|
61
|
+
exclude_files = static_frameworks.map { |x| x.vendored_framework_path.nil? ? nil : "#{x.vendored_framework_path}/Info.plist" }.compact.flatten.uniq
|
62
|
+
public_headers = []
|
63
|
+
else
|
64
|
+
public_headers = Dir.glob(PodBuilder::prebuiltpath("#{item.root_name}/#{item.root_name}/Headers/**/*.h"))
|
65
|
+
vendored_libraries += ["#{item.root_name}/lib#{item.root_name}.a"]
|
66
|
+
vendored_libraries.map! { |t| "#{item.root_name}/#{t}" }.select(&if_exists)
|
67
|
+
|
68
|
+
resources = ["#{item.root_name}/*.{nib,bundle,xcasset,strings,png,jpg,tif,tiff,otf,ttf,ttc,plist,json,caf,wav,p12,momd}"]
|
69
|
+
|
70
|
+
exclude_files = ["*.modulemap"]
|
71
|
+
unless item.swift_version.nil?
|
72
|
+
exclude_files += ["Swift Compatibility Header/*", "*.swiftmodule"]
|
73
|
+
end
|
74
|
+
exclude_files.map! { |t| "#{item.root_name}/#{t}" }
|
75
|
+
end
|
76
|
+
|
77
|
+
entries = lambda { |spec_key, spec_value|
|
78
|
+
key = "#{indentation}#{spec_var}.#{spec_key}"
|
79
|
+
joined_values = spec_value.map { |t| "#{subspec_prefix}#{t}" }.uniq.sort.join("', '")
|
80
|
+
"#{key} = '#{joined_values}'\n"
|
81
|
+
}
|
48
82
|
|
49
83
|
if vendored_frameworks.count > 0
|
50
|
-
podspec += "
|
84
|
+
podspec += entries.call("vendored_frameworks", vendored_frameworks)
|
51
85
|
end
|
52
86
|
if vendored_libraries.count > 0
|
53
|
-
podspec += "
|
87
|
+
podspec += entries.call("vendored_libraries", vendored_libraries)
|
54
88
|
end
|
55
89
|
if item.frameworks.count > 0
|
56
|
-
podspec += "
|
90
|
+
podspec += entries.call("frameworks", item.frameworks)
|
57
91
|
end
|
58
92
|
if item.libraries.count > 0
|
59
|
-
podspec += "
|
93
|
+
podspec += entries.call("libraries", item.libraries)
|
60
94
|
end
|
61
95
|
if resources.count > 0
|
62
|
-
podspec +=
|
96
|
+
podspec += entries.call("resources", resources)
|
63
97
|
end
|
64
98
|
if exclude_files.count > 0
|
65
|
-
podspec +=
|
99
|
+
podspec += entries.call("exclude_files", exclude_files)
|
100
|
+
end
|
101
|
+
if public_headers.count > 0
|
102
|
+
podspec += "#{indentation}#{spec_var}.public_header_files = '#{item.root_name}/Headers/**/*.h'\n"
|
66
103
|
end
|
104
|
+
|
67
105
|
if item.xcconfig.keys.count > 0
|
68
106
|
xcconfig = Hash.new
|
69
107
|
item.xcconfig.each do |k, v|
|
@@ -88,6 +126,21 @@ module PodBuilder
|
|
88
126
|
podspec += "#{indentation}#{spec_var}.xcconfig = #{xcconfig.to_s}\n"
|
89
127
|
end
|
90
128
|
end
|
129
|
+
if !install_using_frameworks && spec_var == "p1"
|
130
|
+
module_path_files = Dir.glob(PodBuilder.prebuiltpath("#{item.root_name}/**/#{item.root_name}.modulemap"))
|
131
|
+
raise "\n\nToo many module maps found for #{item.root_name}".red if module_path_files.count > 1
|
132
|
+
if module_path_file = module_path_files.first
|
133
|
+
rel_path = Pathname.new(PodBuilder::prebuiltpath).relative_path_from(Pathname.new(PodBuilder::project_path("Pods"))).to_s
|
134
|
+
prebuilt_root_var = "#{item.root_name.upcase.gsub("-", "_")}_PREBUILT_ROOT"
|
135
|
+
module_map_rel = module_path_file.gsub(PodBuilder::prebuiltpath("#{item.root_name}/#{item.root_name}/"), "")
|
136
|
+
static_cfg = { prebuilt_root_var => "$(PODS_ROOT)/#{rel_path}",
|
137
|
+
"SWIFT_INCLUDE_PATHS" => "$(inherited) \"$(#{prebuilt_root_var})/#{item.root_name}/#{item.root_name}\"",
|
138
|
+
"OTHER_CFLAGS" => "$(inherited) -fmodule-map-file=\"$(#{prebuilt_root_var})/#{item.root_name}/#{item.root_name}/#{module_map_rel}\"",
|
139
|
+
"OTHER_SWIFT_FLAGS" => "$(inherited) -Xcc -fmodule-map-file=\"$(#{prebuilt_root_var})/#{item.root_name}/#{item.root_name}/#{module_map_rel}\""
|
140
|
+
}
|
141
|
+
podspec += "#{indentation}#{spec_var}.xcconfig = #{static_cfg.to_s}\n"
|
142
|
+
end
|
143
|
+
end
|
91
144
|
|
92
145
|
deps = item.dependency_names.sort
|
93
146
|
if name == item.root_name
|
@@ -103,7 +156,7 @@ module PodBuilder
|
|
103
156
|
end
|
104
157
|
end
|
105
158
|
|
106
|
-
valid = valid || vendored_frameworks.count > 0
|
159
|
+
valid = valid || (install_using_frameworks ? vendored_frameworks.count > 0 : vendored_libraries.count > 0)
|
107
160
|
end
|
108
161
|
|
109
162
|
subspec_names = all_buildable_items.map(&:name).select { |t| t.start_with?("#{name}/") }
|
@@ -117,7 +170,7 @@ module PodBuilder
|
|
117
170
|
podspec += "\n"
|
118
171
|
end
|
119
172
|
|
120
|
-
subspec_keys, subspec_valid = generate_spec_keys_for(subspec_item, subspec, all_buildable_items)
|
173
|
+
subspec_keys, subspec_valid = generate_spec_keys_for(subspec_item, subspec, all_buildable_items, install_using_frameworks)
|
121
174
|
valid = valid || subspec_valid
|
122
175
|
|
123
176
|
if subspec_keys.length > 0
|
@@ -127,10 +180,10 @@ module PodBuilder
|
|
127
180
|
end
|
128
181
|
end
|
129
182
|
|
130
|
-
return podspec, valid
|
183
|
+
return podspec, (valid || Configuration.subspecs_to_split.include?(item.name))
|
131
184
|
end
|
132
185
|
|
133
|
-
def self.generate_podspec_from(all_buildable_items, platform)
|
186
|
+
def self.generate_podspec_from(all_buildable_items, platform, install_using_frameworks)
|
134
187
|
prebuilt_podspec_path = all_buildable_items.map(&:prebuilt_podspec_path)
|
135
188
|
prebuilt_podspec_path.each do |path|
|
136
189
|
if File.exist?(path)
|
@@ -165,7 +218,7 @@ module PodBuilder
|
|
165
218
|
podspec += " p1.#{platform.safe_string_name.downcase}.deployment_target = '#{platform.deployment_target.version}'\n"
|
166
219
|
podspec += "\n"
|
167
220
|
|
168
|
-
main_keys, valid = generate_spec_keys_for(item, item.root_name, all_buildable_items)
|
221
|
+
main_keys, valid = generate_spec_keys_for(item, item.root_name, all_buildable_items, install_using_frameworks)
|
169
222
|
if !valid
|
170
223
|
next
|
171
224
|
end
|
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'fourflusher'
|
4
4
|
require 'colored'
|
5
|
+
require 'pathname'
|
5
6
|
|
6
7
|
module PodBuilder
|
7
|
-
def self.
|
8
|
+
def self.build_for_iosish_platform_framework(sandbox, build_dir, target, device, simulator, configuration, deterministic_build, build_for_apple_silicon)
|
8
9
|
raise "\n\nApple silicon hardware still unsupported since it requires to migrate to xcframeworks".red if build_for_apple_silicon
|
9
10
|
|
10
11
|
dsym_device_folder = File.join(build_dir, "dSYM", device)
|
@@ -15,10 +16,10 @@ module PodBuilder
|
|
15
16
|
deployment_target = target.platform_deployment_target
|
16
17
|
target_label = target.cocoapods_target_label
|
17
18
|
|
18
|
-
xcodebuild(sandbox, target_label, device, deployment_target, configuration, deterministic_build, [])
|
19
|
+
xcodebuild(sandbox, target_label, device, deployment_target, configuration, deterministic_build, [], {})
|
19
20
|
excluded_archs = build_for_apple_silicon ? [] : ["arm64"]
|
20
|
-
xcodebuild(sandbox, target_label, simulator, deployment_target, configuration, deterministic_build, excluded_archs)
|
21
|
-
|
21
|
+
xcodebuild(sandbox, target_label, simulator, deployment_target, configuration, deterministic_build, excluded_archs, {})
|
22
|
+
|
22
23
|
spec_names = target.specs.map { |spec| [spec.root.name, spec.root.module_name] }.uniq
|
23
24
|
spec_names.each do |root_name, module_name|
|
24
25
|
device_base = "#{build_dir}/#{configuration}-#{device}/#{root_name}"
|
@@ -47,37 +48,148 @@ module PodBuilder
|
|
47
48
|
|
48
49
|
raise "Lipo failed on #{device_lib}" unless system("xcrun lipo -create -output #{device_lib} #{device_lib} #{simulator_lib}")
|
49
50
|
|
50
|
-
|
51
|
-
if File.exist?(device_swift_header_path) && File.exist?(simulator_swift_header_path)
|
52
|
-
device_content = File.read(device_swift_header_path)
|
53
|
-
simulator_content = File.read(simulator_swift_header_path)
|
54
|
-
merged_content = %{
|
55
|
-
#if TARGET_OS_SIMULATOR
|
56
|
-
#{simulator_content}
|
57
|
-
#else
|
58
|
-
#{device_content}
|
59
|
-
#endif
|
60
|
-
}
|
61
|
-
File.write(device_swift_header_path, merged_content)
|
62
|
-
end
|
51
|
+
merge_header_into(device_swift_header_path, simulator_swift_header_path)
|
63
52
|
|
64
53
|
# Merge device framework into simulator framework (so that e.g swift Module folder is merged)
|
65
54
|
# letting device framework files overwrite simulator ones
|
66
55
|
FileUtils.cp_r(File.join(device_framework_lib, "."), simulator_framework_lib)
|
67
56
|
source_lib = File.dirname(simulator_framework_lib)
|
68
57
|
|
69
|
-
FileUtils.
|
58
|
+
FileUtils.mv(device_dsym, dsym_device_folder) if File.exist?(device_dsym)
|
59
|
+
FileUtils.mv(simulator_dsym, dsym_simulator_folder) if File.exist?(simulator_dsym)
|
70
60
|
|
71
|
-
FileUtils.
|
72
|
-
FileUtils.cp_r(simulator_dsym, dsym_simulator_folder) if File.exist?(simulator_dsym)
|
61
|
+
FileUtils.mv(source_lib, build_dir)
|
73
62
|
|
74
63
|
# Remove frameworks leaving dSYMs
|
75
64
|
FileUtils.rm_rf(device_framework_lib)
|
76
65
|
FileUtils.rm_rf(simulator_framework_lib)
|
77
66
|
end
|
78
67
|
end
|
68
|
+
|
69
|
+
def self.build_for_iosish_platform_lib(sandbox, build_dir, target, device, simulator, configuration, deterministic_build, build_for_apple_silicon, prebuilt_root_paths)
|
70
|
+
raise "\n\nApple silicon hardware still unsupported since it requires to migrate to xcframeworks".red if build_for_apple_silicon
|
71
|
+
|
72
|
+
deployment_target = target.platform_deployment_target
|
73
|
+
target_label = target.cocoapods_target_label
|
74
|
+
|
75
|
+
spec_names = target.specs.map { |spec| [spec.root.name, spec.root.module_name] }.uniq
|
76
|
+
|
77
|
+
xcodebuild(sandbox, target_label, device, deployment_target, configuration, deterministic_build, [], prebuilt_root_paths)
|
78
|
+
excluded_archs = build_for_apple_silicon ? [] : ["arm64"]
|
79
|
+
xcodebuild(sandbox, target_label, simulator, deployment_target, configuration, deterministic_build, excluded_archs, prebuilt_root_paths)
|
80
|
+
|
81
|
+
spec_names.each do |root_name, module_name|
|
82
|
+
simulator_base = "#{build_dir}/#{configuration}-#{simulator}/#{root_name}"
|
83
|
+
simulator_lib = "#{simulator_base}/lib#{module_name}.a"
|
84
|
+
|
85
|
+
device_base = "#{build_dir}/#{configuration}-#{device}/#{root_name}"
|
86
|
+
device_lib = "#{device_base}/lib#{root_name}.a"
|
79
87
|
|
80
|
-
|
88
|
+
if File.file?(device_lib) && File.file?(simulator_lib)
|
89
|
+
# Starting with Xcode 12b3 the simulator binary contains an arm64 slice as well which conflict with the one in the device_lib
|
90
|
+
# when creating the fat library. A naive workaround is to remove the arm64 from the simulator_lib however this is wrong because
|
91
|
+
# we might actually need to have 2 separated arm64 slices, one for simulator and one for device each built with different
|
92
|
+
# compile time directives (e.g #if targetEnvironment(simulator))
|
93
|
+
#
|
94
|
+
# For the time being we remove the arm64 slice bacause otherwise the `xcrun lipo -create -output ...` would fail.
|
95
|
+
if `xcrun lipo -info #{simulator_lib}`.include?("arm64")
|
96
|
+
`xcrun lipo -remove arm64 #{simulator_lib} -o #{simulator_lib}`
|
97
|
+
end
|
98
|
+
|
99
|
+
raise "Lipo failed on #{device_lib}" unless system("xcrun lipo -create -output #{device_lib} #{device_lib} #{simulator_lib}")
|
100
|
+
end
|
101
|
+
|
102
|
+
device_headers = Dir.glob("#{device_base}/**/*.h")
|
103
|
+
simulator_headers = Dir.glob("#{simulator_base}/**/*.h")
|
104
|
+
device_headers.each do |device_path|
|
105
|
+
simulator_path = device_path.gsub(device_base, simulator_base)
|
106
|
+
|
107
|
+
merge_header_into(device_path, simulator_path)
|
108
|
+
end
|
109
|
+
simulator_only_headers = simulator_headers - device_headers.map { |t| t.gsub(device_base, simulator_base) }
|
110
|
+
simulator_only_headers.each do |path|
|
111
|
+
add_simulator_conditional(path)
|
112
|
+
dir_name = File.dirname(path)
|
113
|
+
destination_folder = dir_name.gsub(simulator_base, device_base)
|
114
|
+
FileUtils.mkdir_p(destination_folder)
|
115
|
+
FileUtils.cp(path, destination_folder)
|
116
|
+
end
|
117
|
+
|
118
|
+
swiftmodule_path = "#{simulator_base}/#{root_name}.swiftmodule"
|
119
|
+
if File.directory?(swiftmodule_path)
|
120
|
+
FileUtils.cp_r("#{swiftmodule_path}/.", "#{device_base}/#{root_name}.swiftmodule")
|
121
|
+
end
|
122
|
+
|
123
|
+
if File.exist?("#{device_base}/#{root_name}.swiftmodule")
|
124
|
+
# This is a swift pod with a swiftmodule in the root of the prebuilt folder
|
125
|
+
else
|
126
|
+
# Objective-C pods have the swiftmodule generated under Pods/Headers/Public
|
127
|
+
public_headers_path = "#{Configuration.build_path}/Pods/Headers/Public/#{root_name}"
|
128
|
+
module_public_headers_path = "#{Configuration.build_path}/Pods/Headers/Public/#{module_name}"
|
129
|
+
if public_headers_path.downcase != module_public_headers_path.downcase && File.directory?(public_headers_path) && File.directory?(module_public_headers_path)
|
130
|
+
# For pods with module_name != name we have to move the modulemap files to the root_name one
|
131
|
+
module_public_headers_path = "#{Configuration.build_path}/Pods/Headers/Public/#{module_name}"
|
132
|
+
FileUtils.cp_r("#{module_public_headers_path}/.", public_headers_path)
|
133
|
+
end
|
134
|
+
Dir.glob("#{public_headers_path}/**/*.*").each do |path|
|
135
|
+
destination_folder = "#{device_base}/Headers" + path.gsub(public_headers_path, "")
|
136
|
+
destination_folder = File.dirname(destination_folder)
|
137
|
+
FileUtils.mkdir_p(destination_folder)
|
138
|
+
FileUtils.cp(path, destination_folder)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
destination_path = "#{build_dir}/#{root_name}"
|
143
|
+
if Dir.glob("#{device_base}/**/*.{a,framework,h}").count > 0
|
144
|
+
FileUtils.mv(device_base, destination_path)
|
145
|
+
|
146
|
+
module_maps = Dir.glob("#{destination_path}/**/*.modulemap")
|
147
|
+
module_map_device_base = device_base.gsub(/^\/private/, "") + "/"
|
148
|
+
module_maps.each do |module_map|
|
149
|
+
content = File.read(module_map)
|
150
|
+
content.gsub!(module_map_device_base, "")
|
151
|
+
File.write(module_map, content)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.merge_header_into(device_file, simulator_file)
|
158
|
+
unless File.exist?(device_file) || File.exist?(simulator_file)
|
159
|
+
return
|
160
|
+
end
|
161
|
+
|
162
|
+
device_content = File.file?(device_file) ? File.read(device_file) : ""
|
163
|
+
simulator_content = File.file?(simulator_file) ? File.read(simulator_file) : ""
|
164
|
+
merged_content = %{
|
165
|
+
#if TARGET_OS_SIMULATOR
|
166
|
+
// ->
|
167
|
+
|
168
|
+
#{simulator_content}
|
169
|
+
|
170
|
+
// ->
|
171
|
+
#else
|
172
|
+
// ->
|
173
|
+
|
174
|
+
#{device_content}
|
175
|
+
|
176
|
+
// ->
|
177
|
+
#endif
|
178
|
+
}
|
179
|
+
File.write(device_file, merged_content)
|
180
|
+
end
|
181
|
+
|
182
|
+
def self.add_simulator_conditional(path)
|
183
|
+
file_content = File.read(path)
|
184
|
+
content = %{
|
185
|
+
#if TARGET_OS_SIMULATOR
|
186
|
+
#{file_content}
|
187
|
+
#endif
|
188
|
+
}
|
189
|
+
File.write(path, content)
|
190
|
+
end
|
191
|
+
|
192
|
+
def self.xcodebuild(sandbox, target, sdk='macosx', deployment_target=nil, configuration, deterministic_build, exclude_archs, prebuilt_root_paths)
|
81
193
|
args = %W(-project #{sandbox.project_path.realdirpath} -scheme #{target} -configuration #{configuration} -sdk #{sdk})
|
82
194
|
supported_platforms = { 'iphonesimulator' => 'iOS', 'appletvsimulator' => 'tvOS', 'watchsimulator' => 'watchOS' }
|
83
195
|
if platform = supported_platforms[sdk]
|
@@ -88,6 +200,9 @@ module PodBuilder
|
|
88
200
|
if exclude_archs.count > 0 && xcodebuild_version >= 12.0
|
89
201
|
args += ["EXCLUDED_ARCHS=#{exclude_archs.join(" ")}"]
|
90
202
|
end
|
203
|
+
prebuilt_root_paths.each do |k, v|
|
204
|
+
args += ["#{k.upcase.gsub("-", "_")}_PREBUILT_ROOT=#{v.gsub(/ /, '\ ')}"]
|
205
|
+
end
|
91
206
|
|
92
207
|
environmental_variables = {}
|
93
208
|
if deterministic_build
|
@@ -148,16 +263,17 @@ module PodBuilder
|
|
148
263
|
end
|
149
264
|
project.save
|
150
265
|
end
|
151
|
-
|
152
|
-
|
153
266
|
end
|
154
267
|
|
155
268
|
Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_context, user_options|
|
156
269
|
enable_dsym = user_options.fetch('dsym', true)
|
157
270
|
configuration = user_options.fetch('configuration', 'Debug')
|
271
|
+
uses_frameworks = user_options.fetch('uses_frameworks', true)
|
158
272
|
if user_options["pre_compile"]
|
159
273
|
user_options["pre_compile"].call(installer_context)
|
160
274
|
end
|
275
|
+
|
276
|
+
prebuilt_root_paths = JSON.parse(user_options["prebuilt_root_paths"].gsub('=>', ':'))
|
161
277
|
|
162
278
|
sandbox_root = Pathname(installer_context.sandbox_root)
|
163
279
|
sandbox = Pod::Sandbox.new(sandbox_root)
|
@@ -170,17 +286,22 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
|
|
170
286
|
build_dir.rmtree if build_dir.directory?
|
171
287
|
targets = installer_context.umbrella_targets.select { |t| t.specs.any? }
|
172
288
|
targets.each do |target|
|
173
|
-
case target.platform_name
|
174
|
-
when :ios then PodBuilder::
|
175
|
-
when :osx then PodBuilder::xcodebuild(sandbox, target.cocoapods_target_label, configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon)
|
176
|
-
when :tvos then PodBuilder::
|
177
|
-
when :watchos then PodBuilder::
|
289
|
+
case [target.platform_name, uses_frameworks]
|
290
|
+
when [:ios, true] then PodBuilder::build_for_iosish_platform_framework(sandbox, build_dir, target, 'iphoneos', 'iphonesimulator', configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon)
|
291
|
+
when [:osx, true] then PodBuilder::xcodebuild(sandbox, target.cocoapods_target_label, configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon, {})
|
292
|
+
when [:tvos, true] then PodBuilder::build_for_iosish_platform_framework(sandbox, build_dir, target, 'appletvos', 'appletvsimulator', configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon)
|
293
|
+
when [:watchos, true] then PodBuilder::build_for_iosish_platform_framework(sandbox, build_dir, target, 'watchos', 'watchsimulator', configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon)
|
294
|
+
when [:ios, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'iphoneos', 'iphonesimulator', configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon, prebuilt_root_paths)
|
295
|
+
when [:osx, false] then PodBuilder::xcodebuild(sandbox, target.cocoapods_target_label, configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon, prebuilt_root_paths)
|
296
|
+
when [:tvos, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'appletvos', 'appletvsimulator', configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon, prebuilt_root_paths)
|
297
|
+
when [:watchos, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'watchos', 'watchsimulator', configuration, PodBuilder::Configuration.deterministic_build, PodBuilder::Configuration.build_for_apple_silicon, prebuilt_root_paths)
|
178
298
|
else raise "\n\nUnknown platform '#{target.platform_name}'".red end
|
179
|
-
end
|
180
|
-
|
299
|
+
end
|
300
|
+
|
181
301
|
raise Pod::Informative, 'The build directory was not found in the expected location.' unless build_dir.directory?
|
182
302
|
|
183
|
-
|
303
|
+
specs = installer_context.umbrella_targets.map { |t| t.specs.map(&:name) }.flatten.map { |t| t.split("/").first }.uniq
|
304
|
+
built_count = Dir["#{build_dir}/*"].select { |t| specs.include?(File.basename(t)) }.count
|
184
305
|
Pod::UI.puts "Built #{built_count} #{'items'.pluralize(built_count)}, copying..."
|
185
306
|
|
186
307
|
base_destination.rmtree if base_destination.directory?
|
@@ -188,20 +309,23 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
|
|
188
309
|
installer_context.umbrella_targets.each do |umbrella|
|
189
310
|
umbrella.specs.each do |spec|
|
190
311
|
root_name = spec.name.split("/").first
|
312
|
+
|
313
|
+
if uses_frameworks
|
314
|
+
destination = File.join(base_destination, root_name)
|
315
|
+
else
|
316
|
+
destination = File.join(base_destination, root_name, root_name)
|
317
|
+
end
|
191
318
|
# Make sure the device target overwrites anything in the simulator build, otherwise iTunesConnect
|
192
319
|
# can get upset about Info.plist containing references to the simulator SDK
|
193
|
-
|
194
|
-
|
320
|
+
files = Pathname.glob("build/#{root_name}/*").reject { |f| f.to_s =~ /Pods[^.]+\.framework/ }
|
321
|
+
|
195
322
|
consumer = spec.consumer(umbrella.platform_name)
|
196
323
|
file_accessor = Pod::Sandbox::FileAccessor.new(sandbox.pod_dir(spec.root.name), consumer)
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
FileUtils.mkdir_p(destination)
|
203
|
-
|
204
|
-
files = frameworks + resources
|
324
|
+
files += file_accessor.vendored_libraries
|
325
|
+
files += file_accessor.vendored_frameworks
|
326
|
+
files += file_accessor.resources
|
327
|
+
|
328
|
+
FileUtils.mkdir_p(destination)
|
205
329
|
files.each do |file|
|
206
330
|
FileUtils.cp_r(file, destination)
|
207
331
|
end
|
@@ -226,7 +350,10 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
|
|
226
350
|
end
|
227
351
|
|
228
352
|
if enable_dsym
|
229
|
-
|
353
|
+
dsym_source = "#{build_dir}/dSYM"
|
354
|
+
if File.directory?(dsym_source)
|
355
|
+
FileUtils.mv(dsym_source, sandbox_root.parent)
|
356
|
+
end
|
230
357
|
else
|
231
358
|
raise "Not implemented"
|
232
359
|
end
|