Class: KZ::KZFrameworkManager
- Inherits:
-
Object
- Object
- KZ::KZFrameworkManager
- Defined in:
- lib/cocoapods-kz/helpers/kz_framework_manager.rb
Constant Summary collapse
- @@all_resources_cache_info =
{}
Class Method Summary collapse
- .contain_multiple_arch?(file_path) ⇒ Boolean
- .contain_x8664?(file_path) ⇒ Boolean
- .convert_arm64_to_simulator(origin_framework_path, destination_path) ⇒ Object
- .create_xcframework(origin_framework_path, origin_simulator_framework_path, framework_basename, destination_xcframework_path) ⇒ Object
- .handle_origin_framework(origin_frameworks, kz_pod_target) ⇒ Object
- .handle_origin_library(origin_libraries, kz_pod_target) ⇒ Object
- .is_current_ar_archive?(file_path) ⇒ Boolean
- .is_dynamic_library?(file_path) ⇒ Boolean
- .resources_cache_info ⇒ Object
- .validate_framework_and_get_result(kz_pod_target) ⇒ Object
Class Method Details
.contain_multiple_arch?(file_path) ⇒ Boolean
262 263 264 265 |
# File 'lib/cocoapods-kz/helpers/kz_framework_manager.rb', line 262 def self.contain_multiple_arch?(file_path) file_result = `lipo -info #{file_path}` return file_result.include?("Architectures in the fat file") end |
.contain_x8664?(file_path) ⇒ Boolean
257 258 259 260 |
# File 'lib/cocoapods-kz/helpers/kz_framework_manager.rb', line 257 def self.contain_x8664?(file_path) file_result = `file -b #{file_path}` return file_result.include?("for architecture x86_64") end |
.convert_arm64_to_simulator(origin_framework_path, destination_path) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/cocoapods-kz/helpers/kz_framework_manager.rb', line 94 def self.convert_arm64_to_simulator(origin_framework_path, destination_path) framework_name = origin_framework_path.basename.to_s if framework_name.end_with?(".framework") framework_basename = framework_name.chomp(".framework") xcframework_path = destination_path + "#{framework_basename}.xcframework" return xcframework_path if File.exist?(xcframework_path) && !Dir.empty?(xcframework_path) if self.create_xcframework(origin_framework_path, origin_framework_path, framework_basename, xcframework_path) return xcframework_path else return origin_framework_path end elsif framework_name.end_with?(".xcframework") framework_basename = framework_name.chomp(".xcframework") xcframework_path = destination_path + "#{framework_basename}.xcframework" return xcframework_path if File.exist?(xcframework_path) info_plist_path = origin_framework_path + "Info.plist" return origin_framework_path unless File.exist?(info_plist_path) info_plist = Xcodeproj::Plist.read_from_path(info_plist_path) available_libraries = info_plist["AvailableLibraries"] available_libraries.each do |available_librarie| if available_librarie["SupportedPlatformVariant"] == "simulator" && available_librarie["SupportedArchitectures"].include?("arm64") FileUtils.mkdir_p(destination_path) unless File.exist?(destination_path) FileUtils.cp_r(origin_framework_path, destination_path) return xcframework_path end end # 找到真机arm64 framework与模拟器x86_64 framework xc_framework_path = "" xc_simulator_framework_path = "" available_libraries.each do |available_librarie| if available_librarie["SupportedPlatformVariant"] == "simulator" if available_librarie["SupportedArchitectures"].include?("x86_64") xc_simulator_framework_path = origin_framework_path + available_librarie["LibraryIdentifier"] + available_librarie["LibraryPath"] end elsif available_librarie["SupportedPlatform"] == "ios" if available_librarie["SupportedArchitectures"].include?("arm64") xc_framework_path = origin_framework_path + available_librarie["LibraryIdentifier"] + available_librarie["LibraryPath"] end end end xc_simulator_framework_path = xc_framework_path unless xc_simulator_framework_path != "" if self.create_xcframework(xc_framework_path, xc_simulator_framework_path, framework_basename, xcframework_path) return xcframework_path else return origin_framework_path end else return origin_framework_path end end |
.create_xcframework(origin_framework_path, origin_simulator_framework_path, framework_basename, destination_xcframework_path) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/cocoapods-kz/helpers/kz_framework_manager.rb', line 150 def self.create_xcframework(origin_framework_path, origin_simulator_framework_path, framework_basename, destination_xcframework_path) tempdir = Pathname(Dir.mktmpdir) arm64_path = tempdir + "arm64" FileUtils.mkdir_p(arm64_path) arm64_framework_path = arm64_path + "#{framework_basename}.framework" FileUtils.cp_r(origin_framework_path, arm64_framework_path) arm64_framework_exe_path = arm64_framework_path + framework_basename if self.contain_multiple_arch?(arm64_framework_exe_path) KZLog.run_shell("lipo #{arm64_framework_exe_path} -thin arm64 -output #{arm64_framework_exe_path}") end simulator_path = tempdir + "simulator" FileUtils.mkdir_p(simulator_path) simulator_framework_path = simulator_path + "#{framework_basename}.framework" FileUtils.cp_r(origin_simulator_framework_path, simulator_framework_path) simulator_framework_exe_path = simulator_framework_path + framework_basename contain_x8664 = self.contain_x8664?(simulator_framework_exe_path) if contain_x8664 KZLog.run_shell("lipo #{simulator_framework_exe_path} -thin x86_64 -output #{simulator_framework_exe_path}") else FileUtils.rm(simulator_framework_exe_path) end temp_framwork_exe_path = tempdir + "#{framework_basename}_arm64_simulator" if self.is_dynamic_library?(origin_framework_path + framework_basename) KZLog.log("'#{origin_framework_path.basename}' 是一个动态库,开始做Load command转换") xcrun_vtool_show_result = `xcrun vtool -arch arm64 -show #{origin_framework_path + framework_basename}`.lines.map(&:chomp) framework_sdk_version = "16.0" framework_deployment_version = "12.0" reach_cmd_tag = false xcrun_vtool_show_result.each do |line| reach_cmd_tag = false if line.start_with?("Load command") line_infos = line.lstrip.split next unless line_infos.count == 2 if line_infos.first == "cmd" && line_infos.last == "LC_VERSION_MIN_IPHONEOS" reach_cmd_tag = true end if reach_cmd_tag if line_infos.include?("sdk") framework_sdk_version = line_infos.last elsif line_infos.include?("version") framework_deployment_version = line_infos.last end end end xcrun_vtool_set_result = KZLog.run_shell("xcrun vtool -arch arm64 -set-build-version 7 #{framework_deployment_version} #{framework_sdk_version} -replace -output #{temp_framwork_exe_path} #{arm64_framework_exe_path}") unless xcrun_vtool_set_result KZLog.log("'#{origin_framework_path.basename}' Load command转换转换失败", :warning) FileUtils.rm_r(tempdir) return false end else ar_x_path = tempdir + "ar_x" FileUtils.mkdir_p(ar_x_path) if self.is_current_ar_archive?(origin_framework_path + framework_basename) KZLog.log("'#{origin_framework_path.basename}' 是一个ar archive类型静态库,开始拆分.o并重新构建") ar_x_success = KZLog.run_shell("cd #{ar_x_path}; ar x #{arm64_framework_exe_path}") if ar_x_success Dir["#{ar_x_path}/*.o"].each do |file| status = KZLog.run_shell("#{ARM64_TO_SIMULATOR_EXECUTE_PATH} '#{file}'") unless status KZLog.log("'#{file}' 存在.o转换失败", :warning) FileUtils.rm_r(tempdir) return false end end KZLog.run_shell("ar crv #{temp_framwork_exe_path} #{ar_x_path}/*.o") else KZLog.log("'#{origin_framework_path.basename}' ar拆分失败", :warning) FileUtils.rm_r(tempdir) return false end else KZLog.log("'#{origin_framework_path.basename}' 是一个不支持转换的格式,arm64 simulator转换失败", :warning) FileUtils.rm_r(tempdir) return false end end if contain_x8664 KZLog.run_shell("lipo -create #{temp_framwork_exe_path} #{simulator_framework_exe_path} -output #{simulator_framework_exe_path}") else FileUtils.mv("#{temp_framwork_exe_path}", simulator_framework_exe_path) end FileUtils.mkdir_p(destination_xcframework_path) unless File.exist?(destination_xcframework_path) KZLog.run_shell("xcodebuild -create-xcframework -framework $(readlink -f '#{arm64_framework_path}') -framework $(readlink -f '#{simulator_framework_path}') -output #{destination_xcframework_path}") FileUtils.rm_r(tempdir) KZLog.log("'#{origin_framework_path.basename}'xcframework创建成功", :success) return true end |
.handle_origin_framework(origin_frameworks, kz_pod_target) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/cocoapods-kz/helpers/kz_framework_manager.rb', line 74 def self.handle_origin_framework(origin_frameworks, kz_pod_target) new_frameworks = [] old_destination_path = kz_pod_target.pod_config_cache_path(false , true) FileUtils.rm_rf(old_destination_path) if File.exist?(old_destination_path) destination_path = kz_pod_target.pod_config_cache_path(true, true) origin_frameworks.each do |origin_framework_path| if kz_pod_target.disable_to_simulator_frameworks.include?(origin_framework_path) new_frameworks.append(origin_framework_path) else new_framework_path = self.convert_arm64_to_simulator(origin_framework_path, destination_path) if new_framework_path == origin_framework_path kz_pod_target.disable_to_simulator_frameworks.append(origin_framework_path) end new_frameworks.append(new_framework_path) end end new_frameworks end |
.handle_origin_library(origin_libraries, kz_pod_target) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/cocoapods-kz/helpers/kz_framework_manager.rb', line 54 def self.handle_origin_library(origin_libraries, kz_pod_target) tempdir = Pathname(Dir.mktmpdir) lib_frameworks_path = tempdir + "lib_frameworks" FileUtils.mkdir_p(lib_frameworks_path) origin_lib_frameworks = [] origin_libraries.each do |origin_library_path| lib_framework_name = origin_library_path.basename(origin_library_path.extname) lib_framework_path = lib_frameworks_path + "#{lib_framework_name}.framework" FileUtils.mkdir_p(lib_framework_path) FileUtils.cp(origin_library_path, lib_framework_path + lib_framework_name) origin_lib_frameworks.append(lib_framework_path) end new_frameworks = handle_origin_framework(origin_lib_frameworks, kz_pod_target) FileUtils.rm_r(tempdir) new_frameworks end |
.is_current_ar_archive?(file_path) ⇒ Boolean
252 253 254 255 |
# File 'lib/cocoapods-kz/helpers/kz_framework_manager.rb', line 252 def self.is_current_ar_archive?(file_path) file_result = `file -b #{file_path}` return file_result.include?("current ar archive") end |
.is_dynamic_library?(file_path) ⇒ Boolean
247 248 249 250 |
# File 'lib/cocoapods-kz/helpers/kz_framework_manager.rb', line 247 def self.is_dynamic_library?(file_path) file_result = `file -b #{file_path}` return file_result.include?("dynamically linked shared library") end |
.resources_cache_info ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/cocoapods-kz/helpers/kz_framework_manager.rb', line 22 def self.resources_cache_info if @@all_resources_cache_info.count > 0 return @@all_resources_cache_info end Dir.foreach(KZ_POD_CONFIG_POD_TARGETS) do |folder_name| next if folder_name == '.' || folder_name == '..' || folder_name == '.DS_Store' config_folder = KZ_POD_CONFIG_POD_TARGETS + folder_name if File.directory?(config_folder) Dir.foreach(config_folder) do |version| next if version == '.' || version == '..' || version == '.DS_Store' || version == 'Headers' version_folder = config_folder + version if File.directory?(version_folder) have_framework = false Dir.foreach(version_folder) do |file_name| next if file_name == '.' || file_name == '..' || file_name == '.DS_Store' if file_name.end_with?(".xcframework") && File.directory?(version_folder + file_name) have_framework = true break end end @@all_resources_cache_info["#{folder_name}_#{version}"] = version_folder if have_framework end end end end @@all_resources_cache_info end |
.validate_framework_and_get_result(kz_pod_target) ⇒ Object
12 13 14 15 16 17 18 19 20 |
# File 'lib/cocoapods-kz/helpers/kz_framework_manager.rb', line 12 def self.validate_framework_and_get_result(kz_pod_target) resources_cache_info = self.resources_cache_info resource_path = resources_cache_info["#{kz_pod_target.name}_#{kz_pod_target.version}"] return nil unless resource_path result = KZConfigResult.new(kz_pod_target) result.resource_path = resource_path result end |