cocoapods-util 0.0.15 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cocoapods-util/binary/Intergation.rb +300 -0
- data/lib/cocoapods-util/binary/config.rb +52 -0
- data/lib/cocoapods-util/binary/helper/names.rb +78 -0
- data/lib/cocoapods-util/binary/helper/podfile_options.rb +120 -0
- data/lib/cocoapods-util/binary/helper/target_checker.rb +49 -0
- data/lib/cocoapods-util/binary/hooks/CocoapodsUtilHook.rb +25 -0
- data/lib/cocoapods-util/binary/hooks/post_install.rb +10 -0
- data/lib/cocoapods-util/binary/hooks/pre_install.rb +21 -0
- data/lib/cocoapods-util/binary/main.rb +4 -0
- data/lib/cocoapods-util/binary/podfile_dsl.rb +10 -0
- data/lib/cocoapods-util/binary/prebuild.rb +66 -0
- data/lib/cocoapods-util/binary/targets/pod_target.rb +104 -0
- data/lib/cocoapods-util/command/cocoapods-extend/install/list.rb +27 -19
- data/lib/cocoapods-util/command/package/helper/pod_utils.rb +2 -6
- data/lib/cocoapods-util/command/xcframework/xcframework.rb +2 -6
- data/lib/cocoapods-util/command/xcframework/xcframework_build.rb +13 -29
- data/lib/cocoapods-util/gem_version.rb +1 -1
- data/lib/cocoapods_plugin.rb +1 -1
- metadata +17 -9
- data/lib/cocoapods-util/CocoapodsUtilHook.rb +0 -63
- data/lib/cocoapods-util/hooks/feature_switch.rb +0 -3
- data/lib/cocoapods-util/hooks/installer.rb +0 -4
- data/lib/cocoapods-util/hooks/prebuild_sandbox.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 656f35fa8c5fb7c2994fb8b454f010a9c3166b2b3a56ad75b9ccdfba7768829b
|
4
|
+
data.tar.gz: 33ff55946a88e29bfaaa0a0112af003702e0e33cee42449af79284fcaa8ebe90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed695aae86dc40ab0a1661e4aefbe61c363a2c89eb15b401d238e489570c3a15f048f7e3422060ceff1b2159e5a9c1c07f777e50fc1d324bece09fddbe32234c
|
7
|
+
data.tar.gz: b51419985404992c9ddaaa707240c2ce0b61f2fce48cdb98f160e2f71148f1303be14d9b4c1c03b04f103928fef2598234489be674e375aa553fd11543a17ded
|
@@ -0,0 +1,300 @@
|
|
1
|
+
require_relative 'helper/podfile_options'
|
2
|
+
require_relative 'helper/names'
|
3
|
+
require_relative 'helper/target_checker'
|
4
|
+
|
5
|
+
|
6
|
+
# NOTE:
|
7
|
+
# This file will only be loaded on normal pod install step
|
8
|
+
# so there's no need to check is_prebuild_stage
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
# Provide a special "download" process for prebuilded pods.
|
13
|
+
#
|
14
|
+
# As the frameworks is already exsited in local folder. We
|
15
|
+
# just create a symlink to the original target folder.
|
16
|
+
#
|
17
|
+
module Pod
|
18
|
+
class Installer
|
19
|
+
class PodSourceInstaller
|
20
|
+
|
21
|
+
def install_for_prebuild!(standard_sanbox)
|
22
|
+
prebuild_sandbox = BinaryPrebuild::Sandbox.from_sandbox(standard_sanbox)
|
23
|
+
return if prebuild_sandbox.nil?
|
24
|
+
target_names = prebuild_sandbox.existed_target_names(self.name)
|
25
|
+
|
26
|
+
def walk(path, &action)
|
27
|
+
return unless path.exist?
|
28
|
+
path.children.each do |child|
|
29
|
+
result = action.call(child, &action)
|
30
|
+
if child.directory?
|
31
|
+
walk(child, &action) if result
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
def make_link(source, target)
|
36
|
+
source = Pathname.new(source)
|
37
|
+
target = Pathname.new(target)
|
38
|
+
target.parent.mkpath unless target.parent.exist?
|
39
|
+
relative_source = source.relative_path_from(target.parent)
|
40
|
+
FileUtils.ln_sf(relative_source, target)
|
41
|
+
end
|
42
|
+
def mirror_with_symlink(source, basefolder, target_folder)
|
43
|
+
relative_path = source.relative_path_from(basefolder)
|
44
|
+
if relative_path.to_s =~ /^(Debug|Release)\/.*/
|
45
|
+
new_relative_path = relative_path.to_s.gsub!(/^(Debug|Release)/) { |match| "#{BinaryPrebuild.config.xcconfig_replace_path}-#{match}" }
|
46
|
+
target = Pathname.new("#{target_folder}/#{new_relative_path}")
|
47
|
+
make_link(source, target)
|
48
|
+
else
|
49
|
+
target = Pathname.new("#{target_folder}/#{relative_path}")
|
50
|
+
make_link(source, target)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
target_names.each do |name|
|
55
|
+
|
56
|
+
# symbol link copy all substructure
|
57
|
+
real_file_folder = prebuild_sandbox.framework_folder_path_for_target_name(name)
|
58
|
+
|
59
|
+
# If have only one platform, just place int the root folder of this pod.
|
60
|
+
# If have multiple paths, we use a sperated folder to store different
|
61
|
+
# platform frameworks. e.g. AFNetworking/AFNetworking-iOS/AFNetworking.framework
|
62
|
+
|
63
|
+
target_folder = standard_sanbox.pod_dir(self.name) + "_Prebuild"
|
64
|
+
target_folder.rmtree if target_folder.exist?
|
65
|
+
target_folder.mkpath
|
66
|
+
|
67
|
+
|
68
|
+
walk(real_file_folder) do |child|
|
69
|
+
source = child
|
70
|
+
# only make symlink to file and `.framework` folder
|
71
|
+
if child.directory? and [".framework", ".xcframework", ".bundle", ".dSYM"].include? child.extname
|
72
|
+
mirror_with_symlink(source, real_file_folder, target_folder)
|
73
|
+
next false # return false means don't go deeper
|
74
|
+
elsif child.file?
|
75
|
+
mirror_with_symlink(source, real_file_folder, target_folder)
|
76
|
+
next true
|
77
|
+
else
|
78
|
+
next true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end # of for each
|
82
|
+
|
83
|
+
end # of method
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
# Let cocoapods use the prebuild framework files in install process.
|
91
|
+
#
|
92
|
+
# the code only effect the second pod install process.
|
93
|
+
#
|
94
|
+
module Pod
|
95
|
+
class Installer
|
96
|
+
# Modify specification to use only the prebuild framework after analyzing
|
97
|
+
old_method2 = instance_method(:resolve_dependencies)
|
98
|
+
define_method(:resolve_dependencies) do
|
99
|
+
# call original
|
100
|
+
old_method2.bind(self).()
|
101
|
+
# ...
|
102
|
+
# ...
|
103
|
+
# ...
|
104
|
+
# after finishing the very complex orginal function
|
105
|
+
|
106
|
+
# check the pods
|
107
|
+
# Although we have did it in prebuild stage, it's not sufficient.
|
108
|
+
# Same pod may appear in another target in form of source code.
|
109
|
+
# Prebuild.check_one_pod_should_have_only_one_target(self.prebuild_pod_targets)
|
110
|
+
# self.validate_every_pod_only_have_one_form
|
111
|
+
|
112
|
+
# prepare
|
113
|
+
cache = []
|
114
|
+
|
115
|
+
def add_vendered_framework(spec, platform, added_framework_file_path)
|
116
|
+
if spec.attributes_hash[platform] == nil
|
117
|
+
spec.attributes_hash[platform] = {}
|
118
|
+
end
|
119
|
+
vendored_frameworks = spec.attributes_hash[platform]["vendored_frameworks"] || []
|
120
|
+
vendored_frameworks = [vendored_frameworks] if vendored_frameworks.kind_of?(String)
|
121
|
+
vendored_frameworks += [added_framework_file_path]
|
122
|
+
spec.attributes_hash[platform]["vendored_frameworks"] = vendored_frameworks
|
123
|
+
end
|
124
|
+
def empty_source_files(spec)
|
125
|
+
spec.attributes_hash["source_files"] = []
|
126
|
+
spec.attributes_hash["public_header_files"] = []
|
127
|
+
spec.attributes_hash["private_header_files"] = []
|
128
|
+
["ios", "watchos", "tvos", "osx"].each do |plat|
|
129
|
+
if spec.attributes_hash[plat] != nil
|
130
|
+
spec.attributes_hash[plat]["source_files"] = []
|
131
|
+
spec.attributes_hash[plat]["public_header_files"] = []
|
132
|
+
spec.attributes_hash[plat]["private_header_files"] = []
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
prebuild_sandbox = BinaryPrebuild::Sandbox.from_sandbox(self.sandbox)
|
138
|
+
return if prebuild_sandbox.nil?
|
139
|
+
|
140
|
+
specs = self.analysis_result.specifications
|
141
|
+
prebuilt_specs = (specs.select do |spec|
|
142
|
+
# rmtree
|
143
|
+
target_prebuild_files = self.sandbox.root + spec.root.name + "_Prebuild"
|
144
|
+
target_prebuild_files.rmtree if target_prebuild_files.exist?
|
145
|
+
|
146
|
+
self.prebuild_pod_names.include? spec.root.name
|
147
|
+
end)
|
148
|
+
|
149
|
+
prebuilt_specs.each do |spec|
|
150
|
+
|
151
|
+
# Use the prebuild framworks as vendered frameworks
|
152
|
+
# get_corresponding_targets
|
153
|
+
targets = Pod.fast_get_targets_for_pod_name(spec.root.name, self.pod_targets, cache)
|
154
|
+
targets.each do |target|
|
155
|
+
# the framework_file_path rule is decided when `install_for_prebuild`,
|
156
|
+
# as to compitable with older version and be less wordy.
|
157
|
+
prebuild_sandbox.prebuild_vendored_frameworks(spec.root.name).each do |frame_file_path|
|
158
|
+
framework_file_path = "_Prebuild/" + frame_file_path
|
159
|
+
add_vendered_framework(spec, target.platform.name.to_s, framework_file_path)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
# Clean the source files
|
163
|
+
# we just add the prebuilt framework to specific platform and set no source files
|
164
|
+
# for all platform, so it doesn't support the sence that 'a pod perbuild for one
|
165
|
+
# platform and not for another platform.'
|
166
|
+
empty_source_files(spec)
|
167
|
+
|
168
|
+
# to remove the resurce bundle target.
|
169
|
+
# When specify the "resource_bundles" in podspec, xcode will generate a bundle
|
170
|
+
# target after pod install. But the bundle have already built when the prebuit
|
171
|
+
# phase and saved in the framework folder. We will treat it as a normal resource
|
172
|
+
# file.
|
173
|
+
# https://github.com/leavez/cocoapods-binary/issues/29
|
174
|
+
if spec.attributes_hash["resource_bundles"]
|
175
|
+
# bundle_names = spec.attributes_hash["resource_bundles"].keys
|
176
|
+
spec.attributes_hash["resource_bundles"] = nil
|
177
|
+
spec.attributes_hash["resources"] ||= []
|
178
|
+
resources = spec.attributes_hash["resources"] || []
|
179
|
+
resources = [resources] if resources.kind_of?(String)
|
180
|
+
spec.attributes_hash["resources"] = resources
|
181
|
+
# spec.attributes_hash["resources"] += bundle_names.map{|n| n+".bundle"}
|
182
|
+
prebuild_bundles = prebuild_sandbox.prebuild_bundles(spec.root.name).each.map do |bundle_path|
|
183
|
+
"_Prebuild/" + bundle_path
|
184
|
+
end
|
185
|
+
spec.attributes_hash["resources"] += prebuild_bundles
|
186
|
+
end
|
187
|
+
|
188
|
+
# to avoid the warning of missing license
|
189
|
+
spec.attributes_hash["license"] = {}
|
190
|
+
spec.attributes_hash["preserve_paths"] = "**/*"
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
# Override the download step to skip download and prepare file in target folder
|
198
|
+
old_method = instance_method(:install_source_of_pod)
|
199
|
+
define_method(:install_source_of_pod) do |pod_name|
|
200
|
+
|
201
|
+
# copy from original
|
202
|
+
pod_installer = create_pod_installer(pod_name)
|
203
|
+
# \copy from original
|
204
|
+
|
205
|
+
# copy from original
|
206
|
+
pod_installer.install!
|
207
|
+
# \copy from original
|
208
|
+
|
209
|
+
if self.prebuild_pod_names.include? pod_name
|
210
|
+
pod_installer.install_for_prebuild!(self.sandbox)
|
211
|
+
end
|
212
|
+
|
213
|
+
# copy from original
|
214
|
+
@installed_specs.concat(pod_installer.specs_by_platform.values.flatten.uniq)
|
215
|
+
# \copy from original
|
216
|
+
end
|
217
|
+
|
218
|
+
alias_method :old_create_pod_installer, :create_pod_installer
|
219
|
+
def create_pod_installer(pod_name)
|
220
|
+
pod_installer = old_create_pod_installer(pod_name)
|
221
|
+
|
222
|
+
pods_to_install = sandbox_state.added | sandbox_state.changed
|
223
|
+
unless pods_to_install.include?(pod_name)
|
224
|
+
pod_installer.install_for_prebuild!(self.sandbox) if self.prebuild_pod_names.include? pod_name
|
225
|
+
end
|
226
|
+
pod_installer
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# A fix in embeded frameworks script.
|
232
|
+
#
|
233
|
+
# The framework file in pod target folder is a symblink. The EmbedFrameworksScript use `readlink`
|
234
|
+
# to read the read path. As the symlink is a relative symlink, readlink cannot handle it well. So
|
235
|
+
# we override the `readlink` to a fixed version.
|
236
|
+
#
|
237
|
+
module Pod
|
238
|
+
module Generator
|
239
|
+
class EmbedFrameworksScript
|
240
|
+
|
241
|
+
old_method = instance_method(:script)
|
242
|
+
define_method(:script) do
|
243
|
+
|
244
|
+
script = old_method.bind(self).()
|
245
|
+
patch = <<-SH.strip_heredoc
|
246
|
+
#!/bin/sh
|
247
|
+
|
248
|
+
# ---- this is added by cocoapods-binary ---
|
249
|
+
# Readlink cannot handle relative symlink well, so we override it to a new one
|
250
|
+
# If the path isn't an absolute path, we add a realtive prefix.
|
251
|
+
old_read_link=`which readlink`
|
252
|
+
readlink () {
|
253
|
+
path=`$old_read_link "$1"`;
|
254
|
+
if [ $(echo "$path" | cut -c 1-1) = '/' ]; then
|
255
|
+
echo $path;
|
256
|
+
else
|
257
|
+
echo "`dirname $1`/$path";
|
258
|
+
fi
|
259
|
+
}
|
260
|
+
# ---
|
261
|
+
SH
|
262
|
+
|
263
|
+
# patch the rsync for copy dSYM symlink
|
264
|
+
script = script.gsub "rsync --delete", "rsync --copy-links --delete"
|
265
|
+
|
266
|
+
patch + script
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
module Pod
|
273
|
+
module Generator
|
274
|
+
class CopyXCFrameworksScript
|
275
|
+
|
276
|
+
alias_method :old_install_xcframework_args, :install_xcframework_args
|
277
|
+
def install_xcframework_args(xcframework, slices)
|
278
|
+
args = old_install_xcframework_args(xcframework, slices)
|
279
|
+
xcconfig_replace_path = BinaryPrebuild.config.xcconfig_replace_path
|
280
|
+
args.gsub!(/#{xcconfig_replace_path}-(Debug|Release)/, "#{xcconfig_replace_path}-${CONFIGURATION}")
|
281
|
+
args
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
module Pod
|
288
|
+
module Generator
|
289
|
+
class CopyResourcesScript
|
290
|
+
|
291
|
+
alias_method :old_script, :script
|
292
|
+
def script
|
293
|
+
script = old_script
|
294
|
+
xcconfig_replace_path = BinaryPrebuild.config.xcconfig_replace_path
|
295
|
+
script.gsub!(/#{xcconfig_replace_path}-(Debug|Release)/, "#{xcconfig_replace_path}-${CONFIGURATION}")
|
296
|
+
script
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module BinaryPrebuild
|
2
|
+
def self.config
|
3
|
+
BinaryPrebuild::Config.instance
|
4
|
+
end
|
5
|
+
|
6
|
+
class Config
|
7
|
+
attr_accessor :dsl_config
|
8
|
+
|
9
|
+
APPLICABLE_DSL_CONFIG = [
|
10
|
+
:all_binary,
|
11
|
+
:binary_dir,
|
12
|
+
:dev_pods_enabled,
|
13
|
+
:xcconfig_replace_path,
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
def initialize()
|
17
|
+
@dsl_config = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.instance
|
21
|
+
@instance ||= new()
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate_dsl_config
|
25
|
+
inapplicable_options = @dsl_config.keys - APPLICABLE_DSL_CONFIG
|
26
|
+
return if inapplicable_options.empty?
|
27
|
+
|
28
|
+
message = <<~HEREDOC
|
29
|
+
[WARNING] The following options (in `config_cocoapods_util`) are not correct: #{inapplicable_options}.
|
30
|
+
Available options: #{APPLICABLE_DSL_CONFIG}.
|
31
|
+
HEREDOC
|
32
|
+
|
33
|
+
Pod::UI.puts message.yellow
|
34
|
+
end
|
35
|
+
|
36
|
+
def all_binary_enable?
|
37
|
+
@dsl_config[:all_binary] || false
|
38
|
+
end
|
39
|
+
|
40
|
+
def dev_pods_enabled?
|
41
|
+
@dsl_config[:dev_pods_enabled] || false
|
42
|
+
end
|
43
|
+
|
44
|
+
def binary_dir
|
45
|
+
@dsl_config[:binary_dir] || '_Prebuild'
|
46
|
+
end
|
47
|
+
|
48
|
+
def xcconfig_replace_path
|
49
|
+
@dsl_config[:xcconfig_replace_path] || "cocoapods-util-binary"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# ABOUT NAMES
|
2
|
+
#
|
3
|
+
# There are many kinds of name in cocoapods. Two main names are widely used in this plugin.
|
4
|
+
# - root_spec.name (spec.root_name, targe.pod_name):
|
5
|
+
# aka "pod_name"
|
6
|
+
# the name we use in podfile. the concept.
|
7
|
+
#
|
8
|
+
# - target.name:
|
9
|
+
# aka "target_name"
|
10
|
+
# the name of the final target in xcode project. the final real thing.
|
11
|
+
#
|
12
|
+
# One pod may have multiple targets in xcode project, due to one pod can be used in mutiple
|
13
|
+
# platform simultaneously. So one `root_spec.name` may have multiple coresponding `target.name`s.
|
14
|
+
# Therefore, map a spec to/from targets is a little complecated. It's one to many.
|
15
|
+
#
|
16
|
+
|
17
|
+
# Tool to transform Pod_name to target efficiently
|
18
|
+
module Pod
|
19
|
+
def self.fast_get_targets_for_pod_name(pod_name, targets, cache)
|
20
|
+
pod_name_to_targets_hash = nil
|
21
|
+
if cache.empty?
|
22
|
+
pod_name_to_targets_hash = targets.reduce({}) do |sum, target|
|
23
|
+
array = sum[target.pod_name] || []
|
24
|
+
array << target
|
25
|
+
sum[target.pod_name] = array
|
26
|
+
sum
|
27
|
+
end
|
28
|
+
cache << pod_name_to_targets_hash
|
29
|
+
else
|
30
|
+
pod_name_to_targets_hash = cache.first
|
31
|
+
end
|
32
|
+
|
33
|
+
pod_name_to_targets_hash[pod_name] || []
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
# Target:
|
43
|
+
|
44
|
+
# def pod_name
|
45
|
+
# root_spec.name
|
46
|
+
# end
|
47
|
+
|
48
|
+
# def name
|
49
|
+
# pod_name + #{scope_suffix}
|
50
|
+
# end
|
51
|
+
|
52
|
+
# def product_module_name
|
53
|
+
# root_spec.module_name
|
54
|
+
# end
|
55
|
+
|
56
|
+
# def framework_name
|
57
|
+
# "#{product_module_name}.framework"
|
58
|
+
# end
|
59
|
+
|
60
|
+
# def product_name
|
61
|
+
# if requires_frameworks?
|
62
|
+
# framework_name
|
63
|
+
# else
|
64
|
+
# static_library_name
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
|
68
|
+
# def product_basename
|
69
|
+
# if requires_frameworks?
|
70
|
+
# product_module_name
|
71
|
+
# else
|
72
|
+
# label
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
|
76
|
+
# def framework_name
|
77
|
+
# "#{product_module_name}.framework"
|
78
|
+
# end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
|
2
|
+
module Pod
|
3
|
+
class Podfile
|
4
|
+
class TargetDefinition
|
5
|
+
def detect_prebuilt_pod(name, requirements)
|
6
|
+
options = requirements.last || {}
|
7
|
+
|
8
|
+
# prebuild
|
9
|
+
@explicit_prebuild_pod_names ||= []
|
10
|
+
@reject_prebuild_pod_names ||= []
|
11
|
+
@explicit_prebuild_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options[:binary]
|
12
|
+
@reject_prebuild_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options.include?(:binary) && !options[:binary]
|
13
|
+
|
14
|
+
# header search path
|
15
|
+
@explicit_header_search_pod_names ||= []
|
16
|
+
@reject_header_search_pod_names ||= []
|
17
|
+
@explicit_header_search_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options[:framework_search_header]
|
18
|
+
@reject_header_search_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options.include?(:framework_search_header) && !options[:framework_search_header]
|
19
|
+
|
20
|
+
options.delete(:binary) if options.is_a?(Hash)
|
21
|
+
options.delete(:framework_search_header) if options.is_a?(Hash)
|
22
|
+
requirements.pop if options.empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the names of pod targets explicitly declared as prebuilt in Podfile using `:binary => true`.
|
26
|
+
def explicit_prebuild_pod_names
|
27
|
+
names = @explicit_prebuild_pod_names || []
|
28
|
+
names += parent.explicit_prebuild_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
|
29
|
+
names
|
30
|
+
end
|
31
|
+
|
32
|
+
def reject_prebuild_pod_names
|
33
|
+
names = @reject_prebuild_pod_names || []
|
34
|
+
names += parent.reject_prebuild_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
|
35
|
+
names
|
36
|
+
end
|
37
|
+
|
38
|
+
def explicit_header_search_pod_names
|
39
|
+
names = @explicit_header_search_pod_names || []
|
40
|
+
names += parent.explicit_header_search_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
|
41
|
+
names
|
42
|
+
end
|
43
|
+
|
44
|
+
def reject_header_search_pod_names
|
45
|
+
names = @reject_header_search_pod_names || []
|
46
|
+
names += parent.reject_header_search_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
|
47
|
+
names
|
48
|
+
end
|
49
|
+
|
50
|
+
# ---- patch method ----
|
51
|
+
# We want modify `store_pod` method, but it's hard to insert a line in the
|
52
|
+
# implementation. So we patch a method called in `store_pod`.
|
53
|
+
original_parse_inhibit_warnings = instance_method(:parse_inhibit_warnings)
|
54
|
+
define_method(:parse_inhibit_warnings) do |name, requirements|
|
55
|
+
detect_prebuilt_pod(name, requirements)
|
56
|
+
original_parse_inhibit_warnings.bind(self).call(name, requirements)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module Pod
|
63
|
+
class Installer
|
64
|
+
# Returns the names of pod targets detected as prebuilt, including
|
65
|
+
# those declared in Podfile and their dependencies
|
66
|
+
def prebuild_pod_names
|
67
|
+
prebuilt_pod_targets.map(&:name).to_set
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the pod targets detected as prebuilt, including
|
71
|
+
# those declared in Podfile and their dependencies
|
72
|
+
def prebuilt_pod_targets
|
73
|
+
@prebuilt_pod_targets ||= begin
|
74
|
+
explicit_prebuild_pod_names = aggregate_targets.flat_map { |target|
|
75
|
+
target.target_definition.explicit_prebuild_pod_names
|
76
|
+
}.uniq
|
77
|
+
|
78
|
+
reject_prebuild_pod_names = aggregate_targets.flat_map { |target|
|
79
|
+
target.target_definition.reject_prebuild_pod_names
|
80
|
+
}.uniq
|
81
|
+
|
82
|
+
available_pod_names = []
|
83
|
+
prebuild_sandbox = BinaryPrebuild::Sandbox.from_sandbox(self.sandbox)
|
84
|
+
available_pod_names = prebuild_sandbox.target_paths.map {|path| path.basename.to_s } unless prebuild_sandbox.nil?
|
85
|
+
if BinaryPrebuild.config.all_binary_enable?
|
86
|
+
explicit_prebuild_pod_names = available_pod_names
|
87
|
+
else
|
88
|
+
explicit_prebuild_pod_names = (explicit_prebuild_pod_names & available_pod_names).uniq
|
89
|
+
end
|
90
|
+
explicit_prebuild_pod_names -= reject_prebuild_pod_names
|
91
|
+
|
92
|
+
targets = pod_targets.select { |target|
|
93
|
+
explicit_prebuild_pod_names.include?(target.pod_name)
|
94
|
+
}
|
95
|
+
targets = targets.reject { |target| sandbox.local?(target.pod_name) } unless BinaryPrebuild.config.dev_pods_enabled?
|
96
|
+
targets.map { |target| target.use_binary = true }
|
97
|
+
targets
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
module Pod
|
104
|
+
class Target
|
105
|
+
attr_accessor :use_binary
|
106
|
+
|
107
|
+
def frame_header_search_paths_enable?
|
108
|
+
return true if self.use_binary
|
109
|
+
header_search_pod_names.include? self.name
|
110
|
+
end
|
111
|
+
|
112
|
+
def header_search_pod_names
|
113
|
+
@explicit_header_search_pod_names ||= begin
|
114
|
+
target_definitions.flat_map { |target_definition|
|
115
|
+
target_definition.explicit_header_search_pod_names - target_definition.reject_header_search_pod_names
|
116
|
+
}.uniq
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module Pod
|
3
|
+
class Prebuild
|
4
|
+
|
5
|
+
# Check the targets, for the current limitation of the plugin
|
6
|
+
#
|
7
|
+
# @param [Array<PodTarget>] prebuilt_targets
|
8
|
+
def self.check_one_pod_should_have_only_one_target(prebuilt_targets)
|
9
|
+
|
10
|
+
targets_have_different_platforms = prebuilt_targets.select {|t| t.pod_name != t.name }
|
11
|
+
|
12
|
+
if targets_have_different_platforms.count > 0
|
13
|
+
names = targets_have_different_platforms.map(&:pod_name)
|
14
|
+
raw_names = targets_have_different_platforms.map(&:name)
|
15
|
+
message = "Oops, you came across a limitation of cocoapods-binary.
|
16
|
+
|
17
|
+
The plugin requires that one pod should have ONLY ONE target in the 'Pod.xcodeproj'. There are mainly 2 situations \
|
18
|
+
causing this problem:
|
19
|
+
|
20
|
+
1. One pod integrates in 2 or more different platforms' targets. e.g.
|
21
|
+
```
|
22
|
+
target 'iphoneApp' do
|
23
|
+
pod 'A', :binary => true
|
24
|
+
end
|
25
|
+
target 'watchApp' do
|
26
|
+
pod 'A'
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
2. Use different subspecs in multiple targets. e.g.
|
31
|
+
```
|
32
|
+
target 'iphoneApp' do
|
33
|
+
pod 'A/core'
|
34
|
+
pod 'A/network'
|
35
|
+
end
|
36
|
+
target 'iphoneAppTest' do
|
37
|
+
pod 'A/core'
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Related pods: #{names}, target names: #{raw_names}
|
42
|
+
"
|
43
|
+
raise Informative, message
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../helper/podfile_options'
|
2
|
+
|
3
|
+
module CocoapodsUtilHook
|
4
|
+
Pod::HooksManager.register('cocoapods-util', :pre_install) do |installer_context, _|
|
5
|
+
require_relative 'pre_install'
|
6
|
+
BinaryPrebuild::PreInstall.new(installer_context).run
|
7
|
+
end
|
8
|
+
|
9
|
+
Pod::HooksManager.register('cocoapods-util', :pre_integrate) do |context, _|
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
Pod::HooksManager.register('cocoapods-util', :post_install) do |context, _|
|
14
|
+
require_relative 'post_install'
|
15
|
+
BinaryPrebuild::PostInstall.new(context).run
|
16
|
+
end
|
17
|
+
|
18
|
+
Pod::HooksManager.register('cocoapods-util', :post_integrate) do |context, _|
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
Pod::HooksManager.register('cocoapods-util', :source_provider) do |context, _|
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module BinaryPrebuild
|
2
|
+
class PreInstall
|
3
|
+
def initialize(installer_context)
|
4
|
+
@installer_context = installer_context
|
5
|
+
end
|
6
|
+
|
7
|
+
def run
|
8
|
+
# [Check Environment]
|
9
|
+
podfile = @installer_context.podfile
|
10
|
+
podfile.target_definition_list.each do |target_definition|
|
11
|
+
if not target_definition.uses_frameworks?
|
12
|
+
STDERR.puts "[!] Cocoapods-binary requires `use_frameworks!`".red
|
13
|
+
exit
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require_relative '../targets/pod_target'
|
18
|
+
require_relative '../Intergation'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module BinaryPrebuild
|
2
|
+
class Sandbox
|
3
|
+
def initialize(path)
|
4
|
+
@sandbox_path = path
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.from_sandbox(sandbox)
|
8
|
+
root = sandbox.root
|
9
|
+
search_path = BinaryPrebuild.config.binary_dir
|
10
|
+
if !search_path.nil? && !search_path.empty?
|
11
|
+
path = File.expand_path(root + search_path)
|
12
|
+
if File.exist? path
|
13
|
+
return Sandbox.new(path)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def binary_dir
|
19
|
+
@binary_dir ||= Pathname.new(@sandbox_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def target_paths
|
23
|
+
return [] unless binary_dir.exist?
|
24
|
+
@targets ||= binary_dir.children().map do |target_path|
|
25
|
+
if target_path.directory? && (not target_path.children.empty?)
|
26
|
+
target_path
|
27
|
+
end
|
28
|
+
end.reject(&:nil?).uniq
|
29
|
+
@targets
|
30
|
+
end
|
31
|
+
|
32
|
+
def existed_target_names(name)
|
33
|
+
target_paths.select { |pair| "#{pair.basename}" == "#{name}" }.map { |pair| pair.basename }
|
34
|
+
end
|
35
|
+
|
36
|
+
def framework_folder_path_for_target_name(name)
|
37
|
+
target_paths.select { |pair| pair.basename == name }.last
|
38
|
+
end
|
39
|
+
|
40
|
+
def prebuild_vendored_frameworks(name)
|
41
|
+
target_path = target_paths.select { |pair| "#{pair.basename}" == "#{name}" }.last
|
42
|
+
return [] if target_path.nil?
|
43
|
+
|
44
|
+
configuration_enable = target_path.children().select { |path| "#{path.basename}" == 'Debug' || "#{path.basename}" == 'Release' }.count == 2
|
45
|
+
if configuration_enable
|
46
|
+
xcconfig_replace_path = BinaryPrebuild.config.xcconfig_replace_path
|
47
|
+
["#{xcconfig_replace_path}-Release/*.{framework,xcframework}"]
|
48
|
+
else
|
49
|
+
["*.{framework,xcframework}"]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def prebuild_bundles(name)
|
54
|
+
target_path = target_paths.select { |pair| "#{pair.basename}" == "#{name}" }.last
|
55
|
+
return [] if target_path.nil?
|
56
|
+
|
57
|
+
configuration_enable = target_path.children().select { |path| "#{path.basename}" == 'Debug' || "#{path.basename}" == 'Release' }.count == 2
|
58
|
+
if configuration_enable
|
59
|
+
xcconfig_replace_path = BinaryPrebuild.config.xcconfig_replace_path
|
60
|
+
["#{xcconfig_replace_path}-Release/*.bundle"]
|
61
|
+
else
|
62
|
+
["*.bundle"]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Pod
|
2
|
+
class Target
|
3
|
+
# @since 1.5.0
|
4
|
+
class BuildSettings
|
5
|
+
# missing framework header search paths
|
6
|
+
def missing_framework_header_search_path(pt)
|
7
|
+
return [] unless pt.frame_header_search_paths_enable?
|
8
|
+
|
9
|
+
paths = []
|
10
|
+
pt.file_accessors.each do |file_accessor|
|
11
|
+
# xcframeworks
|
12
|
+
greater_than_or_equal_to_1_10_0 = Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
|
13
|
+
greater_than_or_equal_to_1_11_0 = Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.11.0')
|
14
|
+
file_accessor.vendored_xcframeworks.map { |path|
|
15
|
+
if greater_than_or_equal_to_1_11_0
|
16
|
+
Xcode::XCFramework.new(file_accessor.spec.name, path)
|
17
|
+
else
|
18
|
+
Xcode::XCFramework.new(path)
|
19
|
+
end
|
20
|
+
}.each { |xcfwk|
|
21
|
+
xcfwk.slices.each { |slice|
|
22
|
+
fwk_name = slice.path.basename
|
23
|
+
if greater_than_or_equal_to_1_11_0
|
24
|
+
paths.push "${PODS_XCFRAMEWORKS_BUILD_DIR}/#{xcfwk.target_name}/#{fwk_name}/Headers"
|
25
|
+
elsif greater_than_or_equal_to_1_10_0
|
26
|
+
paths.push "${PODS_XCFRAMEWORKS_BUILD_DIR}/#{fwk_name.to_s.gsub(/\.framework$/, '')}/#{fwk_name}/Headers"
|
27
|
+
else
|
28
|
+
paths.push "${PODS_CONFIGURATION_BUILD_DIR}/#{fwk_name}/Headers"
|
29
|
+
end
|
30
|
+
}
|
31
|
+
}
|
32
|
+
# Cocoapods 1.9.x bugs
|
33
|
+
if Gem::Version.new(Pod::VERSION) < Gem::Version.new('1.10.0')
|
34
|
+
file_accessor.vendored_xcframeworks.each { |path|
|
35
|
+
Dir.glob("#{path.to_s}/**/*.framework").each do |fwk_path|
|
36
|
+
header_path = Pathname.new("#{fwk_path}/Headers")
|
37
|
+
next unless header_path.exist?
|
38
|
+
paths.push "${PODS_ROOT}/#{header_path.relative_path_from(pt.sandbox.root)}"
|
39
|
+
end
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
# frameworks
|
44
|
+
(file_accessor.vendored_frameworks - file_accessor.vendored_xcframeworks).each { |framework|
|
45
|
+
header_path = Pathname.new("#{framework}/Headers")
|
46
|
+
next unless header_path.exist?
|
47
|
+
paths.push "${PODS_ROOT}/#{header_path.relative_path_from(pt.sandbox.root)}"
|
48
|
+
}
|
49
|
+
end
|
50
|
+
replace_xcconfig_configuration_paths(paths)
|
51
|
+
paths.uniq
|
52
|
+
end
|
53
|
+
|
54
|
+
# replace different configuration xcconfig
|
55
|
+
def replace_xcconfig_configuration_paths(paths)
|
56
|
+
xcconfig_replace_path = BinaryPrebuild.config.xcconfig_replace_path
|
57
|
+
paths.map! { |path|
|
58
|
+
if path =~ /#{xcconfig_replace_path}-(Debug|Release)/
|
59
|
+
configuration = @configuration.to_s.downcase
|
60
|
+
if configuration == 'debug'
|
61
|
+
path.gsub!(/#{xcconfig_replace_path}-(Debug|Release)/, "#{xcconfig_replace_path}-Debug")
|
62
|
+
elsif configuration == 'release'
|
63
|
+
path.gsub!(/#{xcconfig_replace_path}-(Debug|Release)/, "#{xcconfig_replace_path}-Release")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
path
|
67
|
+
}
|
68
|
+
paths
|
69
|
+
end
|
70
|
+
|
71
|
+
# A subclass that generates build settings for a `PodTarget`
|
72
|
+
class AggregateTargetSettings
|
73
|
+
# @return [Array<String>]
|
74
|
+
alias_method :old_raw_header_search_paths, :_raw_header_search_paths
|
75
|
+
def _raw_header_search_paths
|
76
|
+
header_search_paths = old_raw_header_search_paths
|
77
|
+
header_search_paths.concat pod_targets.flat_map { |pt| missing_framework_header_search_path(pt) }
|
78
|
+
header_search_paths.uniq
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# A subclass that generates build settings for a {PodTarget}
|
83
|
+
class PodTargetSettings
|
84
|
+
# @return [Array<String>]
|
85
|
+
alias_method :old_raw_header_search_paths, :_raw_header_search_paths
|
86
|
+
def _raw_header_search_paths
|
87
|
+
header_search_paths = old_raw_header_search_paths
|
88
|
+
header_search_paths.concat dependent_targets.flat_map { |pt| missing_framework_header_search_path(pt) } if target.should_build?
|
89
|
+
header_search_paths.uniq
|
90
|
+
end
|
91
|
+
|
92
|
+
# 按照规则替换framework_search_paths,兼容不同的configuration
|
93
|
+
# 从编译上来说,仅仅替换了framework_search_paths的路径就够了
|
94
|
+
# @return [Array<String>]
|
95
|
+
alias_method :old_raw_framework_search_paths, :_raw_framework_search_paths
|
96
|
+
def _raw_framework_search_paths
|
97
|
+
framework_search_paths = old_raw_framework_search_paths
|
98
|
+
replace_xcconfig_configuration_paths(framework_search_paths)
|
99
|
+
framework_search_paths
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -67,10 +67,11 @@ module Pod
|
|
67
67
|
UI.puts " - SPEC REPO: ".yellow "#{repo_name}".green unless repo_name.nil?
|
68
68
|
|
69
69
|
# external sources
|
70
|
-
|
71
|
-
unless
|
72
|
-
|
73
|
-
|
70
|
+
external_sources = @lockfile.internal_data['EXTERNAL SOURCES']
|
71
|
+
unless external_sources.nil?
|
72
|
+
external_dict = external_sources[name]
|
73
|
+
UI.puts " - EXTERNAL SOURCES: ".yellow unless external_dict.nil?
|
74
|
+
external_dict.each { |key, value| UI.puts " - #{key}: ".yellow "#{value}".green } unless external_dict.nil?
|
74
75
|
end
|
75
76
|
|
76
77
|
# subspecs、dependencies、parents
|
@@ -78,23 +79,33 @@ module Pod
|
|
78
79
|
end
|
79
80
|
|
80
81
|
def show_moreinfo(name)
|
81
|
-
|
82
|
-
|
83
|
-
|
82
|
+
# checkout options
|
83
|
+
checkout_options = @lockfile.internal_data['CHECKOUT OPTIONS']
|
84
|
+
unless checkout_options.nil?
|
85
|
+
checkout_dict = checkout_options[name]
|
86
|
+
UI.puts " - CHECKOUT OPTIONS: ".yellow unless checkout_dict.nil?
|
87
|
+
checkout_dict.each { |key, value| UI.puts " - #{key}: ".yellow "#{value}".green } unless checkout_dict.nil?
|
88
|
+
end
|
89
|
+
|
90
|
+
subspecs, dependencies, parents = [], [], []
|
84
91
|
@lockfile.internal_data["PODS"].each { |item|
|
92
|
+
# 取遍历的pod名称
|
85
93
|
pod_name = item.keys.first if item.is_a?(Hash) && item.count == 1
|
86
94
|
pod_name = item if item.is_a?(String)
|
87
|
-
if pod_name =~ /^#{name}
|
88
|
-
subspecs.push(pod_name.match(/^[^\s]*/).to_s) if pod_name =~ /^#{name}
|
95
|
+
if pod_name =~ /^#{name}[\s\/]/ # 以#{name}开头,后跟一个'空格'或一个'/'
|
96
|
+
subspecs.push(pod_name.match(/^[^\s]*/).to_s) if pod_name =~ /^#{name}\// # 如果#{name}后跟的是'/',则是subspec
|
89
97
|
if item.is_a?(Hash)
|
90
98
|
item.each_value do |value|
|
99
|
+
# 如果不是以#{name}开头的,则是dependency
|
91
100
|
value.each {|dependency| dependencies.push(dependency.to_s) unless dependency =~ /^#{name}/ }
|
92
101
|
end
|
93
102
|
elsif item.is_a?(String)
|
103
|
+
# 如果不是以#{name}开头的,则是dependency
|
94
104
|
dependencies.push(item.to_s) unless item =~ /^#{name}/
|
95
105
|
end
|
96
106
|
else
|
97
107
|
next if pod_name.nil?
|
108
|
+
# 如果不是匹配到的pod名称,则检查是不是依赖了该pod
|
98
109
|
if item.is_a?(Hash)
|
99
110
|
item.each_value do |value|
|
100
111
|
value.each {|dependency| parents.push(pod_name.match(/^[^\s\/]*/).to_s) if dependency =~ /^#{name}/ }
|
@@ -102,12 +113,9 @@ module Pod
|
|
102
113
|
end
|
103
114
|
end
|
104
115
|
}
|
105
|
-
subspecs.uniq
|
106
|
-
dependencies.uniq
|
107
|
-
parents.uniq
|
108
|
-
UI.puts " - SUBSPECS: ".yellow "#{subspecs.join('、')}".green unless subspecs.empty?
|
109
|
-
UI.puts " - DEPENDENCIES: ".yellow "#{dependencies.join('、')}".green unless dependencies.empty?
|
110
|
-
UI.puts " - WHO DEPENDS ON IT: ".yellow "#{parents.join('、')}".green unless parents.empty?
|
116
|
+
UI.puts " - SUBSPECS: ".yellow "#{subspecs.uniq.join('、')}".green unless subspecs.empty?
|
117
|
+
UI.puts " - DEPENDENCIES: ".yellow "#{dependencies.uniq.join('、')}".green unless dependencies.empty?
|
118
|
+
UI.puts " - DEPENDS ON IT: ".yellow "#{parents.uniq.join('、')}".green unless parents.empty?
|
111
119
|
end
|
112
120
|
|
113
121
|
def pod_tags_info
|
@@ -118,10 +126,10 @@ module Pod
|
|
118
126
|
@lockfile.internal_data["PODS"].each do |item|
|
119
127
|
info = item.keys.first if item.is_a?(Hash) && item.count == 1
|
120
128
|
info = item if item.is_a?(String)
|
121
|
-
|
122
|
-
|
123
|
-
tag = info.match(/\(.*\)/)
|
124
|
-
@tags_info[name
|
129
|
+
name = info.match(/^[^\/\s]*/).to_s
|
130
|
+
unless @tags_info.keys.include?(name)
|
131
|
+
tag = info.match(/\(.*\)/).to_s
|
132
|
+
@tags_info[name] = tag unless tag.empty?
|
125
133
|
end
|
126
134
|
end
|
127
135
|
@tags_info
|
@@ -29,8 +29,8 @@ module Pod
|
|
29
29
|
default_build_settings = Hash.new
|
30
30
|
default_build_settings["CLANG_MODULES_AUTOLINK"] = "NO"
|
31
31
|
default_build_settings["GCC_GENERATE_DEBUGGING_SYMBOLS"] = "YES" # 生成Debug编译信息
|
32
|
-
default_build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64" unless @xcframework &&
|
33
|
-
default_build_settings["EXCLUDED_ARCHS[sdk=appletvsimulator*]"] = "arm64" unless @xcframework &&
|
32
|
+
default_build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64" # unless @xcframework && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.11')# 非xcframework排除ios simulator 64位架构
|
33
|
+
default_build_settings["EXCLUDED_ARCHS[sdk=appletvsimulator*]"] = "arm64" # unless @xcframework && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.11') # 非xcframework排除tvos simulator 64位架构
|
34
34
|
default_build_settings["BUILD_LIBRARY_FOR_DISTRIBUTION"] = "YES" # 编译swift生成swiftinterface文件
|
35
35
|
default_build_settings["CODE_SIGN_IDENTITY"] = "" if `xcodebuild -version`.lines.shift.gsub!('Xcode ', '') >= "14" #xcode版本大于等于xcode 14时需要添加
|
36
36
|
|
@@ -121,10 +121,6 @@ module Pod
|
|
121
121
|
|
122
122
|
Specification.from_file(@path)
|
123
123
|
end
|
124
|
-
|
125
|
-
def match_pod_version?(*version)
|
126
|
-
Gem::Dependency.new('', *version).match?('', Pod::VERSION)
|
127
|
-
end
|
128
124
|
end
|
129
125
|
end
|
130
126
|
end
|
@@ -15,16 +15,13 @@ module Pod
|
|
15
15
|
|
16
16
|
def self.options
|
17
17
|
[
|
18
|
-
['--force', '覆盖已经存在的文件']
|
19
|
-
['--create-swiftinterface', '有编译swift文件的framework,如果不包含swiftinterface则无法生成xcframework。
|
20
|
-
设置该参数会生成一个swiftinterface文件解决create失败的问题。']
|
18
|
+
['--force', '覆盖已经存在的文件']
|
21
19
|
]
|
22
20
|
end
|
23
21
|
|
24
22
|
def initialize(argv)
|
25
23
|
@file_path = argv.shift_argument
|
26
24
|
@force = argv.flag?('force')
|
27
|
-
@create_swiftinterface = argv.flag?('create-swiftinterface')
|
28
25
|
super
|
29
26
|
end
|
30
27
|
|
@@ -55,8 +52,7 @@ module Pod
|
|
55
52
|
|
56
53
|
builder = XCFrameworkBuilder.new(
|
57
54
|
framework_name,
|
58
|
-
source_dir
|
59
|
-
@create_swiftinterface
|
55
|
+
source_dir
|
60
56
|
)
|
61
57
|
builder.build_static_xcframework
|
62
58
|
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
module Pod
|
2
2
|
class XCFrameworkBuilder
|
3
|
-
def initialize(name, source_dir
|
3
|
+
def initialize(name, source_dir)
|
4
4
|
@name = name
|
5
5
|
@source_dir = source_dir
|
6
|
-
@create_swiftinterface = create_swiftinterface
|
7
6
|
end
|
8
7
|
|
9
8
|
def build_static_xcframework
|
@@ -57,7 +56,7 @@ module Pod
|
|
57
56
|
# 2. copy os framework
|
58
57
|
if os_archs.count > 0
|
59
58
|
path = Pathname.new("#{@source_dir}/#{os_target_path}")
|
60
|
-
path
|
59
|
+
FileUtils.mkdir_p(path) unless path.exist?
|
61
60
|
`cp -a #{framework_path} #{path}/`
|
62
61
|
|
63
62
|
fwk_path = "#{path}/#{@name}.framework"
|
@@ -67,7 +66,7 @@ module Pod
|
|
67
66
|
# 3. copy simulation framework
|
68
67
|
if sim_archs.count > 0
|
69
68
|
path = Pathname.new("#{@source_dir}/#{simulator_target_path}")
|
70
|
-
path
|
69
|
+
FileUtils.mkdir_p(path) unless path.exist?
|
71
70
|
`cp -a #{framework_path} #{path}/`
|
72
71
|
|
73
72
|
fwk_path = "#{path}/#{@name}.framework"
|
@@ -86,23 +85,8 @@ module Pod
|
|
86
85
|
def generate_xcframework(framework_paths)
|
87
86
|
UI.puts("Generate #{@name}.xcframework")
|
88
87
|
|
89
|
-
|
90
|
-
|
91
|
-
swiftmodule_path = Dir.glob("#{framework_path}/Modules/*.swiftmodule").first
|
92
|
-
unless swiftmodule_path.nil?
|
93
|
-
if Dir.glob("#{swiftmodule_path}/*.swiftinterface").empty?
|
94
|
-
unless @create_swiftinterface
|
95
|
-
UI.puts "Framework中包含swiftmodule文件,但是没有swiftinterface,无法创建xcframework,请检查Framework文件。或者使用`--create-swiftinterface`参数"
|
96
|
-
return
|
97
|
-
end
|
98
|
-
arm_swiftinterface = Pathname.new("#{swiftmodule_path}/arm.swiftinterface")
|
99
|
-
File.new(arm_swiftinterface, "w+").close
|
100
|
-
end
|
101
|
-
end
|
102
|
-
}
|
103
|
-
|
104
|
-
# build xcframework
|
105
|
-
command = "xcodebuild -create-xcframework -framework #{framework_paths.join(' -framework ')} -output #{@source_dir}/#{@name}.xcframework 2>&1"
|
88
|
+
# create xcframework
|
89
|
+
command = "xcodebuild -create-xcframework -allow-internal-distribution -framework #{framework_paths.join(' -framework ')} -output #{@source_dir}/#{@name}.xcframework 2>&1"
|
106
90
|
output = `#{command}`.lines.to_a
|
107
91
|
result = $?
|
108
92
|
# show error
|
@@ -115,19 +99,19 @@ module Pod
|
|
115
99
|
|
116
100
|
private
|
117
101
|
def clean_intermediate_path
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
102
|
+
file_path = "#{@source_dir}/#{temp_intermediate_path}"
|
103
|
+
FileUtils.rm_rf(file_path) if File.exist? file_path
|
104
|
+
end
|
105
|
+
|
106
|
+
def temp_intermediate_path
|
107
|
+
"__temp_create_xcframework_dir"
|
124
108
|
end
|
125
109
|
|
126
110
|
def os_target_path
|
127
|
-
"#{@name}
|
111
|
+
"#{temp_intermediate_path}/#{@name}_os"
|
128
112
|
end
|
129
113
|
def simulator_target_path
|
130
|
-
"#{@name}
|
114
|
+
"#{temp_intermediate_path}/#{@name}_simulator"
|
131
115
|
end
|
132
116
|
end
|
133
117
|
end
|
data/lib/cocoapods_plugin.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocoapods-util
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- guojiashuang
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cocoapods
|
@@ -68,7 +68,18 @@ files:
|
|
68
68
|
- LICENSE
|
69
69
|
- README.md
|
70
70
|
- lib/cocoapods-util.rb
|
71
|
-
- lib/cocoapods-util/
|
71
|
+
- lib/cocoapods-util/binary/Intergation.rb
|
72
|
+
- lib/cocoapods-util/binary/config.rb
|
73
|
+
- lib/cocoapods-util/binary/helper/names.rb
|
74
|
+
- lib/cocoapods-util/binary/helper/podfile_options.rb
|
75
|
+
- lib/cocoapods-util/binary/helper/target_checker.rb
|
76
|
+
- lib/cocoapods-util/binary/hooks/CocoapodsUtilHook.rb
|
77
|
+
- lib/cocoapods-util/binary/hooks/post_install.rb
|
78
|
+
- lib/cocoapods-util/binary/hooks/pre_install.rb
|
79
|
+
- lib/cocoapods-util/binary/main.rb
|
80
|
+
- lib/cocoapods-util/binary/podfile_dsl.rb
|
81
|
+
- lib/cocoapods-util/binary/prebuild.rb
|
82
|
+
- lib/cocoapods-util/binary/targets/pod_target.rb
|
72
83
|
- lib/cocoapods-util/command.rb
|
73
84
|
- lib/cocoapods-util/command/cocoapods-extend/extend.rb
|
74
85
|
- lib/cocoapods-util/command/cocoapods-extend/install.rb
|
@@ -90,16 +101,13 @@ files:
|
|
90
101
|
- lib/cocoapods-util/command/xcframework/xcframework.rb
|
91
102
|
- lib/cocoapods-util/command/xcframework/xcframework_build.rb
|
92
103
|
- lib/cocoapods-util/gem_version.rb
|
93
|
-
- lib/cocoapods-util/hooks/feature_switch.rb
|
94
|
-
- lib/cocoapods-util/hooks/installer.rb
|
95
|
-
- lib/cocoapods-util/hooks/prebuild_sandbox.rb
|
96
104
|
- lib/cocoapods-util/tool.rb
|
97
105
|
- lib/cocoapods_plugin.rb
|
98
106
|
homepage: https://github.com/CaryGo/cocoapods-util
|
99
107
|
licenses:
|
100
108
|
- MIT
|
101
109
|
metadata: {}
|
102
|
-
post_install_message:
|
110
|
+
post_install_message:
|
103
111
|
rdoc_options: []
|
104
112
|
require_paths:
|
105
113
|
- lib
|
@@ -115,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
123
|
version: '0'
|
116
124
|
requirements: []
|
117
125
|
rubygems_version: 3.1.2
|
118
|
-
signing_key:
|
126
|
+
signing_key:
|
119
127
|
specification_version: 4
|
120
128
|
summary: 一个常用插件功能的集合,致力于解决日常开发中遇到的一些问题。
|
121
129
|
test_files: []
|
@@ -1,63 +0,0 @@
|
|
1
|
-
module CocoapodsUtilHook
|
2
|
-
Pod::HooksManager.register('cocoapods-util', :pre_install) do |installer_context, _|
|
3
|
-
puts "pre_install"
|
4
|
-
require_relative 'hooks/feature_switch'
|
5
|
-
if Pod.is_prebuild_stage
|
6
|
-
next
|
7
|
-
end
|
8
|
-
|
9
|
-
# [Check Environment]
|
10
|
-
podfile = installer_context.podfile
|
11
|
-
# podfile.target_definition_list.each do |target_definition|
|
12
|
-
# # next if target_definition.prebuild_framework_pod_names.empty?
|
13
|
-
# # if not target_definition.uses_frameworks?
|
14
|
-
# # STDERR.puts "[!] Cocoapods-binary requires `use_frameworks!`".red
|
15
|
-
# # exit
|
16
|
-
# # end
|
17
|
-
# end
|
18
|
-
|
19
|
-
require_relative 'hooks/prebuild_sandbox'
|
20
|
-
|
21
|
-
# 读取update和repo_update参数
|
22
|
-
update = nil
|
23
|
-
repo_update = nil
|
24
|
-
include ObjectSpace
|
25
|
-
ObjectSpace.each_object(Pod::Installer) { |installer|
|
26
|
-
update = installer.update
|
27
|
-
repo_update = installer.repo_update
|
28
|
-
}
|
29
|
-
|
30
|
-
# switches setting
|
31
|
-
Pod.is_prebuild_stage = true
|
32
|
-
|
33
|
-
# make another custom sandbox
|
34
|
-
standard_sandbox = installer_context.sandbox
|
35
|
-
prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sandbox)
|
36
|
-
|
37
|
-
# get the podfile for prebuild
|
38
|
-
prebuild_podfile = Pod::Podfile.from_ruby(podfile.defined_in_file)
|
39
|
-
|
40
|
-
# install
|
41
|
-
lockfile = installer_context.lockfile
|
42
|
-
binary_installer = Pod::Installer.new(prebuild_sandbox, prebuild_podfile, lockfile)
|
43
|
-
|
44
|
-
binary_installer.update = update
|
45
|
-
binary_installer.repo_update = repo_update
|
46
|
-
# binary_installer.install!
|
47
|
-
|
48
|
-
# reset switches setting
|
49
|
-
Pod.is_prebuild_stage = false
|
50
|
-
end
|
51
|
-
Pod::HooksManager.register('cocoapods-util', :pre_integrate) do |context, _|
|
52
|
-
puts "pre_integrate"
|
53
|
-
end
|
54
|
-
Pod::HooksManager.register('cocoapods-util', :post_install) do |context, _|
|
55
|
-
puts "post_install"
|
56
|
-
end
|
57
|
-
Pod::HooksManager.register('cocoapods-util', :post_integrate) do |context, _|
|
58
|
-
puts "post_integrate"
|
59
|
-
end
|
60
|
-
Pod::HooksManager.register('cocoapods-util', :source_provider) do |context, _|
|
61
|
-
puts "source_provider"
|
62
|
-
end
|
63
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module Pod
|
2
|
-
class PrebuildSandbox < Sandbox
|
3
|
-
|
4
|
-
# [String] standard_sandbox_path
|
5
|
-
def self.from_standard_sanbox_path(path)
|
6
|
-
prebuild_sandbox_path = Pathname.new(path).realpath + "_Prebuild"
|
7
|
-
self.new(prebuild_sandbox_path)
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.from_standard_sandbox(sandbox)
|
11
|
-
self.from_standard_sanbox_path(sandbox.root)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|