Skip to content

Instantly share code, notes, and snippets.

@MapaX
Last active April 28, 2021 12:45
Show Gist options
  • Save MapaX/1fda8e83837625d4304d1fb4004823fe to your computer and use it in GitHub Desktop.
Save MapaX/1fda8e83837625d4304d1fb4004823fe to your computer and use it in GitHub Desktop.
Swift command line tool to make any .framework to .xcframework which works then in Apple Silicon M1 mac. The script is used with command "MakeXCFramework.swift myFramework.framework"
#!/usr/bin/env swift
import Foundation
func shell(_ command: String) -> String {
print("Running command: \(command)")
let task = Process()
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.arguments = ["-c", command]
task.launchPath = "/bin/zsh"
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)!
return output
}
extension String {
func trim() -> String {
return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
}
let frameworkName: String = CommandLine.arguments[1]
let frameworkBegin = frameworkName.components(separatedBy: ".").first!.trim()
print("Found framework \(frameworkName)")
let architectures = shell("lipo -i \(frameworkName)/\(frameworkBegin)")
print("Supported architectures \(architectures)")
let architecturesString: String = architectures.components(separatedBy: ":").last!.trim()
var architecturesArray = architecturesString.components(separatedBy: " ")
if architecturesArray.contains("armv7") {
let oneArchName = "./\(frameworkName)/\(frameworkBegin)"
_ = shell("lipo -remove armv7 \(oneArchName) -o \(oneArchName)")
architecturesArray.remove(at: architecturesArray.firstIndex(of: "armv7")!)
}
if architecturesArray.contains("i386") {
let oneArchName = "./\(frameworkName)/\(frameworkBegin)"
_ = shell("lipo -remove i386 \(oneArchName) -o \(oneArchName)")
architecturesArray.remove(at: architecturesArray.firstIndex(of: "i386")!)
}
var directoryNameArray: [String] = []
for arch in architecturesArray {
let directoryName = "\(frameworkBegin)_\(arch)"
directoryNameArray.append(directoryName)
_ = shell("mkdir \(directoryName)")
_ = shell("cp -R ./\(frameworkName) ./\(directoryName)")
var removedArchs: [String] = architecturesArray
if let index = removedArchs.firstIndex(of: arch){
removedArchs.remove(at: index)
}
for removeArch in removedArchs {
let oneArchName = "./\(directoryName)/\(frameworkName)/\(frameworkBegin)"
_ = shell("lipo -remove \(removeArch) \(oneArchName) -o \(oneArchName)")
}
}
let joinerString = "/\(frameworkName)/ -framework "
let buildResult = shell("xcodebuild -create-xcframework -framework \(directoryNameArray.joined(separator: joinerString))/\(frameworkName)/ -output \(frameworkBegin).xcframework")
print("Building completed: \(buildResult)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment