cocoapods-kz 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46e0c9230296bcc63a1a7dc8c0049a03047d9c9458329fcd447518efb667a7de
4
- data.tar.gz: 7d9504733bbec7908497dae4aaa3575042310cf435efc156dac2fbaffbd358fa
3
+ metadata.gz: 6c9619f1947bb18ec49029b61641468d7f9df706184017ec8e77d2b17d1a58d0
4
+ data.tar.gz: dce63b4ca62cea830b0104106f92166ac0fa9b7d00e0110378f32efe4d43fe94
5
5
  SHA512:
6
- metadata.gz: 58ea2d44a9f3c144dd8bb4a5b3e31a469a9027ef59ad51dec6bd681ea36114ed751451393e739dbd583f4904118edb116ece715a3044de12a24bc11f709a6bb9
7
- data.tar.gz: 8c0ad50abe85677d019d292bc8cfde63376a6e12b8e9ba36b09a3ceb15584606aef5578b18279f4369f2be9e6318cd16a227381a2d4da12451f892c3293dbb20
6
+ metadata.gz: 349028d335d34a1d9b186d61e377c78feb03ebe4447136970e469f192ec6e7bf785026fa2420fd31714f7c9172abdb14f533ceb8e090a13accba984ea116198b
7
+ data.tar.gz: 646ca98a19160714c566e70f64b1f822f6a05e9f1531c1970ec0e89534198054c71e2c2b24659cb747cfb2c8592a6a79c335d1ff6f29f504f604cc9368186bbe
@@ -1,5 +1,5 @@
1
1
  module CocoapodsKz
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.4"
3
3
  end
4
4
 
5
5
  module Pod
@@ -98,7 +98,7 @@ module KZ
98
98
  xcframework_path = destination_path + "#{framework_basename}.xcframework"
99
99
  return xcframework_path if File.exist?(xcframework_path) && !Dir.empty?(xcframework_path)
100
100
 
101
- if self.create_xcframework(origin_framework_path, origin_framework_path, framework_basename, xcframework_path)
101
+ if self.create_xcframework(origin_framework_path, framework_basename, xcframework_path)
102
102
  return xcframework_path
103
103
  else
104
104
  return origin_framework_path
@@ -121,34 +121,47 @@ module KZ
121
121
  end
122
122
  end
123
123
 
124
- # 找到真机arm64 framework与模拟器x86_64 framework
124
+ # 找到真机arm64 framework
125
125
  xc_framework_path = ""
126
- xc_simulator_framework_path = ""
127
126
  available_libraries.each do |available_librarie|
128
- if available_librarie["SupportedPlatformVariant"] == "simulator"
129
- if available_librarie["SupportedArchitectures"].include?("x86_64")
130
- xc_simulator_framework_path = origin_framework_path + available_librarie["LibraryIdentifier"] + available_librarie["LibraryPath"]
127
+ if available_librarie["SupportedPlatform"] == "ios"
128
+ if available_librarie["SupportedArchitectures"].include?("arm64")
129
+ xc_framework_path = origin_framework_path + available_librarie["LibraryIdentifier"] + available_librarie["LibraryPath"]
131
130
  end
132
- elsif available_librarie["SupportedPlatform"] == "ios"
133
- if available_librarie["SupportedArchitectures"].include?("arm64")
134
- xc_framework_path = origin_framework_path + available_librarie["LibraryIdentifier"] + available_librarie["LibraryPath"]
135
- end
136
131
  end
137
132
  end
138
133
 
139
- xc_simulator_framework_path = xc_framework_path unless xc_simulator_framework_path != ""
140
- if self.create_xcframework(xc_framework_path, xc_simulator_framework_path, framework_basename, xcframework_path)
141
- return xcframework_path
142
- else
134
+ if xc_framework_path == "" || !self.create_xcframework(xc_framework_path, framework_basename, xcframework_path)
143
135
  return origin_framework_path
136
+ else
137
+ return xcframework_path
144
138
  end
145
139
  else
146
140
  return origin_framework_path
147
141
  end
148
142
  end
149
143
 
