--- /dev/null
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// detect attempts to autodetect the correct
+// values of the environment variables
+// used by go_darwin_arm_exec.
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "strings"
+)
+
+func main() {
+ devID := detectDevID()
+ fmt.Printf("export GOIOS_DEV_ID=%s\n", devID)
+
+ udid := detectUDID()
+ mp := detectMobileProvisionFile(udid)
+
+ f, err := ioutil.TempFile("", "go_ios_detect_")
+ check(err)
+ fname := f.Name()
+ defer os.Remove(fname)
+
+ out := combinedOutput(parseMobileProvision(mp))
+ _, err = f.Write(out)
+ check(err)
+ check(f.Close())
+
+ appID, err := plistExtract(fname, "ApplicationIdentifierPrefix:0")
+ check(err)
+ fmt.Printf("export GOIOS_APP_ID=%s\n", appID)
+
+ teamID, err := plistExtract(fname, "Entitlements:com.apple.developer.team-identifier")
+ check(err)
+ fmt.Printf("export GOIOS_TEAM_ID=%s\n", teamID)
+}
+
+func detectDevID() string {
+ cmd := exec.Command("security", "find-identity", "-p", "codesigning", "-v")
+ lines := getLines(cmd)
+
+ for _, line := range lines {
+ if !bytes.Contains(line, []byte("iPhone Developer")) {
+ continue
+ }
+ fields := bytes.Fields(line)
+ return string(fields[1])
+ }
+ fail("no code signing identity found")
+ panic("unreachable")
+}
+
+var udidPrefix = []byte("UniqueDeviceID: ")
+
+func detectUDID() []byte {
+ cmd := exec.Command("ideviceinfo")
+ lines := getLines(cmd)
+ for _, line := range lines {
+ if bytes.HasPrefix(line, udidPrefix) {
+ return bytes.TrimPrefix(line, udidPrefix)
+ }
+ }
+ fail("udid not found; is the device connected?")
+ panic("unreachable")
+}
+
+func detectMobileProvisionFile(udid []byte) string {
+ cmd := exec.Command("mdfind", "-name", ".mobileprovision")
+ lines := getLines(cmd)
+
+ for _, line := range lines {
+ if len(line) == 0 {
+ continue
+ }
+ xmlLines := getLines(parseMobileProvision(string(line)))
+ for _, xmlLine := range xmlLines {
+ if bytes.Contains(xmlLine, udid) {
+ return string(line)
+ }
+ }
+ }
+ fail("did not find mobile provision matching device udid %s", udid)
+ panic("ureachable")
+}
+
+func parseMobileProvision(fname string) *exec.Cmd {
+ return exec.Command("security", "cms", "-D", "-i", string(fname))
+}
+
+func plistExtract(fname string, path string) ([]byte, error) {
+ out, err := exec.Command("/usr/libexec/PlistBuddy", "-c", "Print "+path, fname).CombinedOutput()
+ if err != nil {
+ return nil, err
+ }
+ return bytes.TrimSpace(out), nil
+}
+
+func getLines(cmd *exec.Cmd) [][]byte {
+ out := combinedOutput(cmd)
+ return bytes.Split(out, []byte("\n"))
+}
+
+func combinedOutput(cmd *exec.Cmd) []byte {
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ fmt.Println(strings.Join(cmd.Args, "\n"))
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ return out
+}
+
+func check(err error) {
+ if err != nil {
+ fail(err.Error())
+ }
+}
+
+func fail(msg string, v ...interface{}) {
+ fmt.Fprintf(os.Stderr, msg, v...)
+ fmt.Fprintln(os.Stderr)
+ os.Exit(1)
+}
// the remote lldb session. This flag is appended to the end of the
// script's arguments and is not passed through to the underlying
// binary.
+//
+// This script requires that three environment variables be set:
+// GOIOS_DEV_ID: The codesigning developer id or certificate identifier
+// GOIOS_APP_ID: The provisioning app id prefix. Must support wildcard app ids.
+// GOIOS_TEAM_ID: The team id that owns the app id prefix.
+// $GOROOT/misc/ios contains a script, detect.go, that attempts to autodetect these.
package main
import (
var tmpdir string
+var (
+ devID string
+ appID string
+ teamID string
+)
+
func main() {
log.SetFlags(0)
log.SetPrefix("go_darwin_arm_exec: ")
log.Fatal("usage: go_darwin_arm_exec a.out")
}
+ devID = getenv("GOIOS_DEV_ID")
+ appID = getenv("GOIOS_APP_ID")
+ teamID = getenv("GOIOS_TEAM_ID")
+
var err error
tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_")
if err != nil {
}
}
+func getenv(envvar string) string {
+ s := os.Getenv(envvar)
+ if s == "" {
+ log.Fatalf("%s not set\nrun $GOROOT/misc/ios/detect.go to attempt to autodetect", s)
+ }
+ return s
+}
+
func run(bin string, args []string) (err error) {
appdir := filepath.Join(tmpdir, "gotest.app")
os.RemoveAll(appdir)
}
entitlementsPath := filepath.Join(tmpdir, "Entitlements.plist")
- if err := ioutil.WriteFile(entitlementsPath, []byte(entitlementsPlist), 0744); err != nil {
+ if err := ioutil.WriteFile(entitlementsPath, []byte(entitlementsPlist()), 0744); err != nil {
return err
}
if err := ioutil.WriteFile(filepath.Join(appdir, "Info.plist"), []byte(infoPlist), 0744); err != nil {
cmd := exec.Command(
"codesign",
"-f",
- "-s", "E8BMC3FE2Z", // certificate associated with golang.org
+ "-s", devID,
"--entitlements", entitlementsPath,
appdir,
)
</plist>
`
-const devID = `YE84DJ86AZ`
-
-const entitlementsPlist = `<?xml version="1.0" encoding="UTF-8"?>
+func entitlementsPlist() string {
+ return `<?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>keychain-access-groups</key>
- <array><string>` + devID + `.golang.gotest</string></array>
+ <array><string>` + teamID + `.golang.gotest</string></array>
<key>get-task-allow</key>
<true/>
<key>application-identifier</key>
- <string>` + devID + `.golang.gotest</string>
+ <string>` + teamID + `.golang.gotest</string>
<key>com.apple.developer.team-identifier</key>
- <string>` + devID + `</string>
+ <string>` + teamID + `</string>
</dict>
</plist>`
+}
const resourceRules = `<?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">