Created
December 23, 2020 08:27
-
-
Save horsley/db13fd63b6cc07899c3a09112d0b2612 to your computer and use it in GitHub Desktop.
Xcode 12.3 golang script for xcframework convertion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"os" | |
"os/exec" | |
"path/filepath" | |
"regexp" | |
"strings" | |
"time" | |
) | |
var ( | |
archRegex = regexp.MustCompile(`\(for architecture ([^)]*)\)`) | |
archMap = map[string]string{ | |
"armv7": "ios", | |
"armv7s": "ios", | |
"arm64": "ios", | |
"i386": "simulator", | |
"x86_64": "simulator", | |
} | |
) | |
func main() { | |
if len(os.Args) < 2 { | |
fmt.Println(filepath.Base(os.Args[0]), "xxx.framework") | |
return | |
} | |
oldFrameworkPath := os.Args[1] | |
//stage 1 find fat binary | |
if !strings.HasSuffix(oldFrameworkPath, ".framework") { | |
fmt.Println("not a framework!") | |
return | |
} | |
fatName := strings.Replace(filepath.Base(oldFrameworkPath), ".framework", "", 1) | |
fatPath := filepath.Join(oldFrameworkPath, fatName) | |
fatArch := make([]string, 0, 5) | |
fatInfo := syncRunCmd("file", fatPath) | |
archMatches := archRegex.FindAllStringSubmatch(fatInfo, -1) | |
if len(archMatches) <= 1 { | |
fmt.Println("multi architecture fat binary not found") | |
return | |
} | |
fmt.Println(fatPath, "found fat binary") | |
fmt.Println("\n", fatInfo) | |
for _, a := range archMatches { | |
fatArch = append(fatArch, a[1]) | |
} | |
//stage 2 make seperate thin bin, copy framework for seperate platform | |
tmp := filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Unix())) | |
fmt.Println("tmp dir:", tmp) | |
platformBin := make(map[string][]string) | |
for _, arch := range fatArch { | |
platform, ok := archMap[arch] | |
if !ok { | |
fmt.Println("platform not define for arch:", arch) | |
return | |
} | |
platformFramework := filepath.Join(tmp, platform, filepath.Base(oldFrameworkPath)) | |
if _, err := os.Stat(platformFramework); err != nil && os.IsNotExist(err) { | |
os.MkdirAll(filepath.Dir(platformFramework), 0755) | |
fmt.Println("make copy:", platformFramework) | |
fmt.Println(syncRunCmd("cp", "-r", oldFrameworkPath, platformFramework)) | |
platformBin[platformFramework] = make([]string, 0, 3) | |
} | |
seperateBin := filepath.Join(tmp, platform, arch, fatName) | |
os.MkdirAll(filepath.Dir(seperateBin), 0755) | |
fmt.Println(syncRunCmd("lipo", fatPath, "-thin", arch, "-output", seperateBin)) | |
platformBin[platformFramework] = append(platformBin[platformFramework], seperateBin) | |
} | |
//stage 3 combine bin by platform, save in framework dir | |
xcframworkParam := make([]string, 0, 2*len(fatArch)+3) | |
xcframworkParam = append(xcframworkParam, "-create-xcframework") | |
for framework, bin := range platformBin { | |
lipoParam := []string{"-create", "-output", filepath.Join(framework, fatName)} | |
lipoParam = append(lipoParam, bin...) | |
fmt.Println("lipo", lipoParam) | |
fmt.Println(syncRunCmd("lipo", lipoParam...)) | |
xcframworkParam = append(xcframworkParam, "-framework", framework) | |
} | |
//stage 4 make xcframework | |
xcframworkParam = append(xcframworkParam, "-output", strings.Replace(oldFrameworkPath, ".framework", ".xcframework", 1)) | |
fmt.Println("xcodebuild", xcframworkParam) | |
fmt.Println(syncRunCmd("xcodebuild", xcframworkParam...)) | |
} | |
func syncRunCmd(cmd string, args ...string) string { | |
rst, err := exec.Command(cmd, args...).CombinedOutput() | |
if err != nil { | |
return err.Error() | |
} | |
return string(rst) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment