2
0
mirror of synced 2025-02-23 23:08:14 +00:00

cmd/gomobile: add the -bundleid flag

The current gomobile build command fails when attempting to sign the application
indicating that a development team should be selected. These changes fix that
by auto-detecting the developer team ID and setting the
"allowProvisioningUpdates" flag on the xcodebuild command. The bundle ID of
the application is also allowed to be changed via another command line
parameter "bundleid".

Fixes golang/go#17407

Change-Id: Ib0b878424a95a0cd49f3655ed4de56b2b91ff7a0
Reviewed-on: https://go-review.googlesource.com/77070
Reviewed-by: Elias Naur <elias.naur@gmail.com>
This commit is contained in:
Kevin Ruffin 2017-11-10 14:20:07 -05:00 committed by Elias Naur
parent 2a5bbaa217
commit c0beac360c
3 changed files with 92 additions and 20 deletions

View File

@ -24,7 +24,7 @@ var tmpdir string
var cmdBuild = &command{
run: runBuild,
Name: "build",
Usage: "[-target android|ios] [-o output] [build flags] [package]",
Usage: "[-target android|ios] [-o output] [-bundleid bundleId] [build flags] [package]",
Short: "compile android APK and iOS app",
Long: `
Build compiles and encodes the app named by the import path.
@ -47,6 +47,9 @@ installed. Support is not complete.
If the package directory contains an assets subdirectory, its contents
are copied into the output.
The -bundleid flag is for -target ios only and sets the bundle ID to use
with the app; defaults to "org.golang.todo".
The -o flag specifies the output file name. If not specified, the
output file name depends on the package built.
@ -118,7 +121,7 @@ func runBuild(cmd *command) (err error) {
}
return goBuild(pkg.ImportPath, darwinArm64Env)
}
nmpkgs, err = goIOSBuild(pkg)
nmpkgs, err = goIOSBuild(pkg, buildBundleID)
if err != nil {
return err
}
@ -205,16 +208,17 @@ func printcmd(format string, args ...interface{}) {
// "Build flags", used by multiple commands.
var (
buildA bool // -a
buildI bool // -i
buildN bool // -n
buildV bool // -v
buildX bool // -x
buildO string // -o
buildGcflags string // -gcflags
buildLdflags string // -ldflags
buildTarget string // -target
buildWork bool // -work
buildA bool // -a
buildI bool // -i
buildN bool // -n
buildV bool // -v
buildX bool // -x
buildO string // -o
buildGcflags string // -gcflags
buildLdflags string // -ldflags
buildTarget string // -target
buildWork bool // -work
buildBundleID string // -bundleid
)
func addBuildFlags(cmd *command) {
@ -222,6 +226,7 @@ func addBuildFlags(cmd *command) {
cmd.flag.StringVar(&buildGcflags, "gcflags", "", "")
cmd.flag.StringVar(&buildLdflags, "ldflags", "", "")
cmd.flag.StringVar(&buildTarget, "target", "android", "")
cmd.flag.StringVar(&buildBundleID, "bundleid", "org.golang.todo", "")
cmd.flag.BoolVar(&buildA, "a", false, "")
cmd.flag.BoolVar(&buildI, "i", false, "")

View File

@ -33,7 +33,29 @@ func TestIOSBuild(t *testing.T) {
t.Fatal(err)
}
diff, err := diffOutput(buf.String(), iosBuildTmpl)
teamID, err := detectTeamID()
if err != nil {
t.Fatalf("detecting team ID failed: %v", err)
}
data := struct {
outputData
TeamID string
}{
outputData: defaultOutputData(),
TeamID: teamID,
}
got := filepath.ToSlash(buf.String())
wantBuf := new(bytes.Buffer)
if err := iosBuildTmpl.Execute(wantBuf, data); err != nil {
t.Fatalf("computing diff failed: %v", err)
}
diff, err := diff(got, wantBuf.String())
if err != nil {
t.Fatalf("computing diff failed: %v", err)
}
@ -54,6 +76,6 @@ GOOS=darwin GOARCH=arm GOARM=7 CC=clang-iphoneos CXX=clang-iphoneos CGO_CFLAGS=-
GOOS=darwin GOARCH=arm64 CC=clang-iphoneos CXX=clang-iphoneos CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=6.1 -arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=6.1 -arch arm64 CGO_ENABLED=1 go build -pkgdir=$GOMOBILE/pkg_darwin_arm64 -tags tag1 ios -x -o=$WORK/arm64 golang.org/x/mobile/example/basic
xcrun lipo -create $WORK/arm $WORK/arm64 -o $WORK/main/main
mkdir -p $WORK/main/assets
xcrun xcodebuild -configuration Release -project $WORK/main.xcodeproj
xcrun xcodebuild -configuration Release -project $WORK/main.xcodeproj -allowProvisioningUpdates DEVELOPMENT_TEAM={{.TeamID}}
mv $WORK/build/Release-iphoneos/main.app basic.app
`))

