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:
parent
2a5bbaa217
commit
c0beac360c
@ -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, "")
|
||||
|
@ -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
|
||||
`))
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user