cmd/gomobile: fix a compatibility issue with Xcode 15.3 This change adds compatibility for Xcode 15.3 to "gomobile bind" for building xcframeworks. - New blank Info.plist in the *.framework target root - Add CFBundleExecutable and CFBundleIdentifier to the resource level Info.plist Tested locally on my framework on Xcode 15.3 (fixes issue) and 15.2 (doesn't create new issues). Would love to get some more folks to try this fix, to make sure it works broadly. Note: I'm using the framework name as the bundleID. Some chance of collision here, but didn't want to add a required top level cmd parameter. I don't *think* a collision is a serious concern, but I'm not an apple build system expert. To test: - sync my branch - build go mobile: `go build` in the `cmd/gomobile` dir - Build your xcframework with this version of go mobile: `gomobile bind ... ` - Launch a project using the xcframework in Xcode 15.3, and run in simulator Fixes golang/go#66018 Change-Id: I3e8ee99adb09071aa89a541dc97271a44b552ea3 GitHub-Last-Rev: 6277c7d66a26efa8b9ff99dea191eeb7bef136a6 GitHub-Pull-Request: golang/mobile#96 Reviewed-on: https://go-review.googlesource.com/c/mobile/+/572175 TryBot-Result: Gopher Robot <gobot@golang.org> TryBot-Bypass: Hyang-Ah Hana Kim <hyangah@gmail.com> Reviewed-by: Hajime Hoshi <hajimehoshi@gmail.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> Run-TryBot: Hajime Hoshi <hajimehoshi@gmail.com> Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com> Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
diff --git a/cmd/gomobile/bind_iosapp.go b/cmd/gomobile/bind_iosapp.go index 3843743..e92aa36 100644 --- a/cmd/gomobile/bind_iosapp.go +++ b/cmd/gomobile/bind_iosapp.go
@@ -5,6 +5,8 @@ package main import ( + "bytes" + "encoding/xml" "errors" "fmt" "io" @@ -230,6 +232,14 @@ if err != nil { return err } + + err = writeFile(filepath.Join(frameworkDir, "Info.plist"), func(w io.Writer) error { + _, err := w.Write([]byte(appleBlankInfoPlist)) + return err + }) + if err != nil { + return err + } } if err := mkdir(filepath.Join(versionsADir, "Resources")); err != nil { @@ -239,7 +249,15 @@ return err } err = writeFile(filepath.Join(frameworkDir, "Resources", "Info.plist"), func(w io.Writer) error { - _, err := w.Write([]byte(appleBindInfoPlist)) + infoFrameworkPlistlData := infoFrameworkPlistlData{ + BundleID: escapePlistValue(rfc1034Label(title)), + ExecutableName: escapePlistValue(title), + } + infoplist := new(bytes.Buffer) + if err := infoFrameworkPlistTmpl.Execute(infoplist, infoFrameworkPlistlData); err != nil { + return err + } + _, err := w.Write(infoplist.Bytes()) return err }) if err != nil { @@ -286,7 +304,7 @@ return err } -const appleBindInfoPlist = `<?xml version="1.0" encoding="UTF-8"?> +const appleBlankInfoPlist = `<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> @@ -294,6 +312,29 @@ </plist> ` +type infoFrameworkPlistlData struct { + BundleID string + ExecutableName string +} + +var infoFrameworkPlistTmpl = template.Must(template.New("infoFrameworkPlist").Parse(`<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleExecutable</key> + <string>{{.ExecutableName}}</string> + <key>CFBundleIdentifier</key> + <string>{{.BundleID}}</string> +</dict> +</plist> +`)) + +func escapePlistValue(value string) string { + var b bytes.Buffer + xml.EscapeText(&b, []byte(value)) + return b.String() +} + var appleModuleMapTmpl = template.Must(template.New("iosmmap").Parse(`framework module "{{.Module}}" { header "ref.h" {{range .Headers}} header "{{.}}"