150
- def self.create_xcframework(origin_framework_path, origin_simulator_framework_path, framework_basename, destination_xcframework_path)
144
+ # 将 xcframework slice 中直接提供的 .a 包装成 create_xcframework 可处理的 .framework。
145
+ # 除了静态库本身,也保留同级目录中的 Headers、Modules 等支持文件。
146
+ def self.convert_static_library_to_framework(origin_library_path, framework_basename, destination_path)
147
+ return origin_library_path unless File.extname(origin_library_path.to_s) == ".a"
148
+
149
+ framework_path = destination_path + "#{framework_basename}.framework"
150
+ framework_library_path = framework_path + origin_library_path.basename
151
+ framework_executable_path = framework_path + framework_basename
152
+ FileUtils.mkdir_p(framework_path)
153
+ Dir.children(origin_library_path.parent).each do |entry|
154
+ FileUtils.cp_r(origin_library_path.parent + entry, framework_path)
155
+ end
156
+ FileUtils.mv(framework_library_path, framework_executable_path)
157
+ KZLog.log("'#{origin_library_path.basename}' 已包装为 framework,继续创建 xcframework")
158
+ framework_path
159
+ end
160
+
161
+ def self.create_xcframework(origin_framework_path, framework_basename, destination_xcframework_path)
151
162
  tempdir = Pathname(Dir.mktmpdir)
163
+ origin_framework_path = self.convert_static_library_to_framework(origin_framework_path, framework_basename, tempdir + "origin")
164
+
152
165
  arm64_path = tempdir + "arm64"
153
166
  FileUtils.mkdir_p(arm64_path)
154
167
  arm64_framework_path = arm64_path + "#{framework_basename}.framework"
@@ -161,20 +174,14 @@ module KZ
161
174
  simulator_path = tempdir + "simulator"
162
175
  FileUtils.mkdir_p(simulator_path)
163
176
  simulator_framework_path = simulator_path + "#{framework_basename}.framework"
164
- FileUtils.cp_r(origin_simulator_framework_path, simulator_framework_path)
177
+ FileUtils.cp_r(arm64_framework_path, simulator_framework_path)
165
178
  simulator_framework_exe_path = simulator_framework_path + framework_basename
166
- contain_x8664 = self.contain_x8664?(simulator_framework_exe_path)
167
- if contain_x8664
168
- KZLog.run_shell("lipo #{simulator_framework_exe_path} -thin x86_64 -output #{simulator_framework_exe_path}")
169
- else
170
- FileUtils.rm(simulator_framework_exe_path)
171
- end
172
179
 
173
180
  temp_framwork_exe_path = tempdir + "#{framework_basename}_arm64_simulator"
174
- if self.is_dynamic_library?(origin_framework_path + framework_basename)
181
+ if self.is_dynamic_library?(arm64_framework_exe_path)
175
182
  KZLog.log("'#{origin_framework_path.basename}' 是一个动态库,开始做Load command转换")
176
183
 
177
- xcrun_vtool_show_result = `xcrun vtool -arch arm64 -show #{origin_framework_path + framework_basename}`.lines.map(&:chomp)
184
+ xcrun_vtool_show_result = `xcrun vtool -arch arm64 -show #{arm64_framework_exe_path}`.lines.map(&:chomp)
178
185
  framework_sdk_version = "16.0"
179
186
  framework_deployment_version = "12.0"
180
187
  reach_cmd_tag = false
@@ -205,8 +212,8 @@ module KZ
205
212
  else
206
213
  ar_x_path = tempdir + "ar_x"
207
214
  FileUtils.mkdir_p(ar_x_path)
208
- if self.is_current_ar_archive?(origin_framework_path + framework_basename)
209
- KZLog.log("'#{origin_framework_path.basename}' 是一个ar archive类型静态库,开始拆分.o并重新构建")
215
+ if self.is_current_ar_archive?(arm64_framework_exe_path)
216
+ KZLog.log("'#{arm64_framework_path.basename}' 是一个ar archive类型静态库,开始拆分.o并重新构建")
210
217
 
211
218
  ar_x_success = KZLog.run_shell("cd #{ar_x_path}; ar x #{arm64_framework_exe_path}")
212
219
  if ar_x_success
@@ -232,11 +239,7 @@ module KZ
232
239
  end
233
240
  end
234
241
 