View File

@ -6,6 +6,8 @@ package main
import (
"bytes"
"crypto/x509"
"encoding/pem"
"fmt"
"go/build"
"io/ioutil"
@ -17,7 +19,7 @@ import (
"text/template"
)
func goIOSBuild(pkg *build.Package) (map[string]bool, error) {
func goIOSBuild(pkg *build.Package, bundleID string) (map[string]bool, error) {
src := pkg.ImportPath
if buildO != "" && !strings.HasSuffix(buildO, ".app") {
return nil, fmt.Errorf("-o must have an .app for -target=ios")
@ -31,7 +33,7 @@ func goIOSBuild(pkg *build.Package) (map[string]bool, error) {
infoplist := new(bytes.Buffer)
if err := infoplistTmpl.Execute(infoplist, infoplistTmplData{
// TODO: better bundle id.
BundleID: "org.golang.todo." + productName,
BundleID: bundleID + "." + productName,
Name: strings.Title(path.Base(pkg.ImportPath)),
}); err != nil {
return nil, err
@ -94,12 +96,22 @@ func goIOSBuild(pkg *build.Package) (map[string]bool, error) {
return nil, err
}
// Detect the team ID
teamID, err := detectTeamID()
if err != nil {
return nil, err
}
// Build and move the release build to the output directory.
cmd = exec.Command(
"xcrun", "xcodebuild",
cmdStrings := []string{
"xcodebuild",
"-configuration", "Release",
"-project", tmpdir+"/main.xcodeproj",
)
"-project", tmpdir + "/main.xcodeproj",
"-allowProvisioningUpdates",
"DEVELOPMENT_TEAM=" + teamID,
}
cmd = exec.Command("xcrun", cmdStrings...)
if err := runCmd(cmd); err != nil {
return nil, err
}
@ -133,6 +145,39 @@ func goIOSBuild(pkg *build.Package) (map[string]bool, error) {
return nmpkgs, nil
}
func detectTeamID() (string, error) {
// Grabs the first certificate for "iPhone Developer"; will not work if there
// are multiple certificates and the first is not desired.
cmd := exec.Command(
"security", "find-certificate",
"-c", "iPhone Developer", "-p",
)
pemString, err := cmd.Output()
if err != nil {
err = fmt.Errorf("failed to pull the signing certificate to determine your team ID: %v", err)
return "", err
}
block, _ := pem.Decode(pemString)
if block == nil {
err = fmt.Errorf("failed to decode the PEM to determine your team ID: %s", pemString)
return "", err
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
err = fmt.Errorf("failed to parse your signing certificate to determine your team ID: %v", err)
return "", err
}
if len(cert.Subject.OrganizationalUnit) == 0 {
err = fmt.Errorf("the signing certificate has no organizational unit (team ID).")
return "", err
}
return cert.Subject.OrganizationalUnit[0], nil
}
func iosCopyAssets(pkg *build.Package, xcodeProjDir string) error {
dstAssets := xcodeProjDir + "/main/assets"
if err := mkdir(dstAssets); err != nil {