Class: GoNative::Plugins::IOS::BuildFramework
- Inherits:
-
Object
- Object
- GoNative::Plugins::IOS::BuildFramework
- Extended by:
- DSL::Serviceable
- Defined in:
- lib/gonative/plugins/ios/build_framework.rb
Instance Attribute Summary collapse
-
#archs ⇒ Object
readonly
Returns the value of attribute archs.
-
#persist_build_dir ⇒ Object
readonly
Returns the value of attribute persist_build_dir.
-
#project_root ⇒ Object
readonly
Returns the value of attribute project_root.
Instance Method Summary collapse
- #archive_commands ⇒ Object
- #archive_framework! ⇒ Object
- #build_framework_with_tuist! ⇒ Object
- #call ⇒ Object
- #classes_root_path ⇒ Object
- #cleanup_build_dir ⇒ Object
- #create_xcframework_command ⇒ Object
- #device_archive_path ⇒ Object
- #device_dsym_path ⇒ Object
- #device_framework_path ⇒ Object
- #ensure_public_umbrella_header!(project, target) ⇒ Object
- #frameworks_dir ⇒ Object
- #generate_module_artifacts! ⇒ Object
- #generate_tuist_project! ⇒ Object
- #header_import_paths ⇒ Object
-
#initialize(archs, persist_build_dir, project_root = FileUtils.pwd) ⇒ BuildFramework
constructor
A new instance of BuildFramework.
- #modulemap_contents ⇒ Object
- #modulemap_path ⇒ Object
- #modulemap_project_setting_path ⇒ Object
- #move_xcframework_to_frameworks! ⇒ Object
- #patch_build_settings!(config) ⇒ Object
- #patch_generated_project! ⇒ Object
- #plugin_name ⇒ Object
- #simulator_archive_path ⇒ Object
- #simulator_dsym_path ⇒ Object
- #simulator_framework_path ⇒ Object
- #tuist_project? ⇒ Boolean
- #tuist_workspace_path ⇒ Object
- #umbrella_header_contents ⇒ Object
- #umbrella_header_path ⇒ Object
- #xcframework_output_path ⇒ Object
- #xcodebuild_archive_command(destination:, archive_path:, sdk:, archs_override: false) ⇒ Object
- #xcodeproj_path ⇒ Object
Constructor Details
#initialize(archs, persist_build_dir, project_root = FileUtils.pwd) ⇒ BuildFramework
Returns a new instance of BuildFramework.
18 19 20 21 22 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 18 def initialize(archs, persist_build_dir, project_root = FileUtils.pwd) @archs = archs.gsub(',', ' ') @persist_build_dir = persist_build_dir @project_root = File.(project_root) end |
Instance Attribute Details
#archs ⇒ Object (readonly)
Returns the value of attribute archs.
16 17 18 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 16 def archs @archs end |
#persist_build_dir ⇒ Object (readonly)
Returns the value of attribute persist_build_dir.
16 17 18 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 16 def persist_build_dir @persist_build_dir end |
#project_root ⇒ Object (readonly)
Returns the value of attribute project_root.
16 17 18 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 16 def project_root @project_root end |
Instance Method Details
#archive_commands ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 130 def archive_commands [ xcodebuild_archive_command( destination: "generic/platform=iOS Simulator", archive_path: simulator_archive_path, sdk: "iphonesimulator", archs_override: true ), xcodebuild_archive_command( destination: "generic/platform=iOS", archive_path: device_archive_path, sdk: "iphoneos" ), create_xcframework_command, %(rm -rf #{Shellwords.escape(simulator_archive_path)} #{Shellwords.escape(device_archive_path)}) ].join(' && ') end |
#archive_framework! ⇒ Object
121 122 123 124 125 126 127 128 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 121 def archive_framework! FileUtils.rm_rf(simulator_archive_path) FileUtils.rm_rf(device_archive_path) return if system(archive_commands) raise Error, 'Error building framework with Tuist. Please run the generated archive commands manually to inspect the failure' end |
#build_framework_with_tuist! ⇒ Object
36 37 38 39 40 41 42 43 44 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 36 def build_framework_with_tuist! FileUtils.cd(project_root) FileUtils.mkdir_p(File.join('.build', 'Frameworks')) generate_module_artifacts! generate_tuist_project! patch_generated_project! archive_framework! move_xcframework_to_frameworks! end |
#call ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 24 def call original_dir = FileUtils.pwd raise Error, "No Project.swift found in #{project_root}" unless tuist_project? build_framework_with_tuist! ensure FileUtils.cd(original_dir) if original_dir && File.directory?(original_dir) cleanup_build_dir unless persist_build_dir end |
#classes_root_path ⇒ Object
233 234 235 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 233 def classes_root_path File.join(project_root, 'Classes') end |
#cleanup_build_dir ⇒ Object
209 210 211 212 213 214 215 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 209 def cleanup_build_dir FileUtils.rm_rf(File.join(project_root, '.build')) FileUtils.rm_rf(File.join(project_root, "#{plugin_name}.xcodeproj")) FileUtils.rm_rf(File.join(project_root, "#{plugin_name}.xcworkspace")) FileUtils.rm_f(File.join(project_root, "#{plugin_name}.modulemap")) FileUtils.rm_f(File.join(project_root, "#{plugin_name}-umbrella.h")) end |
#create_xcframework_command ⇒ Object
148 149 150 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 148 def create_xcframework_command %(xcodebuild -create-xcframework -framework #{Shellwords.escape(simulator_framework_path)} -debug-symbols #{Shellwords.escape(simulator_dsym_path)} -framework #{Shellwords.escape(device_framework_path)} -debug-symbols #{Shellwords.escape(device_dsym_path)} -output #{Shellwords.escape(xcframework_output_path)}) end |
#device_archive_path ⇒ Object
185 186 187 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 185 def device_archive_path File.join('.build', 'Frameworks', 'iOS.xcarchive') end |
#device_dsym_path ⇒ Object
205 206 207 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 205 def device_dsym_path File.(File.join(device_archive_path, 'dSYMs', "#{plugin_name}.framework.dSYM"), project_root) end |
#device_framework_path ⇒ Object
197 198 199 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 197 def device_framework_path File.(File.join(device_archive_path, 'Products', 'Library', 'Frameworks', "#{plugin_name}.framework"), project_root) end |
#ensure_public_umbrella_header!(project, target) ⇒ Object
111 112 113 114 115 116 117 118 119 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 111 def ensure_public_umbrella_header!(project, target) relative_header_path = File.basename(umbrella_header_path) file_reference = project.files.find { |file| file.path == relative_header_path } || project.main_group.new_file(relative_header_path) build_file = target.headers_build_phase.files_references.find { |file| file.path == relative_header_path } build_file ||= target.headers_build_phase.add_file_reference(file_reference, true) build_file.settings = { 'ATTRIBUTES' => ['Public'] } end |
#frameworks_dir ⇒ Object
56 57 58 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 56 def frameworks_dir File.join(project_root, 'Frameworks') end |
#generate_module_artifacts! ⇒ Object
74 75 76 77 78 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 74 def generate_module_artifacts! Utils::UI.info 'Generating umbrella header and module map' File.write(umbrella_header_path, umbrella_header_contents) File.write(modulemap_path, modulemap_contents) end |
#generate_tuist_project! ⇒ Object
80 81 82 83 84 85 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 80 def generate_tuist_project! Utils::UI.info 'Generating project with Tuist' return if system('tuist generate --no-open') raise Error, 'Error generating Tuist project' end |
#header_import_paths ⇒ Object
237 238 239 240 241 242 243 244 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 237 def header_import_paths Dir.glob(File.join(classes_root_path, '**', '*.h')).sort.filter_map do |header_path| basename = File.basename(header_path) next if basename == "#{plugin_name}-Bridging-Header.h" basename end end |
#modulemap_contents ⇒ Object
267 268 269 270 271 272 273 274 275 276 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 267 def modulemap_contents <<~MODULEMAP framework module #{plugin_name} { umbrella header "#{File.basename(umbrella_header_path)}" export * module * { export * } } MODULEMAP end |
#modulemap_path ⇒ Object
221 222 223 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 221 def modulemap_path File.join(project_root, "#{plugin_name}.modulemap") end |
#modulemap_project_setting_path ⇒ Object
229 230 231 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 229 def modulemap_project_setting_path "$(PROJECT_DIR)/#{File.basename(modulemap_path)}" end |
#move_xcframework_to_frameworks! ⇒ Object
46 47 48 49 50 51 52 53 54 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 46 def move_xcframework_to_frameworks! Utils::UI.info 'Moving xcframework to Frameworks directory' source = File.join(project_root, '.build', 'Frameworks', "#{plugin_name}.xcframework") dest_dir = frameworks_dir FileUtils.mkdir_p(dest_dir) dest = File.join(dest_dir, "#{plugin_name}.xcframework") FileUtils.rm_rf(dest) if File.exist?(dest) FileUtils.cp_r(source, dest) end |
#patch_build_settings!(config) ⇒ Object
105 106 107 108 109 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 105 def patch_build_settings!(config) config.build_settings.delete('SWIFT_OBJC_BRIDGING_HEADER') config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES' config.build_settings['MODULEMAP_FILE'] = modulemap_project_setting_path end |
#patch_generated_project! ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 87 def patch_generated_project! Utils::UI.info 'Patching generated Xcode project' project = Xcodeproj::Project.open(xcodeproj_path) project.build_configurations.each do |config| patch_build_settings!(config) end project.targets.select { |target| target.name == plugin_name }.each do |target| ensure_public_umbrella_header!(project, target) target.build_configurations.each do |config| patch_build_settings!(config) end end project.save end |
#plugin_name ⇒ Object
64 65 66 67 68 69 70 71 72 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 64 def plugin_name @plugin_name ||= begin project_definition = File.read(File.join(project_root, 'Project.swift')) match = project_definition.match(/name:\s*"([^"]+)"/) raise Error, "Could not determine project name from #{File.join(project_root, 'Project.swift')}" unless match match[1] end end |
#simulator_archive_path ⇒ Object
181 182 183 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 181 def simulator_archive_path File.join('.build', 'Frameworks', 'simulator.xcarchive') end |
#simulator_dsym_path ⇒ Object
201 202 203 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 201 def simulator_dsym_path File.(File.join(simulator_archive_path, 'dSYMs', "#{plugin_name}.framework.dSYM"), project_root) end |
#simulator_framework_path ⇒ Object
193 194 195 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 193 def simulator_framework_path File.(File.join(simulator_archive_path, 'Products', 'Library', 'Frameworks', "#{plugin_name}.framework"), project_root) end |
#tuist_project? ⇒ Boolean
60 61 62 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 60 def tuist_project? File.exist?(File.join(project_root, 'Project.swift')) end |
#tuist_workspace_path ⇒ Object
177 178 179 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 177 def tuist_workspace_path "#{plugin_name}.xcworkspace" end |
#umbrella_header_contents ⇒ Object
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 246 def umbrella_header_contents <<~HEADER #ifdef __OBJC__ #import <UIKit/UIKit.h> #else #ifndef FOUNDATION_EXPORT #if defined(__cplusplus) #define FOUNDATION_EXPORT extern "C" #else #define FOUNDATION_EXPORT extern #endif #endif #endif #{header_import_paths.map { |path| %(#import "#{path}") }.join("\n")} FOUNDATION_EXPORT double #{plugin_name}VersionNumber; FOUNDATION_EXPORT const unsigned char #{plugin_name}VersionString[]; HEADER end |
#umbrella_header_path ⇒ Object
225 226 227 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 225 def umbrella_header_path File.join(project_root, "#{plugin_name}-umbrella.h") end |
#xcframework_output_path ⇒ Object
189 190 191 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 189 def xcframework_output_path File.join('.build', 'Frameworks', "#{plugin_name}.xcframework") end |
#xcodebuild_archive_command(destination:, archive_path:, sdk:, archs_override: false) ⇒ Object
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 152 def xcodebuild_archive_command(destination:, archive_path:, sdk:, archs_override: false) command = [ "xcodebuild", "-workspace #{Shellwords.escape(tuist_workspace_path)}", "archive", ] if archs_override command << "ONLY_ACTIVE_ARCH=NO" command << "ARCHS=#{Shellwords.escape(archs)}" end command.concat( [ "-scheme #{Shellwords.escape(plugin_name)}", %( -destination "#{destination}").strip, "-archivePath #{Shellwords.escape(archive_path)}", "-sdk #{Shellwords.escape(sdk)}", "SKIP_INSTALL=NO", ] ) command.join(" ") end |
#xcodeproj_path ⇒ Object
217 218 219 |
# File 'lib/gonative/plugins/ios/build_framework.rb', line 217 def xcodeproj_path File.join(project_root, "#{plugin_name}.xcodeproj") end |