235
- if contain_x8664
236
- KZLog.run_shell("lipo -create #{temp_framwork_exe_path} #{simulator_framework_exe_path} -output #{simulator_framework_exe_path}")
237
- else
238
- FileUtils.mv("#{temp_framwork_exe_path}", simulator_framework_exe_path)
239
- end
242
+ FileUtils.mv("#{temp_framwork_exe_path}", simulator_framework_exe_path)
240
243
  FileUtils.mkdir_p(destination_xcframework_path) unless File.exist?(destination_xcframework_path)
241
244
  KZLog.run_shell("xcodebuild -create-xcframework -framework $(readlink -f '#{arm64_framework_path}') -framework $(readlink -f '#{simulator_framework_path}') -output #{destination_xcframework_path}")
242
245
  FileUtils.rm_r(tempdir)
@@ -254,11 +257,6 @@ module KZ
254
257
  return file_result.include?("current ar archive")
255
258
  end
256
259
 
257
- def self.contain_x8664?(file_path)
258
- file_result = `file -b #{file_path}`
259
- return file_result.include?("for architecture x86_64")
260
- end
261
-
262
260
  def self.contain_multiple_arch?(file_path)
263
261
  file_result = `lipo -info #{file_path}`
264
262
  return file_result.include?("Architectures in the fat file")
@@ -13,7 +13,7 @@ module KZ
13
13
  }
14
14
 
15
15
  def self.log(log_string, type = :normal, skip_count = 1)
16
- if KZGlobalHelper.instance.debug || type == :error || type == :warning
16
+ if KZGlobalHelper.instance.debug || type == :error
17
17
  loc = caller_locations(skip_count, 1).first
18
18
  puts "#{loc.path}:#{loc.lineno} ⬇️"
19
19
  puts "\e[36m【Cocoapods-kz】\e[0m#{@log_types[type]}【#{type}】#{@log_types[:reset]}#{log_string}"
@@ -24,7 +24,7 @@ module KZ
24
24
  stdout, stderr, status = Open3.capture3(cmd)
25
25
 
26
26
  self.log(stdout, :normal, 2) unless stdout.empty?
27
- self.log(stderr, :error, 2) unless stderr.empty?
27
+ self.log(stderr, status.success? ? :warning : :error, 2) unless stderr.empty?
28
28
 
29
29
  return status.success?
30
30
  end
@@ -14,13 +14,13 @@ module Pod
14
14
 
15
15
  xcframeworks = target.xcframeworks.values.flatten
16
16
 
17
- kz_pod_target = target.weakRef_kz_pod_target
18
- if kz_pod_target&.have_same_root
19
- # 如果产物相同,极大可能为sub pod模式,xcframework有相同处理指令,导致并发执行rsync报错
20
- # 这里延迟0.2秒可以极大减少这种错误产生
17
+ # XCFramework 的输出目录由 xcframework.target_name 决定,不能只根据
18
+ # have_same_root 判断是否冲突:首个同名 target 或其他 root pod 也可能复制到
19
+ # 同一个 destination。所有 Copy XCFramework 脚本都加 destination 级别的锁;
20
+ # 不同 destination 的复制仍可并行。
21
+ unless xcframeworks.empty?
21
22
  script_content = File.read(target.copy_xcframeworks_script_path)
