pod-builder 2.0.0 → 2.1.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 +4 -4
- data/README.md +5 -5
- data/lib/pod_builder/analyze.rb +2 -22
- data/lib/pod_builder/command/build.rb +3 -7
- data/lib/pod_builder/command/generate_lldbinit.rb +83 -106
- data/lib/pod_builder/configuration.rb +9 -9
- data/lib/pod_builder/podfile.rb +6 -10
- data/lib/pod_builder/podfile/pre_actions_swizzles.rb +84 -0
- data/lib/pod_builder/podfile_item.rb +0 -18
- data/lib/pod_builder/podspec.rb +28 -11
- data/lib/pod_builder/rome/post_install.rb +123 -69
- data/lib/pod_builder/templates/build_podfile.template +1 -1
- data/lib/pod_builder/version.rb +1 -1
- metadata +3 -3
- data/lib/pod_builder/podfile/post_actions.rb +0 -136
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce4c05c8ce4048a574a1d3d203275ace997c07064e06ba99c0cec91cba1dae2f
|
|
4
|
+
data.tar.gz: 91fdbc0904546a7556f5da861a021f597f68be581dfb8b1e82a31759d4a1a949
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 64dab7229f6a12530a193d9a96b03f85ef906a67e66419670a554b2a26883b538479e1f822aec0e970af3c26f1547f400e3465588e62f889dab535771160def8
|
|
7
|
+
data.tar.gz: aff61128539d61e3811983f60c19a4020311b285dcb8f8c29cc20acdc57116820fac2041424c70ddb6d98f235f1bfcffd65fc303b7655e432d662ec33aec5f3a
|
data/README.md
CHANGED
|
@@ -280,9 +280,13 @@ Like `build_settings` but per pod. Pod name can also refer to subspec.
|
|
|
280
280
|
|
|
281
281
|
Specify which build system to use to compile frameworks. Either `Legacy` (standard build system) or `Latest` (new build system). Default value: `Latest`.
|
|
282
282
|
|
|
283
|
+
#### `build_xcframeworks`
|
|
284
|
+
|
|
285
|
+
Specify if PodBuilder will build .xcframeworks. Will enable `library_evolution_support`. Default value: false
|
|
286
|
+
|
|
283
287
|
#### `library_evolution_support`
|
|
284
288
|
|
|
285
|
-
Specify if Swift frameworks should be compiled with library evolution support (BUILD_LIBRARY_FOR_DISTRIBUTION).
|
|
289
|
+
Specify if Swift frameworks should be compiled with library evolution support (BUILD_LIBRARY_FOR_DISTRIBUTION). Default value: false
|
|
286
290
|
|
|
287
291
|
#### `license_filename`
|
|
288
292
|
|
|
@@ -310,10 +314,6 @@ PodBuilder writes a plist and markdown license files of pods specified in the Po
|
|
|
310
314
|
|
|
311
315
|
If you use bundler to pin the version of CocoaPods in your project set this to true. Default false.
|
|
312
316
|
|
|
313
|
-
#### `build_for_apple_silicon`
|
|
314
|
-
|
|
315
|
-
If set to true built frameworks will include iPhone simulator slices for Apple silicon based hardware. Default false.
|
|
316
|
-
|
|
317
317
|
|
|
318
318
|
# Behind the scenes
|
|
319
319
|
|
data/lib/pod_builder/analyze.rb
CHANGED
|
@@ -52,28 +52,8 @@ module PodBuilder
|
|
|
52
52
|
all_specs = analysis_result.specifications
|
|
53
53
|
|
|
54
54
|
supported_platforms = analyzer.instance_variable_get("@result").targets.map { |t| t.platform.safe_string_name.downcase }
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
names = analyzer.explicit_pods().map(&:name)
|
|
58
|
-
|
|
59
|
-
podfile_pods = []
|
|
60
|
-
last_count = -1
|
|
61
|
-
while podfile_pods.count != last_count do
|
|
62
|
-
last_count = podfile_pods.count
|
|
63
|
-
|
|
64
|
-
updated_names = []
|
|
65
|
-
names.each do |name|
|
|
66
|
-
if pod = all_podfile_items.detect { |t| t.name == name }
|
|
67
|
-
podfile_pods.push(pod)
|
|
68
|
-
updated_names += pod.dependency_names
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
names = updated_names.uniq
|
|
73
|
-
podfile_pods.uniq!
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
return podfile_pods.sort_by(&:name)
|
|
55
|
+
|
|
56
|
+
return all_specs.map { |spec| PodfileItem.new(spec, all_specs, checkout_options, supported_platforms) }.sort_by(&:name)
|
|
77
57
|
end
|
|
78
58
|
end
|
|
79
59
|
end
|
|
@@ -60,10 +60,6 @@ module PodBuilder
|
|
|
60
60
|
|
|
61
61
|
check_not_building_development_pods(pods_to_build)
|
|
62
62
|
|
|
63
|
-
# Remove dependencies from pods to build
|
|
64
|
-
all_dependencies_name = pods_to_build.map(&:dependency_names).flatten.uniq
|
|
65
|
-
pods_to_build.select! { |x| !all_dependencies_name.include?(x.name) }
|
|
66
|
-
|
|
67
63
|
pods_to_build_debug = pods_to_build.select { |x| x.build_configuration == "debug" }
|
|
68
64
|
pods_to_build_release = pods_to_build - pods_to_build_debug
|
|
69
65
|
|
|
@@ -88,7 +84,7 @@ module PodBuilder
|
|
|
88
84
|
build_configuration = podfile_items.map(&:build_configuration).uniq.first
|
|
89
85
|
|
|
90
86
|
podfile_items = podfile_items.map { |t| t.recursive_dependencies(all_buildable_items) }.flatten.uniq
|
|
91
|
-
podfile_content = Podfile.from_podfile_items(podfile_items, analyzer, build_configuration, install_using_frameworks)
|
|
87
|
+
podfile_content = Podfile.from_podfile_items(podfile_items, analyzer, build_configuration, install_using_frameworks, Configuration.build_xcframeworks)
|
|
92
88
|
|
|
93
89
|
install_result += Install.podfile(podfile_content, podfile_items, podfile_items.first.build_configuration)
|
|
94
90
|
|
|
@@ -187,10 +183,10 @@ module PodBuilder
|
|
|
187
183
|
lines = File.read(PodBuilder::project_path("Podfile")).split("\n")
|
|
188
184
|
stripped_lines = lines.map { |x| Podfile.strip_line(x) }.select { |x| !x.start_with?("#")}
|
|
189
185
|
|
|
190
|
-
expected_stripped = Podfile::
|
|
186
|
+
expected_stripped = Podfile::PRE_INSTALL_ACTIONS.map { |x| Podfile.strip_line(x) }
|
|
191
187
|
|
|
192
188
|
if !expected_stripped.all? { |x| stripped_lines.include?(x) }
|
|
193
|
-
warn_message = "PodBuilder's
|
|
189
|
+
warn_message = "PodBuilder's pre install actions missing from application Podfile!\n"
|
|
194
190
|
if OPTIONS[:allow_warnings]
|
|
195
191
|
puts "\n\n#{warn_message}".yellow
|
|
196
192
|
else
|
|
@@ -9,142 +9,119 @@ module PodBuilder
|
|
|
9
9
|
if Configuration.build_using_repo_paths
|
|
10
10
|
raise "\n\nlldb shenanigans not supported when 'build_using_repo_paths' is enabled".red
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
arguments = ARGV.dup
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
if arguments.count > 0
|
|
16
16
|
source_path = arguments[0]
|
|
17
17
|
if !is_absolute_path(source_path)
|
|
18
18
|
source_path = PodBuilder::basepath(source_path)
|
|
19
19
|
end
|
|
20
20
|
source_path = File.expand_path(source_path)
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
raise "\n\nSpecified path does not exists" unless File.directory?(source_path)
|
|
23
23
|
end
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
base_path = PodBuilder::basepath
|
|
26
|
-
|
|
27
26
|
app_podfile_content = File.read(PodBuilder::project_path("Podfile"))
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
|
|
30
28
|
lldbinit_path = File.expand_path(PodBuilder::basepath(Configuration.lldbinit_name))
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if lldbinit_content.include?("# <pb_md5:#{base_path}:#{podfile_hash}")
|
|
34
|
-
puts "\n\n🎉 already in sync!\n".green
|
|
35
|
-
return 0
|
|
36
|
-
end
|
|
37
|
-
|
|
29
|
+
|
|
38
30
|
puts "Extracting debug information".yellow
|
|
39
31
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
source_map_lines = []
|
|
46
|
-
Dir.glob("#{PodBuilder::prebuiltpath}/**/#{Configuration.prebuilt_info_filename}").each do |path|
|
|
47
|
-
data = JSON.parse(File.read(path))
|
|
48
|
-
next if data.fetch("is_prebuilt", true)
|
|
32
|
+
FileUtils.mkdir_p(Configuration.build_path)
|
|
33
|
+
compilation_base_path = Pathname.new(Configuration.build_path).realpath.to_s
|
|
34
|
+
|
|
35
|
+
pods_mappings = Hash.new
|
|
49
36
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
app_podfile_content.each_line do |line|
|
|
38
|
+
unless (name_match = line.match(/^\s*pod ['|"](.*?)['|"](.*)/)) && name_match.size == 3
|
|
39
|
+
next
|
|
40
|
+
end
|
|
53
41
|
|
|
54
|
-
|
|
55
|
-
podspec_path = "#{File.dirname(path)}/#{podspec_name}.podspec"
|
|
42
|
+
pod_name = name_match[1].split("/").first
|
|
56
43
|
|
|
57
|
-
|
|
44
|
+
source = nil
|
|
45
|
+
destination = PodBuilder::basepath # puts some existing path, see lldbinit_content.reverse! comment
|
|
46
|
+
if (path_match = line.match(/:path\s?=>\s?['|"](.*?)['|"]/)) && path_match.size == 2
|
|
47
|
+
pod_path = path_match[1]
|
|
48
|
+
if !is_absolute_path(pod_path)
|
|
49
|
+
pod_path = File.expand_path("#{base_path}/#{pod_path}")
|
|
50
|
+
end
|
|
58
51
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
is_prebuilt = pod_path.start_with?(PodBuilder::prebuiltpath(pod_name))
|
|
53
|
+
if is_prebuilt
|
|
54
|
+
source = "#{compilation_base_path}/Pods/#{pod_name}"
|
|
55
|
+
destination = PodBuilder::prebuiltpath(pod_name)
|
|
56
|
+
|
|
57
|
+
info_path = "#{pod_path}/#{Configuration.prebuilt_info_filename}"
|
|
58
|
+
next unless File.exists?(info_path)
|
|
59
|
+
data = JSON.parse(File.read(info_path))
|
|
60
|
+
|
|
61
|
+
build_source_path_matches = data["entry"].match(/:path => '(.*?)'/)
|
|
62
|
+
if build_source_path_matches&.size == 2
|
|
63
|
+
build_source_path = build_source_path_matches[1]
|
|
64
|
+
if !is_absolute_path(build_source_path)
|
|
65
|
+
build_source_path = PodBuilder::basepath(build_source_path)
|
|
66
|
+
end
|
|
67
|
+
destination = File.expand_path(build_source_path)
|
|
68
|
+
end
|
|
69
|
+
elsif File.directory?(pod_path)
|
|
70
|
+
source = pod_path
|
|
71
|
+
destination = pod_path
|
|
65
72
|
end
|
|
66
|
-
build_source_path = File.expand_path(build_source_path)
|
|
67
|
-
elsif source_path.nil?
|
|
68
|
-
next
|
|
69
73
|
else
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
pod_path = PodBuilder::project_path("Pods/#{pod_name}")
|
|
75
|
+
if File.directory?(pod_path)
|
|
76
|
+
source = pod_path
|
|
77
|
+
destination = pod_path
|
|
78
|
+
end
|
|
73
79
|
end
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
unless source_map_lines.include?("settings append target.source-map '#{original_compile_path}'")
|
|
78
|
-
source_map_lines.push("# <pb:#{base_path}>\n", "settings append target.source-map '#{original_compile_path}' '#{build_source_path}'\n")
|
|
79
|
-
end
|
|
80
|
+
|
|
81
|
+
if !source.nil? && File.directory?(destination)
|
|
82
|
+
pods_mappings[source] = destination
|
|
80
83
|
end
|
|
81
84
|
end
|
|
82
85
|
|
|
83
|
-
|
|
86
|
+
prebuilt_source_map_entries = []
|
|
87
|
+
other_source_map_entries = []
|
|
88
|
+
pods_mappings.each do |source, destination|
|
|
89
|
+
if source.include?(compilation_base_path)
|
|
90
|
+
prebuilt_source_map_entries.push("settings append target.source-map '#{source}/' '#{destination}/'")
|
|
91
|
+
else
|
|
92
|
+
other_source_map_entries.push("settings append target.source-map '#{source}/' '#{destination}/'")
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# There is a bug/unexpected behavior related to the target.source-map command
|
|
97
|
+
#
|
|
98
|
+
# If I have debug symbols for the following files:
|
|
99
|
+
# /tmp/pod_builder/Pods/SomeName/... which are now under /new/path/SomeName/
|
|
100
|
+
# /tmp/pod_builder/Pods/SomeNameCommon/... which are now under /new/path/SomeNameCommon/
|
|
101
|
+
#
|
|
102
|
+
# adding a remap as follows
|
|
103
|
+
# settings append '/tmp/pod_builder/Pods/SomeName/' '/new/path/SomeName/'
|
|
104
|
+
#
|
|
105
|
+
# causes breakpoints added to files under /new/path/SomeNameCommon/ to be incorrectly added to
|
|
106
|
+
# /tmp/pod_builder/Pods/SomeName/Common/Somefile
|
|
107
|
+
#
|
|
108
|
+
# LLDB evaluates remap in order so to workaround this issue we have to add a remap of
|
|
109
|
+
# /tmp/pod_builder/Pods/SomeNameCommon/ before remapping /tmp/pod_builder/Pods/SomeName/
|
|
110
|
+
# even if the remap isn't needed!
|
|
111
|
+
lldbinit_content = other_source_map_entries.sort.reverse + prebuilt_source_map_entries.sort.reverse
|
|
112
|
+
|
|
113
|
+
lldbinit_content.insert(0, "settings clear target.source-map\n")
|
|
114
|
+
|
|
115
|
+
File.write(lldbinit_path, lldbinit_content.join("\n"))
|
|
84
116
|
|
|
85
117
|
puts "\n\n🎉 done!\n".green
|
|
86
118
|
return 0
|
|
87
119
|
end
|
|
88
|
-
|
|
120
|
+
|
|
89
121
|
private
|
|
90
|
-
|
|
91
|
-
def self.is_absolute_path(path)
|
|
92
|
-
return ["~", "/"].any? { |t| t.start_with?(t) }
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def self.is_prebuilt_pod(podspec_path, app_podfile_content)
|
|
96
|
-
development_path = Pathname.new(podspec_path).relative_path_from(Pathname.new(PodBuilder::project_path)).parent.to_s
|
|
97
|
-
|
|
98
|
-
return app_podfile_content.include?(":path => '#{development_path}'")
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def self.rewrite_lldinit(lldbinit_path, source_map_lines, base_path, podfile_hash)
|
|
102
|
-
puts "Writing #{lldbinit_path}".yellow
|
|
103
|
-
|
|
104
|
-
FileUtils.touch(lldbinit_path)
|
|
105
|
-
raise "\n\nDestination file should be a file".red unless File.exist?(lldbinit_path)
|
|
106
|
-
|
|
107
|
-
lldbinit_lines = []
|
|
108
|
-
skipNext = false
|
|
109
|
-
File.read(lldbinit_path).each_line do |line|
|
|
110
|
-
if line.include?("# <pb:#{base_path}>") || line.include?("# <pb>")
|
|
111
|
-
skipNext = true
|
|
112
|
-
next
|
|
113
|
-
elsif skipNext
|
|
114
|
-
skipNext = false
|
|
115
|
-
next
|
|
116
|
-
elsif line != "\n"
|
|
117
|
-
if line.include?("settings set target.source-map")
|
|
118
|
-
raise "\n\n#{lldbinit_destination_path} already includes a manual `settings set target.source-map`. This is unsupported and you'll have to manually remove that entry\n".red
|
|
119
|
-
end
|
|
120
|
-
lldbinit_lines.push(line)
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
source_map_lines.insert(0, "# <pb>\n")
|
|
125
|
-
source_map_lines.insert(1, "settings clear target.source-map\n")
|
|
126
|
-
source_map_lines.insert(2, "# <pb:#{base_path}>\n")
|
|
127
|
-
source_map_lines.insert(3, "# <pb_md5:#{base_path}:#{podfile_hash}>\n")
|
|
128
|
-
|
|
129
|
-
lldbinit_lines += source_map_lines
|
|
130
122
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
def self.find_podspec_path_for(name, podspec_paths, podspec_contents)
|
|
135
|
-
if (path = podspec_paths.detect { |t| File.basename(t, ".podspec") == name.gsub("_", "-") })
|
|
136
|
-
return path
|
|
137
|
-
elsif (path_index = podspec_contents.find_index { |t| t.include?(".module_name='#{name}'") })
|
|
138
|
-
return podspec_paths[path_index]
|
|
139
|
-
elsif (path_index = podspec_contents.find_index { |t| t.include?(".name='#{name}") }) # kind of optimistic,, but a last resort
|
|
140
|
-
return podspec_paths[path_index]
|
|
141
|
-
elsif (path_index = podspec_contents.find_index { |t| t.include?("'module_name':'#{name}'") }) # [json podspec]
|
|
142
|
-
return podspec_paths[path_index]
|
|
143
|
-
elsif (path_index = podspec_contents.find_index { |t| t.include?("'name':'#{name}") }) # [json podspec] kind of optimistic,, but a last resort
|
|
144
|
-
return podspec_paths[path_index]
|
|
145
|
-
else
|
|
146
|
-
return nil
|
|
147
|
-
end
|
|
123
|
+
def self.is_absolute_path(path)
|
|
124
|
+
return ["~", "/"].any? { |t| path.start_with?(t) }
|
|
148
125
|
end
|
|
149
126
|
end
|
|
150
127
|
end
|
|
@@ -45,8 +45,8 @@ module PodBuilder
|
|
|
45
45
|
DEFAULT_BUILD_SYSTEM = "Latest".freeze # either Latest (New build system) or Legacy (Standard build system)
|
|
46
46
|
DEFAULT_LIBRARY_EVOLUTION_SUPPORT = false
|
|
47
47
|
DEFAULT_PLATFORMS = ["iphoneos", "iphonesimulator", "appletvos", "appletvsimulator"].freeze
|
|
48
|
-
DEFAULT_BUILD_FOR_APPLE_SILICON = false
|
|
49
48
|
DEFAULT_BUILD_USING_REPO_PATHS = false
|
|
49
|
+
DEFAULT_BUILD_XCFRAMEWORKS = false
|
|
50
50
|
|
|
51
51
|
private_constant :DEFAULT_BUILD_SETTINGS
|
|
52
52
|
private_constant :DEFAULT_BUILD_SETTINGS_OVERRIDES
|
|
@@ -78,10 +78,10 @@ module PodBuilder
|
|
|
78
78
|
attr_accessor :use_bundler
|
|
79
79
|
attr_accessor :deterministic_build
|
|
80
80
|
attr_accessor :supported_platforms
|
|
81
|
-
attr_accessor :build_for_apple_silicon
|
|
82
81
|
attr_accessor :build_using_repo_paths
|
|
83
82
|
attr_accessor :react_native_project
|
|
84
83
|
attr_accessor :lldbinit_name
|
|
84
|
+
attr_accessor :build_xcframeworks
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
@allow_building_development_pods = false
|
|
@@ -111,9 +111,10 @@ module PodBuilder
|
|
|
111
111
|
@deterministic_build = false
|
|
112
112
|
|
|
113
113
|
@supported_platforms = DEFAULT_PLATFORMS
|
|
114
|
-
@build_for_apple_silicon = DEFAULT_BUILD_FOR_APPLE_SILICON
|
|
115
114
|
@build_using_repo_paths = DEFAULT_BUILD_USING_REPO_PATHS
|
|
116
115
|
@react_native_project = false
|
|
116
|
+
|
|
117
|
+
@build_xcframeworks = DEFAULT_BUILD_XCFRAMEWORKS
|
|
117
118
|
|
|
118
119
|
def self.check_inited
|
|
119
120
|
raise "\n\nNot inited, run `pod_builder init`\n".red if podbuilder_path.nil?
|
|
@@ -207,11 +208,6 @@ module PodBuilder
|
|
|
207
208
|
Configuration.deterministic_build = value
|
|
208
209
|
end
|
|
209
210
|
end
|
|
210
|
-
if value = json["build_for_apple_silicon"]
|
|
211
|
-
if [TrueClass, FalseClass].include?(value.class)
|
|
212
|
-
Configuration.build_for_apple_silicon = value
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
211
|
if value = json["build_using_repo_paths"]
|
|
216
212
|
if [TrueClass, FalseClass].include?(value.class)
|
|
217
213
|
Configuration.build_using_repo_paths = value
|
|
@@ -222,6 +218,11 @@ module PodBuilder
|
|
|
222
218
|
Configuration.react_native_project = value
|
|
223
219
|
end
|
|
224
220
|
end
|
|
221
|
+
if value = json["build_xcframeworks"]
|
|
222
|
+
if [TrueClass, FalseClass].include?(value.class)
|
|
223
|
+
Configuration.build_xcframeworks = value
|
|
224
|
+
end
|
|
225
|
+
end
|
|
225
226
|
|
|
226
227
|
Configuration.build_settings.freeze
|
|
227
228
|
|
|
@@ -264,7 +265,6 @@ module PodBuilder
|
|
|
264
265
|
config["allow_building_development_pods"] = Configuration.allow_building_development_pods
|
|
265
266
|
config["use_bundler"] = Configuration.use_bundler
|
|
266
267
|
config["deterministic_build"] = Configuration.deterministic_build
|
|
267
|
-
config["build_for_apple_silicon"] = Configuration.build_for_apple_silicon
|
|
268
268
|
config["build_using_repo_paths"] = Configuration.build_using_repo_paths
|
|
269
269
|
config["react_native_project"] = Configuration.react_native_project
|
|
270
270
|
|
data/lib/pod_builder/podfile.rb
CHANGED
|
@@ -2,12 +2,10 @@ require 'json'
|
|
|
2
2
|
module PodBuilder
|
|
3
3
|
class Podfile
|
|
4
4
|
PODBUILDER_LOCK_ACTION = ["raise \"\\n🚨 Do not launch 'pod install' manually, use `pod_builder` instead!\\n\" if !File.exist?('pod_builder.lock')"].freeze
|
|
5
|
-
POST_INSTALL_ACTIONS = ["require 'pod_builder/podfile/post_actions'", "PodBuilder::Podfile::pod_builder_post_process"].freeze
|
|
6
5
|
|
|
7
|
-
PRE_INSTALL_ACTIONS = ["Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_duplicate_framework_and_library_names) {}"].freeze
|
|
8
|
-
private_constant :PRE_INSTALL_ACTIONS
|
|
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
|
|
9
7
|
|
|
10
|
-
def self.from_podfile_items(items, analyzer, build_configuration, install_using_frameworks)
|
|
8
|
+
def self.from_podfile_items(items, analyzer, build_configuration, install_using_frameworks, build_xcframeworks)
|
|
11
9
|
raise "\n\nno items".red unless items.count > 0
|
|
12
10
|
|
|
13
11
|
sources = analyzer.sources
|
|
@@ -19,6 +17,7 @@ module PodBuilder
|
|
|
19
17
|
|
|
20
18
|
podfile.sub!("%%%use_frameworks%%%", install_using_frameworks ? "use_frameworks!" : "use_modular_headers!")
|
|
21
19
|
podfile.sub!("%%%uses_frameworks%%%", install_using_frameworks ? "true" : "false")
|
|
20
|
+
podfile.sub!("%%%build_xcframeworks%%%", build_xcframeworks ? "true" : "false")
|
|
22
21
|
|
|
23
22
|
podfile.sub!("%%%platform_name%%%", platform.name.to_s)
|
|
24
23
|
podfile.sub!("%%%deployment_version%%%", platform.deployment_target.version)
|
|
@@ -61,6 +60,9 @@ module PodBuilder
|
|
|
61
60
|
elsif Configuration.library_evolution_support
|
|
62
61
|
build_settings["BUILD_LIBRARY_FOR_DISTRIBUTION"] = "YES"
|
|
63
62
|
end
|
|
63
|
+
if Configuration.build_xcframeworks
|
|
64
|
+
build_settings["BUILD_LIBRARY_FOR_DISTRIBUTION"] = "YES"
|
|
65
|
+
end
|
|
64
66
|
|
|
65
67
|
build_settings["SWIFT_VERSION"] = item_build_settings["SWIFT_VERSION"] || item.swift_version || project_swift_version(analyzer)
|
|
66
68
|
|
|
@@ -229,7 +231,6 @@ module PodBuilder
|
|
|
229
231
|
podfile_content = Podfile.update_require_entries(podfile_content, Podfile.method(:podfile_path_transform))
|
|
230
232
|
|
|
231
233
|
podfile_content = add_pre_install_actions(podfile_content)
|
|
232
|
-
podfile_content = add_post_install_checks(podfile_content)
|
|
233
234
|
|
|
234
235
|
project_podfile_path = PodBuilder::project_path("Podfile")
|
|
235
236
|
File.write(project_podfile_path, podfile_content)
|
|
@@ -249,7 +250,6 @@ module PodBuilder
|
|
|
249
250
|
podfile_content = Podfile.update_require_entries(podfile_content, Podfile.method(:podfile_path_transform))
|
|
250
251
|
|
|
251
252
|
podfile_content = add_pre_install_actions(podfile_content)
|
|
252
|
-
podfile_content = add_post_install_checks(podfile_content)
|
|
253
253
|
|
|
254
254
|
project_podfile_path = PodBuilder::project_path("Podfile")
|
|
255
255
|
File.write(project_podfile_path, podfile_content)
|
|
@@ -486,10 +486,6 @@ module PodBuilder
|
|
|
486
486
|
return add(PRE_INSTALL_ACTIONS + [" "], "pre_install", podfile_content)
|
|
487
487
|
end
|
|
488
488
|
|
|
489
|
-
def self.add_post_install_checks(podfile_content)
|
|
490
|
-
return add(POST_INSTALL_ACTIONS + [" "], "post_install", podfile_content)
|
|
491
|
-
end
|
|
492
|
-
|
|
493
489
|
def self.add(entries, marker, podfile_content)
|
|
494
490
|
file_indentation = indentation_from_string(podfile_content)
|
|
495
491
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'xcodeproj'
|
|
2
|
+
require 'pod_builder/core'
|
|
3
|
+
require 'digest'
|
|
4
|
+
|
|
5
|
+
class Pod::Generator::FileList
|
|
6
|
+
alias_method :swz_initialize, :initialize
|
|
7
|
+
|
|
8
|
+
def initialize(paths)
|
|
9
|
+
paths.uniq!
|
|
10
|
+
swz_initialize(paths)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class Pod::Generator::CopyXCFrameworksScript
|
|
15
|
+
alias_method :swz_initialize, :initialize
|
|
16
|
+
|
|
17
|
+
def initialize(xcframeworks, sandbox_root, platform)
|
|
18
|
+
xcframeworks.uniq! { |t| t.path }
|
|
19
|
+
swz_initialize(xcframeworks, sandbox_root, platform)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class Pod::Generator::EmbedFrameworksScript
|
|
24
|
+
alias_method :swz_initialize, :initialize
|
|
25
|
+
|
|
26
|
+
def initialize(*args)
|
|
27
|
+
raise "Unsupported CocoaPods version" if (args.count == 0 || args.count > 2)
|
|
28
|
+
|
|
29
|
+
frameworks_by_config = args[0]
|
|
30
|
+
frameworks_by_config.keys.each do |key|
|
|
31
|
+
items = frameworks_by_config[key]
|
|
32
|
+
items.uniq! { |t| t.source_path }
|
|
33
|
+
frameworks_by_config[key] = items
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if args.count == 2
|
|
37
|
+
# CocoaPods 1.10.0 and newer
|
|
38
|
+
xcframeworks_by_config = args[1]
|
|
39
|
+
xcframeworks_by_config.keys.each do |key|
|
|
40
|
+
items = xcframeworks_by_config[key]
|
|
41
|
+
items.uniq! { |t| t.path }
|
|
42
|
+
xcframeworks_by_config[key] = items
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
swz_initialize(*args)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class Pod::Generator::CopyResourcesScript
|
|
51
|
+
alias_method :swz_initialize, :initialize
|
|
52
|
+
|
|
53
|
+
def initialize(resources_by_config, platform)
|
|
54
|
+
resources_by_config.keys.each do |key|
|
|
55
|
+
items = resources_by_config[key]
|
|
56
|
+
items.uniq!
|
|
57
|
+
|
|
58
|
+
colliding_resources = items.group_by { |t| File.basename(t) }.values.select { |t| t.count > 1 }
|
|
59
|
+
|
|
60
|
+
unless colliding_resources.empty?
|
|
61
|
+
message = ""
|
|
62
|
+
colliding_resources.each do |resources|
|
|
63
|
+
resources.map! { |t| File.expand_path(t.gsub("${PODS_ROOT}", "#{Dir.pwd}/Pods")) }
|
|
64
|
+
# check that files are identical.
|
|
65
|
+
# For files with paths that are resolved (e.g containing ${PODS_ROOT}) we use the file hash
|
|
66
|
+
# we fallback to the filename for the others
|
|
67
|
+
hashes = resources.map { |t| File.exists?(t) ? Digest::MD5.hexdigest(File.read(t)) : File.basename(t) }
|
|
68
|
+
if hashes.uniq.count > 1
|
|
69
|
+
message += resources.join("\n") + "\n"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
unless message.empty?
|
|
74
|
+
message = "\n\nThe following resources have the same name and will collide once copied into application bundle:\n" + message
|
|
75
|
+
raise message
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
resources_by_config[key] = items
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
swz_initialize(resources_by_config, platform)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -459,24 +459,6 @@ module PodBuilder
|
|
|
459
459
|
return root_name == named.split("/").first
|
|
460
460
|
end
|
|
461
461
|
|
|
462
|
-
def vendored_framework_path
|
|
463
|
-
if File.exist?(PodBuilder::prebuiltpath("#{root_name}/#{vendored_subspec_framework_name}"))
|
|
464
|
-
return vendored_subspec_framework_name
|
|
465
|
-
elsif File.exist?(PodBuilder::prebuiltpath("#{root_name}/#{vendored_spec_framework_name}"))
|
|
466
|
-
return vendored_spec_framework_name
|
|
467
|
-
end
|
|
468
|
-
|
|
469
|
-
return nil
|
|
470
|
-
end
|
|
471
|
-
|
|
472
|
-
def vendored_subspec_framework_name
|
|
473
|
-
return "#{prebuilt_rel_path}"
|
|
474
|
-
end
|
|
475
|
-
|
|
476
|
-
def vendored_spec_framework_name
|
|
477
|
-
return "#{module_name}.framework"
|
|
478
|
-
end
|
|
479
|
-
|
|
480
462
|
private
|
|
481
463
|
|
|
482
464
|
def extract_vendored_frameworks(spec, all_specs)
|
data/lib/pod_builder/podspec.rb
CHANGED
|
@@ -32,8 +32,8 @@ module PodBuilder
|
|
|
32
32
|
if_exists = lambda { |t| File.exist?(PodBuilder::prebuiltpath("#{item.root_name}/#{t}") || "") }
|
|
33
33
|
|
|
34
34
|
vendored_frameworks = item.vendored_frameworks
|
|
35
|
-
if item.default_subspecs.count == 0 && install_using_frameworks
|
|
36
|
-
vendored_frameworks += ["#{item.module_name}.framework"]
|
|
35
|
+
if item.default_subspecs.reject { |t| "#{item.root_name}/#{t}" == item.name }.count == 0 && install_using_frameworks
|
|
36
|
+
vendored_frameworks += ["#{item.module_name}.framework", "#{item.module_name}.xcframework"].select(&if_exists)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
existing_vendored_frameworks = vendored_frameworks.select(&if_exists)
|
|
@@ -49,13 +49,23 @@ module PodBuilder
|
|
|
49
49
|
# .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)
|
|
50
50
|
vendored_libraries.reject! { |t| t.end_with?(".a") }
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
public_headers = []
|
|
53
|
+
resources = []
|
|
54
|
+
exclude_files = []
|
|
55
|
+
vendored_frameworks.each do |vendored_framework|
|
|
56
|
+
binary_path = Dir.glob(PodBuilder::prebuiltpath("#{item.root_name}/#{vendored_framework}/**/#{File.basename(vendored_framework, ".*")}")).first
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
next if binary_path.nil?
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
is_static = `file '#{binary_path}'`.include?("current ar archive")
|
|
61
|
+
if is_static
|
|
62
|
+
parent_folder = File.expand_path("#{binary_path}/..")
|
|
63
|
+
rel_path = Pathname.new(parent_folder).relative_path_from(Pathname.new(PodBuilder::prebuiltpath(item.root_name))).to_s
|
|
64
|
+
|
|
65
|
+
resources.push("#{rel_path}/*.{nib,bundle,xcasset,strings,png,jpg,tif,tiff,otf,ttf,ttc,plist,json,caf,wav,p12,momd}")
|
|
66
|
+
exclude_files.push("#{rel_path}/Info.plist")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
59
69
|
else
|
|
60
70
|
public_headers = Dir.glob(PodBuilder::prebuiltpath("#{item.root_name}/#{item.root_name}/Headers/**/*.h"))
|
|
61
71
|
vendored_libraries += ["#{item.root_name}/lib#{item.root_name}.a"]
|
|
@@ -152,6 +162,10 @@ module PodBuilder
|
|
|
152
162
|
if name == item.root_name
|
|
153
163
|
deps.reject! { |t| t.split("/").first == item.root_name }
|
|
154
164
|
end
|
|
165
|
+
|
|
166
|
+
deps.reject! { |t| t == item.name }
|
|
167
|
+
all_buildable_items_name = all_buildable_items.map(&:name)
|
|
168
|
+
deps.select! { |t| all_buildable_items_name.include?(t) }
|
|
155
169
|
|
|
156
170
|
if deps.count > 0
|
|
157
171
|
if podspec.count("\n") > 1
|
|
@@ -164,10 +178,12 @@ module PodBuilder
|
|
|
164
178
|
|
|
165
179
|
valid = valid || (install_using_frameworks ? vendored_frameworks.count > 0 : vendored_libraries.count > 0)
|
|
166
180
|
end
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
181
|
+
|
|
182
|
+
subspec_base = name.split("/").first(slash_count).join("/")
|
|
183
|
+
subspec_items = all_buildable_items.select { |t| t.name.start_with?("#{subspec_base}/") }
|
|
184
|
+
|
|
185
|
+
subspec_names = subspec_items.map { |t| t.name.split("/").drop(slash_count).join("/") }
|
|
186
|
+
subspec_names.map! { |t| "#{subspec_base}/#{t}" }
|
|
171
187
|
|
|
172
188
|
subspec_names.each do |subspec|
|
|
173
189
|
subspec_item = all_buildable_items.detect { |t| t.name == subspec } || item
|
|
@@ -201,6 +217,7 @@ module PodBuilder
|
|
|
201
217
|
if item.is_prebuilt
|
|
202
218
|
next
|
|
203
219
|
end
|
|
220
|
+
|
|
204
221
|
if item.name != item.root_name
|
|
205
222
|
if all_buildable_items.map(&:name).include?(item.root_name)
|
|
206
223
|
next # will process root spec, skip subspecs
|
|
@@ -3,9 +3,7 @@ require 'colored'
|
|
|
3
3
|
require 'pathname'
|
|
4
4
|
|
|
5
5
|
module PodBuilder
|
|
6
|
-
def self.build_for_iosish_platform_framework(sandbox, build_dir, target, device, simulator, configuration, deterministic_build
|
|
7
|
-
raise "\n\nApple silicon hardware still unsupported since it requires to migrate to xcframeworks".red if build_for_apple_silicon
|
|
8
|
-
|
|
6
|
+
def self.build_for_iosish_platform_framework(sandbox, build_dir, target, device, simulator, configuration, deterministic_build)
|
|
9
7
|
dsym_device_folder = File.join(build_dir, "dSYM", device)
|
|
10
8
|
dsym_simulator_folder = File.join(build_dir, "dSYM", simulator)
|
|
11
9
|
FileUtils.mkdir_p(dsym_device_folder)
|
|
@@ -16,7 +14,7 @@ module PodBuilder
|
|
|
16
14
|
|
|
17
15
|
xcodebuild(sandbox, target_label, device, deployment_target, configuration, deterministic_build, [], {})
|
|
18
16
|
excluded_archs = ["i386"] # Fixes https://github.com/Subito-it/PodBuilder/issues/17
|
|
19
|
-
excluded_archs +=
|
|
17
|
+
excluded_archs += ["arm64"] # Exclude apple silicon slice
|
|
20
18
|
xcodebuild(sandbox, target_label, simulator, deployment_target, configuration, deterministic_build, excluded_archs, {})
|
|
21
19
|
|
|
22
20
|
spec_names = target.specs.map { |spec| [spec.root.name, spec.root.module_name] }.uniq
|
|
@@ -65,16 +63,14 @@ module PodBuilder
|
|
|
65
63
|
end
|
|
66
64
|
end
|
|
67
65
|
|
|
68
|
-
def self.build_for_iosish_platform_lib(sandbox, build_dir, target, device, simulator, configuration, deterministic_build,
|
|
69
|
-
raise "\n\nApple silicon hardware still unsupported since it requires to migrate to xcframeworks".red if build_for_apple_silicon
|
|
70
|
-
|
|
66
|
+
def self.build_for_iosish_platform_lib(sandbox, build_dir, target, device, simulator, configuration, deterministic_build, prebuilt_root_paths)
|
|
71
67
|
deployment_target = target.platform_deployment_target
|
|
72
68
|
target_label = target.cocoapods_target_label
|
|
73
69
|
|
|
74
70
|
spec_names = target.specs.map { |spec| [spec.root.name, spec.root.module_name] }.uniq
|
|
75
71
|
|
|
76
72
|
xcodebuild(sandbox, target_label, device, deployment_target, configuration, deterministic_build, [], prebuilt_root_paths)
|
|
77
|
-
excluded_archs =
|
|
73
|
+
excluded_archs = ["arm64"] # Exclude Apple silicon slice
|
|
78
74
|
xcodebuild(sandbox, target_label, simulator, deployment_target, configuration, deterministic_build, excluded_archs, prebuilt_root_paths)
|
|
79
75
|
|
|
80
76
|
spec_names.each do |root_name, module_name|
|
|
@@ -273,6 +269,7 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
|
|
|
273
269
|
if user_options["pre_compile"]
|
|
274
270
|
user_options["pre_compile"].call(installer_context)
|
|
275
271
|
end
|
|
272
|
+
build_xcframeworks = user_options.fetch('build_xcframeworks', false)
|
|
276
273
|
|
|
277
274
|
prebuilt_root_paths = JSON.parse(user_options["prebuilt_root_paths"].gsub('=>', ':'))
|
|
278
275
|
|
|
@@ -285,82 +282,139 @@ Pod::HooksManager.register('podbuilder-rome', :post_install) do |installer_conte
|
|
|
285
282
|
base_destination = sandbox_root.parent + 'Prebuilt'
|
|
286
283
|
|
|
287
284
|
build_dir.rmtree if build_dir.directory?
|
|
285
|
+
|
|
288
286
|
targets = installer_context.umbrella_targets.select { |t| t.specs.any? }
|
|
289
|
-
targets.
|
|
287
|
+
raise "\n\nUnsupported target count".red unless targets.count == 1
|
|
288
|
+
target = targets.first
|
|
289
|
+
|
|
290
|
+
if build_xcframeworks
|
|
291
|
+
project_path = sandbox_root.parent + 'Pods/Pods.xcodeproj'
|
|
292
|
+
|
|
293
|
+
case target.platform_name
|
|
294
|
+
when :ios then platforms = ['iphoneos', 'iphonesimulator']
|
|
295
|
+
when :osx then platforms = ['macos']
|
|
296
|
+
when :tvos then platforms = ['appletvos', 'appletvsimulator']
|
|
297
|
+
when :watchos then platforms = ['watchos', 'watchsimulator']
|
|
298
|
+
else raise "\n\nUnknown platform '#{target.platform_name}'".red end
|
|
299
|
+
|
|
300
|
+
platforms.each do |platform|
|
|
301
|
+
puts "Building xcframeworks for #{platform}".yellow
|
|
302
|
+
raise "\n\n#{platform} xcframework archive failed!".red if !system("xcodebuild archive -project #{project_path.to_s} -scheme Pods-DummyTarget -sdk #{platform} -archivePath '#{build_dir}/#{platform}' SKIP_INSTALL=NO > /dev/null")
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
built_items = Dir.glob("#{build_dir}/#{platforms.first}.xcarchive/Products/Library/Frameworks/*").reject { |t| File.basename(t, ".*") == "Pods_DummyTarget" }
|
|
306
|
+
|
|
307
|
+
built_items.each do |built_item|
|
|
308
|
+
built_item_paths = [built_item]
|
|
309
|
+
platforms.drop(1).each do |platform|
|
|
310
|
+
path = "#{build_dir}/#{platform}.xcarchive/Products/Library/Frameworks/#{File.basename(built_item)}"
|
|
311
|
+
if File.directory?(path)
|
|
312
|
+
built_item_paths.push(path)
|
|
313
|
+
else
|
|
314
|
+
built_item_paths = []
|
|
315
|
+
break
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
next if built_item_paths.count == 0
|
|
320
|
+
|
|
321
|
+
framework_name = File.basename(built_item_paths.first, ".*")
|
|
322
|
+
xcframework_path = "#{base_destination}/#{framework_name}/#{framework_name}.xcframework"
|
|
323
|
+
framework_params = built_item_paths.map { |t| "-framework '#{t}'"}.join(" ")
|
|
324
|
+
raise "\n\nFailed packing xcframework!".red if !system("xcodebuild -create-xcframework #{framework_params} -output '#{xcframework_path}' > /dev/null")
|
|
325
|
+
|
|
326
|
+
if enable_dsym
|
|
327
|
+
platforms.each do |platform|
|
|
328
|
+
dsym_source = "#{build_dir}/#{platform}.xcarchive/dSYMs/"
|
|
329
|
+
if File.directory?(dsym_source)
|
|
330
|
+
destination = sandbox_root.parent + "dSYMs"
|
|
331
|
+
FileUtils.mkdir_p(destination)
|
|
332
|
+
FileUtils.mv(dsym_source, destination)
|
|
333
|
+
FileUtils.mv("#{destination}/dSYMs", "#{destination}/#{platform}")
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
else
|
|
337
|
+
raise "Not implemented"
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
built_count = built_items.count
|
|
342
|
+
Pod::UI.puts "Built #{built_count} #{'item'.pluralize(built_count)}"
|
|
343
|
+
else
|
|
290
344
|
case [target.platform_name, uses_frameworks]
|
|
291
|
-
when [:ios, true] then PodBuilder::build_for_iosish_platform_framework(sandbox, build_dir, target, 'iphoneos', 'iphonesimulator', configuration, PodBuilder::Configuration.deterministic_build
|
|
292
|
-
when [:osx, true] then PodBuilder::xcodebuild(sandbox, target.cocoapods_target_label, configuration, PodBuilder::Configuration.deterministic_build,
|
|
293
|
-
when [:tvos, true] then PodBuilder::build_for_iosish_platform_framework(sandbox, build_dir, target, 'appletvos', 'appletvsimulator', configuration, PodBuilder::Configuration.deterministic_build
|
|
294
|
-
when [:watchos, true] then PodBuilder::build_for_iosish_platform_framework(sandbox, build_dir, target, 'watchos', 'watchsimulator', configuration, PodBuilder::Configuration.deterministic_build
|
|
295
|
-
when [:ios, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'iphoneos', 'iphonesimulator', configuration, PodBuilder::Configuration.deterministic_build,
|
|
296
|
-
when [:osx, false] then PodBuilder::xcodebuild(sandbox, target.cocoapods_target_label, configuration, PodBuilder::Configuration.deterministic_build,
|
|
297
|
-
when [:tvos, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'appletvos', 'appletvsimulator', configuration, PodBuilder::Configuration.deterministic_build,
|
|
298
|
-
when [:watchos, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'watchos', 'watchsimulator', configuration, PodBuilder::Configuration.deterministic_build,
|
|
345
|
+
when [:ios, true] then PodBuilder::build_for_iosish_platform_framework(sandbox, build_dir, target, 'iphoneos', 'iphonesimulator', configuration, PodBuilder::Configuration.deterministic_build)
|
|
346
|
+
when [:osx, true] then PodBuilder::xcodebuild(sandbox, target.cocoapods_target_label, configuration, PodBuilder::Configuration.deterministic_build, {})
|
|
347
|
+
when [:tvos, true] then PodBuilder::build_for_iosish_platform_framework(sandbox, build_dir, target, 'appletvos', 'appletvsimulator', configuration, PodBuilder::Configuration.deterministic_build)
|
|
348
|
+
when [:watchos, true] then PodBuilder::build_for_iosish_platform_framework(sandbox, build_dir, target, 'watchos', 'watchsimulator', configuration, PodBuilder::Configuration.deterministic_build)
|
|
349
|
+
when [:ios, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'iphoneos', 'iphonesimulator', configuration, PodBuilder::Configuration.deterministic_build, prebuilt_root_paths)
|
|
350
|
+
when [:osx, false] then PodBuilder::xcodebuild(sandbox, target.cocoapods_target_label, configuration, PodBuilder::Configuration.deterministic_build, prebuilt_root_paths)
|
|
351
|
+
when [:tvos, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'appletvos', 'appletvsimulator', configuration, PodBuilder::Configuration.deterministic_build, prebuilt_root_paths)
|
|
352
|
+
when [:watchos, false] then PodBuilder::build_for_iosish_platform_lib(sandbox, build_dir, target, 'watchos', 'watchsimulator', configuration, PodBuilder::Configuration.deterministic_build, prebuilt_root_paths)
|
|
299
353
|
else raise "\n\nUnknown platform '#{target.platform_name}'".red end
|
|
300
|
-
|
|
354
|
+
|
|
355
|
+
raise Pod::Informative, 'The build directory was not found in the expected location.' unless build_dir.directory?
|
|
301
356
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
built_count = Dir["#{build_dir}/*"].select { |t| specs.include?(File.basename(t)) }.count
|
|
306
|
-
Pod::UI.puts "Built #{built_count} #{'items'.pluralize(built_count)}, copying..."
|
|
307
|
-
|
|
308
|
-
base_destination.rmtree if base_destination.directory?
|
|
357
|
+
specs = installer_context.umbrella_targets.map { |t| t.specs.map(&:name) }.flatten.map { |t| t.split("/").first }.uniq
|
|
358
|
+
built_count = Dir["#{build_dir}/*"].select { |t| specs.include?(File.basename(t)) }.count
|
|
359
|
+
Pod::UI.puts "Built #{built_count} #{'item'.pluralize(built_count)}, copying..."
|
|
309
360
|
|
|
310
|
-
|
|
311
|
-
umbrella.specs.each do |spec|
|
|
312
|
-
root_name = spec.name.split("/").first
|
|
361
|
+
base_destination.rmtree if base_destination.directory?
|
|
313
362
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
363
|
+
installer_context.umbrella_targets.each do |umbrella|
|
|
364
|
+
umbrella.specs.each do |spec|
|
|
365
|
+
root_name = spec.name.split("/").first
|
|
366
|
+
|
|
367
|
+
if uses_frameworks
|
|
368
|
+
destination = File.join(base_destination, root_name)
|
|
369
|
+
else
|
|
370
|
+
destination = File.join(base_destination, root_name, root_name)
|
|
371
|
+
end
|
|
372
|
+
# Make sure the device target overwrites anything in the simulator build, otherwise iTunesConnect
|
|
373
|
+
# can get upset about Info.plist containing references to the simulator SDK
|
|
374
|
+
files = Pathname.glob("build/#{root_name}/*").reject { |f| f.to_s =~ /Pods[^.]+\.framework/ }
|
|
375
|
+
|
|
376
|
+
consumer = spec.consumer(umbrella.platform_name)
|
|
377
|
+
file_accessor = Pod::Sandbox::FileAccessor.new(sandbox.pod_dir(spec.root.name), consumer)
|
|
378
|
+
files += file_accessor.vendored_libraries
|
|
379
|
+
files += file_accessor.vendored_frameworks
|
|
380
|
+
files += file_accessor.resources
|
|
381
|
+
|
|
382
|
+
FileUtils.mkdir_p(destination)
|
|
383
|
+
files.each do |file|
|
|
384
|
+
FileUtils.cp_r(file, destination)
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
# Depending on the resource it may happen that it is present twice, both in the .framework and in the parent folder
|
|
390
|
+
Dir.glob("#{base_destination}/*") do |path|
|
|
391
|
+
unless File.directory?(path)
|
|
392
|
+
return
|
|
318
393
|
end
|
|
319
|
-
# Make sure the device target overwrites anything in the simulator build, otherwise iTunesConnect
|
|
320
|
-
# can get upset about Info.plist containing references to the simulator SDK
|
|
321
|
-
files = Pathname.glob("build/#{root_name}/*").reject { |f| f.to_s =~ /Pods[^.]+\.framework/ }
|
|
322
394
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
files += file_accessor.vendored_libraries
|
|
326
|
-
files += file_accessor.vendored_frameworks
|
|
327
|
-
files += file_accessor.resources
|
|
395
|
+
files = Dir.glob("#{path}/*")
|
|
396
|
+
framework_files = Dir.glob("#{path}/*.framework/**/*").map { |t| File.basename(t) }
|
|
328
397
|
|
|
329
|
-
FileUtils.mkdir_p(destination)
|
|
330
398
|
files.each do |file|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
# Depending on the resource it may happen that it is present twice, both in the .framework and in the parent folder
|
|
337
|
-
Dir.glob("#{base_destination}/*") do |path|
|
|
338
|
-
unless File.directory?(path)
|
|
339
|
-
return
|
|
399
|
+
filename = File.basename(file.gsub(/\.xib$/, ".nib"))
|
|
400
|
+
if framework_files.include?(filename)
|
|
401
|
+
FileUtils.rm_rf(file)
|
|
402
|
+
end
|
|
403
|
+
end
|
|
340
404
|
end
|
|
341
405
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
filename = File.basename(file.gsub(/\.xib$/, ".nib"))
|
|
347
|
-
if framework_files.include?(filename)
|
|
348
|
-
FileUtils.rm_rf(file)
|
|
406
|
+
if enable_dsym
|
|
407
|
+
dsym_source = "#{build_dir}/dSYM"
|
|
408
|
+
if File.directory?(dsym_source)
|
|
409
|
+
FileUtils.mv(dsym_source, sandbox_root.parent)
|
|
349
410
|
end
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
if enable_dsym
|
|
354
|
-
dsym_source = "#{build_dir}/dSYM"
|
|
355
|
-
if File.directory?(dsym_source)
|
|
356
|
-
FileUtils.mv(dsym_source, sandbox_root.parent)
|
|
357
|
-
end
|
|
358
|
-
else
|
|
359
|
-
raise "Not implemented"
|
|
411
|
+
else
|
|
412
|
+
raise "Not implemented"
|
|
413
|
+
end
|
|
360
414
|
end
|
|
361
|
-
|
|
415
|
+
|
|
362
416
|
build_dir.rmtree if build_dir.directory?
|
|
363
|
-
|
|
417
|
+
|
|
364
418
|
if user_options["post_compile"]
|
|
365
419
|
user_options["post_compile"].call(installer_context)
|
|
366
420
|
end
|
|
@@ -4,7 +4,7 @@ require 'cfpropertylist'
|
|
|
4
4
|
|
|
5
5
|
%%%use_frameworks%%%
|
|
6
6
|
|
|
7
|
-
plugin 'podbuilder-rome', { dsym: true, configuration: '%%%build_configuration%%%', uses_frameworks: %%%uses_frameworks%%%, prebuilt_root_paths: '%%%prebuilt_root_paths%%%', pre_compile: Proc.new { |installer|
|
|
7
|
+
plugin 'podbuilder-rome', { dsym: true, configuration: '%%%build_configuration%%%', uses_frameworks: %%%uses_frameworks%%%, build_xcframeworks: %%%build_xcframeworks%%%, prebuilt_root_paths: '%%%prebuilt_root_paths%%%', pre_compile: Proc.new { |installer|
|
|
8
8
|
|
|
9
9
|
def set_build_settings(target_name, build_configurations, installer)
|
|
10
10
|
installer.pods_project.targets.each do |target|
|
data/lib/pod_builder/version.rb
CHANGED
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.
|
|
4
|
+
version: 2.1.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-11-
|
|
11
|
+
date: 2020-11-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -204,7 +204,7 @@ files:
|
|
|
204
204
|
- lib/pod_builder/install.rb
|
|
205
205
|
- lib/pod_builder/licenses.rb
|
|
206
206
|
- lib/pod_builder/podfile.rb
|
|
207
|
-
- lib/pod_builder/podfile/
|
|
207
|
+
- lib/pod_builder/podfile/pre_actions_swizzles.rb
|
|
208
208
|
- lib/pod_builder/podfile_cp.rb
|
|
209
209
|
- lib/pod_builder/podfile_item.rb
|
|
210
210
|
- lib/pod_builder/podspec.rb
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
require 'xcodeproj'
|
|
2
|
-
require 'pod_builder/core'
|
|
3
|
-
|
|
4
|
-
module PodBuilder
|
|
5
|
-
class Podfile
|
|
6
|
-
def self.pod_builder_post_process
|
|
7
|
-
Configuration.load
|
|
8
|
-
|
|
9
|
-
targets = find_xcodeproj_targets
|
|
10
|
-
target_names = targets.map(&:name)
|
|
11
|
-
|
|
12
|
-
puts "[PodBuilder] Removing target support duplicated entries".yellow
|
|
13
|
-
# Frameworks and resources
|
|
14
|
-
target_names.each do |target|
|
|
15
|
-
remove_duplicate_entries("Pods/Target Support Files/Pods-#{target}/Pods-#{target}-frameworks.sh")
|
|
16
|
-
remove_duplicate_entries("Pods/Target Support Files/Pods-#{target}/Pods-#{target}-resources.sh")
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
puts "[PodBuilder] Checking target support resource collisions".yellow
|
|
20
|
-
target_names.each do |target|
|
|
21
|
-
check_for_colliding_resources("Pods/Target Support Files/Pods-#{target}/Pods-#{target}-resources.sh", target, targets)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
def self.remove_duplicate_entries(path)
|
|
28
|
-
if !File.file?(path)
|
|
29
|
-
return
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# Adding the same pod to multiple targets results in duplicate entries in Pods-TARGET-frameworks.sh and Pods-TARGET-resources.sh (Cocoapods 1.4.0)
|
|
33
|
-
# To avoid conflicts during parallel codesign we manually remove duplicates
|
|
34
|
-
in_section_to_update = false
|
|
35
|
-
processed_entries = []
|
|
36
|
-
lines = []
|
|
37
|
-
File.read(path).each_line do |line|
|
|
38
|
-
stripped_line = line.strip()
|
|
39
|
-
next if stripped_line.empty?
|
|
40
|
-
|
|
41
|
-
if stripped_line.include?("if [[ \"$CONFIGURATION\" == ")
|
|
42
|
-
in_section_to_update = true
|
|
43
|
-
elsif stripped_line == "fi"
|
|
44
|
-
in_section_to_update = false
|
|
45
|
-
processed_entries = []
|
|
46
|
-
end
|
|
47
|
-
if in_section_to_update
|
|
48
|
-
if processed_entries.include?(stripped_line)
|
|
49
|
-
if !line.include?("#")
|
|
50
|
-
line = "# #{line}"
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
processed_entries.push(stripped_line)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
lines.push(line)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
File.write(path, lines.join)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def self.check_for_colliding_resources(path, target_name, targets)
|
|
63
|
-
if !File.file?(path)
|
|
64
|
-
return
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
if target = targets.detect { |x| x.name == target_name }
|
|
68
|
-
resource_files = target.resources_build_phase.files.map { |i| i.file_ref.real_path.to_s }.to_set
|
|
69
|
-
resource_files = resource_files.map { |i| File.basename(i) }
|
|
70
|
-
resource_files = resource_files.map { |i| i.gsub(".xib", ".nib") }
|
|
71
|
-
else
|
|
72
|
-
raise "\n\n#{target} not found!".red
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Check that Pods-TARGET-resources.sh doesn't contain colliding entries (Cocoapods 1.4.0)
|
|
76
|
-
in_section_to_update = false
|
|
77
|
-
processed_entries = []
|
|
78
|
-
File.read(path).each_line do |line|
|
|
79
|
-
stripped_line = line.strip()
|
|
80
|
-
next if stripped_line.empty?
|
|
81
|
-
|
|
82
|
-
if stripped_line.include?("if [[ \"$CONFIGURATION\" == ")
|
|
83
|
-
in_section_to_update = true
|
|
84
|
-
next
|
|
85
|
-
elsif stripped_line == "fi"
|
|
86
|
-
in_section_to_update = false
|
|
87
|
-
|
|
88
|
-
processed_entries.each do |entry|
|
|
89
|
-
matches_other_framework = processed_entries.select { |t| t[0] == entry[0] }
|
|
90
|
-
|
|
91
|
-
# Check for static framework cross-collisions
|
|
92
|
-
if matches_other_framework.count > 1
|
|
93
|
-
error = "\n\nCross-framework resource collision detected:\n"
|
|
94
|
-
error += "#{entry[0]} found in\n"
|
|
95
|
-
error += matches_other_framework.map { |x| "- #{x[1]}" }.join("\n")
|
|
96
|
-
error += "\n\n"
|
|
97
|
-
|
|
98
|
-
raise error.red
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Check for collisions with app's resources
|
|
102
|
-
matches_app_resources = resource_files.select { |t| t == entry[0] }
|
|
103
|
-
if matches_app_resources.count > 0
|
|
104
|
-
error = "\n\nResource collision with app file detected:\n"
|
|
105
|
-
error += "#{entry[0]} found in app but also in\n"
|
|
106
|
-
error += matches_app_resources.map { |x| "- #{x[1]}" }.join("\n")
|
|
107
|
-
error += "\n\n"
|
|
108
|
-
|
|
109
|
-
raise error.red
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
processed_entries = []
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
next if stripped_line.start_with?("#") # skip commented lines
|
|
117
|
-
next if stripped_line.count("/..") > 2 # skip development pods
|
|
118
|
-
|
|
119
|
-
line.gsub!("\"", "")
|
|
120
|
-
line.gsub!("install_resource", "")
|
|
121
|
-
line.strip!()
|
|
122
|
-
|
|
123
|
-
if in_section_to_update
|
|
124
|
-
filename = File.basename(line)
|
|
125
|
-
processed_entries.push([filename, line])
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def self.find_xcodeproj_targets
|
|
131
|
-
project = Xcodeproj::Project.open(PodBuilder::find_xcodeproj)
|
|
132
|
-
|
|
133
|
-
return project.targets
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|