22
- new_script_content = script_content.sub(/(install_xcframework "\$\{PODS_ROOT})/, "sleep 0.2\n\\1")
23
- File.write(target.copy_xcframeworks_script_path, new_script_content)
23
+ File.write(target.copy_xcframeworks_script_path, kz_lock_xcframework_rsync(script_content))
24
24
  end
25
25
 
26
26
  if use_input_output_paths? && !xcframeworks.empty?
@@ -64,6 +64,30 @@ module Pod
64
64
  native_target, script_path, input_paths_by_config, output_paths_by_config)
65
65
  end
66
66
  end
67
+
68
+ # 保留 CocoaPods 原始 rsync 命令,仅在执行前插入 destination 级别的文件锁。
69
+ # 不同 destination 可并行复制;同一 destination 的多个脚本会串行执行。
70
+ def kz_lock_xcframework_rsync(script_content)
71
+ lock_marker = '# COCOAPODS_KZ_XCFRAMEWORK_RSYNC_LOCK'
72
+ return script_content if script_content.include?(lock_marker)
73
+
74
+ rsync_pattern = /^([ \t]*)(rsync\s+--delete\b[^\r\n]*)$/
75
+ match = rsync_pattern.match(script_content)
76
+ unless match
77
+ raise 'Unable to locate the XCFramework rsync command for the copy lock patch.'
78
+ end
79
+
80
+ indent = match[1]
81
+ rsync_command = match[2]
82
+ locked_command = [
83
+ "#{indent}#{lock_marker}",
84
+ "#{indent}# Serialize only copies that share the same XCFramework destination.",
85
+ "#{indent}local lock_file=\"${PODS_XCFRAMEWORKS_BUILD_DIR}/.cocoapods-kz-xcframeworks-$(printf '%s' \"${destination}\" | shasum -a 256 | awk '{print $1}').lock\"",
86
+ "#{indent}/usr/bin/lockf -k -w \"${lock_file}\" #{rsync_command}",
87
+ ].join("\n")
88
+
89
+ script_content.sub(rsync_pattern, locked_command)
90
+ end
67
91
  end
68
92
  end
69
93
  end
@@ -54,7 +54,8 @@ module Pod
54
54
  xcconfig.attributes['USE_HEADERMAP'] = 'NO'
55
55
  xcconfig.attributes["KZ_POD_CONFIG_ROOT"] = KZ::KZ_POD_CONFIG_ROOT_STR
56
56
  if KZ::KZGlobalHelper.instance.arm64_simulator
57
- xcconfig.attributes.delete("EXCLUDED_ARCHS[sdk=iphonesimulator*]")
57
+ xcconfig.attributes.delete_if { |key, _value| key.to_s.start_with?("VALID_ARCHS") }
58
+ xcconfig.attributes.delete_if { |key, _value| key.to_s.start_with?("EXCLUDED_ARCHS") }
58
59
  xcconfig.attributes['VALID_ARCHS'] = 'arm64 arm64_32 x86_64'
59
60
  end
60
61
  if KZ::KZGlobalHelper.instance.on_demand_resources_info.odr_target_names.include?(self.target.name.sub('Pods-', ''))
@@ -98,7 +99,8 @@ module Pod
98
99
  xcconfig.attributes['KZ_FIX_FORCE_LOAD_EXE_FOLDER'] = kz_pod_target.configuration_build_dir(true)
99
100
  end
100
101
  if KZ::KZGlobalHelper.instance.arm64_simulator
101
- xcconfig.attributes.delete("EXCLUDED_ARCHS[sdk=iphonesimulator*]")
102
+ xcconfig.attributes.delete_if { |key, _value| key.to_s.start_with?("VALID_ARCHS") }
103
+ xcconfig.attributes.delete_if { |key, _value| key.to_s.start_with?("EXCLUDED_ARCHS") }
102
104
  xcconfig.attributes['VALID_ARCHS'] = 'arm64 arm64_32 x86_64'
103
105
  end
104
106
 
@@ -4,9 +4,11 @@ if [ "${MACH_O_TYPE}" != "staticlib" ]; then
4
4
  exit 0
5
5
  fi
6
6
 
7
+ XCFRAMEWORK_OUTPUT="${KZ_FRAMEWORK_CACHE_PATH}/${PRODUCT_NAME}.xcframework"
8
+
7
9
  if [ -d "${KZ_FRAMEWORK_CACHE_PATH}" ]; then
8
- if [ -d "${KZ_FRAMEWORK_CACHE_PATH}/${PRODUCT_NAME}.xcframework" ]; then
9
- rm -r "${KZ_FRAMEWORK_CACHE_PATH}/${PRODUCT_NAME}.xcframework"
10
+ if [ -d "${XCFRAMEWORK_OUTPUT}" ]; then
11
+ rm -r "${XCFRAMEWORK_OUTPUT}"
10
12
  fi
11
13
  else
12
14
  mkdir -p "${KZ_FRAMEWORK_CACHE_PATH}"
@@ -34,10 +36,59 @@ if [ "${OPPOSE_PLATFORM_NAME}" = "" ]; then
34
36
  fi
35
37
 
36
38
  OPPOSE_PRODUCT_FULL_DIR=${PODS_BUILD_DIR}/${CONFIGURATION}-${OPPOSE_PLATFORM_NAME}/${TARGET_NAME}/${FULL_PRODUCT_NAME}
37
- if [ -d "${OPPOSE_PRODUCT_FULL_DIR}" ]; then
38
- xcodebuild -create-xcframework -allow-internal-distribution -framework $(readlink -f "${CURRENT_PRODUCT_DIR}/${FULL_PRODUCT_NAME}") -framework $(readlink -f "${OPPOSE_PRODUCT_FULL_DIR}") \
39
- -output "${KZ_FRAMEWORK_CACHE_PATH}/${PRODUCT_NAME}.xcframework"
40
- else
41
- xcodebuild -create-xcframework -allow-internal-distribution -framework $(readlink -f "${CURRENT_PRODUCT_DIR}/${FULL_PRODUCT_NAME}") \
42
- -output "${KZ_FRAMEWORK_CACHE_PATH}/${PRODUCT_NAME}.xcframework"
39
+ OPPOSE_BINARY="${OPPOSE_PRODUCT_FULL_DIR}/${PRODUCT_NAME}"
40
+
41
+ resolve_framework_path() {
42
+ local FRAMEWORK_PATH="$1"
43
+ local RESOLVED_PATH
44
+ RESOLVED_PATH=$(readlink -f "${FRAMEWORK_PATH}" 2>/dev/null)
45
+ if [ $? -ne 0 ] || [ -z "${RESOLVED_PATH}" ] || [ ! -d "${RESOLVED_PATH}" ]; then
46
+ return 1
47
+ fi
48
+ echo "${RESOLVED_PATH}"
49
+ }
50
+
51
+ remove_xcframework_output() {
52
+ if [ -d "${XCFRAMEWORK_OUTPUT}" ]; then
53
+ rm -r "${XCFRAMEWORK_OUTPUT}"
54
+ fi
55
+ }
56
+
57
+ create_single_platform_xcframework() {
58
+ remove_xcframework_output
59
+ xcodebuild -create-xcframework -allow-internal-distribution \
60
+ -framework "${CURRENT_FRAMEWORK_PATH}" \
61
+ -output "${XCFRAMEWORK_OUTPUT}"
62
+ }
63
+
64
+ if ! CURRENT_FRAMEWORK_PATH=$(resolve_framework_path "${CURRENT_PRODUCT_DIR}/${FULL_PRODUCT_NAME}"); then
65
+ echo "error: [KZ] Unable to resolve current platform framework: ${CURRENT_PRODUCT_DIR}/${FULL_PRODUCT_NAME}" >&2
66
+ exit 1
67
+ fi
68
+
69
+ CURRENT_BINARY="${CURRENT_FRAMEWORK_PATH}/${PRODUCT_NAME}"
70
+ if [ ! -f "${CURRENT_BINARY}" ] || [ ! -r "${CURRENT_BINARY}" ]; then
71
+ echo "error: [KZ] Current platform framework binary is unavailable: ${CURRENT_BINARY}" >&2
72
+ exit 1
73
+ fi
74
+
75
+ if [ -f "${OPPOSE_BINARY}" ] && [ -r "${OPPOSE_BINARY}" ]; then
76
+ if OPPOSE_FRAMEWORK_PATH=$(resolve_framework_path "${OPPOSE_PRODUCT_FULL_DIR}"); then
77
+ if xcodebuild -create-xcframework -allow-internal-distribution \
78
+ -framework "${CURRENT_FRAMEWORK_PATH}" \
79
+ -framework "${OPPOSE_FRAMEWORK_PATH}" \
80
+ -output "${XCFRAMEWORK_OUTPUT}"; then
81
+ exit 0
82
+ fi
83
+ echo "warning: [KZ] Failed to create a dual-platform xcframework; falling back to the current platform only: ${OPPOSE_FRAMEWORK_PATH}" >&2
84
+ else
85
+ echo "warning: [KZ] Unable to resolve the opposite platform framework; falling back to the current platform only: ${OPPOSE_PRODUCT_FULL_DIR}" >&2
86
+ fi
87
+ elif [ -d "${OPPOSE_PRODUCT_FULL_DIR}" ]; then
88
+ echo "warning: [KZ] Opposite platform framework binary is unavailable; falling back to the current platform only: ${OPPOSE_BINARY}" >&2
89
+ fi
90
+
91
+ if ! create_single_platform_xcframework; then
92
+ echo "error: [KZ] Failed to create a current-platform xcframework: ${CURRENT_FRAMEWORK_PATH}" >&2
93
+ exit 1
43
94
  fi
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoapods-kz
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - yixiong