mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 18:35:34 +00:00
cmd/gogio: group buildInfo related code
Signed-off-by: Walter Werner SCHNEIDER <contact@schnwalter.eu>
This commit is contained in:
committed by
Elias Naur
parent
7eb32360e5
commit
3c739323cb
@@ -111,7 +111,7 @@ func buildAndroid(tmpDir string, bi *buildInfo) error {
|
|||||||
"CGO_ENABLED=1",
|
"CGO_ENABLED=1",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
pkgs, err := packages.Load(cfg, bi.pkg)
|
pkgs, err := packages.Load(cfg, bi.pkgPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -205,7 +205,7 @@ func compileAndroid(tmpDir string, tools *androidTools, bi *buildInfo) (err erro
|
|||||||
"-buildmode=c-shared",
|
"-buildmode=c-shared",
|
||||||
"-tags", bi.tags,
|
"-tags", bi.tags,
|
||||||
"-o", libFile,
|
"-o", libFile,
|
||||||
bi.pkg,
|
bi.pkgPath,
|
||||||
)
|
)
|
||||||
cmd.Env = append(
|
cmd.Env = append(
|
||||||
os.Environ(),
|
os.Environ(),
|
||||||
@@ -352,7 +352,7 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
|
|||||||
}
|
}
|
||||||
icon := *iconPath
|
icon := *iconPath
|
||||||
if icon == "" {
|
if icon == "" {
|
||||||
icon = filepath.Join(bi.dir, "appicon.png")
|
icon = filepath.Join(bi.pkgDir, "appicon.png")
|
||||||
}
|
}
|
||||||
iconSnip := ""
|
iconSnip := ""
|
||||||
if _, err := os.Stat(icon); err == nil {
|
if _, err := os.Stat(icon); err == nil {
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type buildInfo struct {
|
||||||
|
appID string
|
||||||
|
archs []string
|
||||||
|
ldflags string
|
||||||
|
minsdk int
|
||||||
|
name string
|
||||||
|
pkgDir string
|
||||||
|
pkgPath string
|
||||||
|
tags string
|
||||||
|
target string
|
||||||
|
version int
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBuildInfo(pkgAbsPath string) (*buildInfo, error) {
|
||||||
|
pkgMetadata, err := getPkgMetadata(pkgAbsPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
appID := getAppID(pkgMetadata)
|
||||||
|
bi := &buildInfo{
|
||||||
|
appID: appID,
|
||||||
|
archs: getArchs(),
|
||||||
|
ldflags: getLdFlags(appID),
|
||||||
|
minsdk: *minsdk,
|
||||||
|
name: getPkgName(pkgMetadata),
|
||||||
|
pkgDir: pkgMetadata.Dir,
|
||||||
|
pkgPath: pkgAbsPath,
|
||||||
|
tags: *extraTags,
|
||||||
|
target: *target,
|
||||||
|
version: *version,
|
||||||
|
}
|
||||||
|
return bi, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPkgAbsPath() string {
|
||||||
|
absPath, _ := filepath.Abs(flag.Arg(0))
|
||||||
|
return absPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func getArchs() []string {
|
||||||
|
if *archNames != "" {
|
||||||
|
return strings.Split(*archNames, ",")
|
||||||
|
}
|
||||||
|
switch *target {
|
||||||
|
case "js":
|
||||||
|
return []string{"wasm"}
|
||||||
|
case "ios", "tvos":
|
||||||
|
// Only 64-bit support.
|
||||||
|
return []string{"arm64", "amd64"}
|
||||||
|
case "android":
|
||||||
|
return []string{"arm", "arm64", "386", "amd64"}
|
||||||
|
default:
|
||||||
|
// TODO: Add flag tests.
|
||||||
|
panic("The target value has already been validated, this will never execute.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLdFlags(appID string) string {
|
||||||
|
var ldflags []string
|
||||||
|
if extra := *extraLdflags; extra != "" {
|
||||||
|
ldflags = append(ldflags, strings.Split(extra, " ")...)
|
||||||
|
}
|
||||||
|
// Pass appID along, to be used for logging on platforms like Android.
|
||||||
|
ldflags = append(ldflags, fmt.Sprintf("-X gioui.org/app/internal/log.appID=%s", appID))
|
||||||
|
// Pass along all remaining arguments to the app.
|
||||||
|
if appArgs := flag.Args()[1:]; len(appArgs) > 0 {
|
||||||
|
ldflags = append(ldflags, fmt.Sprintf("-X gioui.org/app.extraArgs=%s", strings.Join(appArgs, "|")))
|
||||||
|
}
|
||||||
|
if m := *linkMode; m != "" {
|
||||||
|
ldflags = append(ldflags, "-linkmode="+m)
|
||||||
|
}
|
||||||
|
return strings.Join(ldflags, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
type packageMetadata struct {
|
||||||
|
PkgPath string
|
||||||
|
Dir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPkgMetadata(absPath string) (*packageMetadata, error) {
|
||||||
|
pkgImportPath, err := runCmd(exec.Command("go", "list", "-f", "{{.ImportPath}}", absPath))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pkgDir, err := runCmd(exec.Command("go", "list", "-f", "{{.Dir}}", absPath))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &packageMetadata{
|
||||||
|
PkgPath: pkgImportPath,
|
||||||
|
Dir: pkgDir,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAppID(pkgMetadata *packageMetadata) string {
|
||||||
|
if *appID != "" {
|
||||||
|
return *appID
|
||||||
|
}
|
||||||
|
elems := strings.Split(pkgMetadata.PkgPath, "/")
|
||||||
|
domain := strings.Split(elems[0], ".")
|
||||||
|
name := ""
|
||||||
|
if len(elems) > 1 {
|
||||||
|
name = "." + elems[len(elems)-1]
|
||||||
|
}
|
||||||
|
if len(elems) < 2 && len(domain) < 2 {
|
||||||
|
name = "." + domain[0]
|
||||||
|
domain[0] = "localhost"
|
||||||
|
} else {
|
||||||
|
for i := 0; i < len(domain)/2; i++ {
|
||||||
|
opp := len(domain) - 1 - i
|
||||||
|
domain[i], domain[opp] = domain[opp], domain[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgDomain := strings.Join(domain, ".")
|
||||||
|
appid := []rune(pkgDomain + name)
|
||||||
|
|
||||||
|
// a Java-language-style package name may contain upper- and lower-case
|
||||||
|
// letters and underscores with individual parts separated by '.'.
|
||||||
|
// https://developer.android.com/guide/topics/manifest/manifest-element
|
||||||
|
for i, c := range appid {
|
||||||
|
if !('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' ||
|
||||||
|
c == '_' || c == '.') {
|
||||||
|
appid[i] = '_'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(appid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPkgName(pkgMetadata *packageMetadata) string {
|
||||||
|
return path.Base(pkgMetadata.PkgPath)
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
type expval struct {
|
||||||
|
in, out string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppID(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []expval{
|
||||||
|
{"example", "localhost.example"},
|
||||||
|
{"example.com", "com.example"},
|
||||||
|
{"www.example.com", "com.example.www"},
|
||||||
|
{"examplecom/app", "examplecom.app"},
|
||||||
|
{"example.com/app", "com.example.app"},
|
||||||
|
{"www.example.com/app", "com.example.www.app"},
|
||||||
|
{"www.en.example.com/app", "com.example.en.www.app"},
|
||||||
|
{"example.com/dir/app", "com.example.app"},
|
||||||
|
{"example.com/dir.ext/app", "com.example.app"},
|
||||||
|
{"example.com/dir/app.ext", "com.example.app.ext"},
|
||||||
|
{"example-com.net/dir/app", "net.example_com.app"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
got := getAppID(&packageMetadata{PkgPath: test.in})
|
||||||
|
if exp := test.out; got != exp {
|
||||||
|
t.Errorf("(%d): expected '%s', got '%s'", i, exp, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -224,7 +224,7 @@ int main(int argc, char * argv[]) {
|
|||||||
}
|
}
|
||||||
icon := *iconPath
|
icon := *iconPath
|
||||||
if icon == "" {
|
if icon == "" {
|
||||||
icon = filepath.Join(bi.dir, "appicon.png")
|
icon = filepath.Join(bi.pkgDir, "appicon.png")
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(icon); err == nil {
|
if _, err := os.Stat(icon); err == nil {
|
||||||
assetPlist, err := iosIcons(bi, tmpDir, app, icon)
|
assetPlist, err := iosIcons(bi, tmpDir, app, icon)
|
||||||
@@ -440,7 +440,7 @@ func archiveIOS(tmpDir, target, frameworkRoot string, bi *buildInfo) error {
|
|||||||
"-buildmode=c-archive",
|
"-buildmode=c-archive",
|
||||||
"-o", lib,
|
"-o", lib,
|
||||||
"-tags", tags,
|
"-tags", tags,
|
||||||
bi.pkg,
|
bi.pkgPath,
|
||||||
)
|
)
|
||||||
lipo.Args = append(lipo.Args, lib)
|
lipo.Args = append(lipo.Args, lib)
|
||||||
cflagsLine := strings.Join(cflags, " ")
|
cflagsLine := strings.Join(cflags, " ")
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func buildJS(bi *buildInfo) error {
|
|||||||
"-ldflags="+bi.ldflags,
|
"-ldflags="+bi.ldflags,
|
||||||
"-tags="+bi.tags,
|
"-tags="+bi.tags,
|
||||||
"-o", filepath.Join(out, "main.wasm"),
|
"-o", filepath.Join(out, "main.wasm"),
|
||||||
bi.pkg,
|
bi.pkgPath,
|
||||||
)
|
)
|
||||||
cmd.Env = append(
|
cmd.Env = append(
|
||||||
os.Environ(),
|
os.Environ(),
|
||||||
|
|||||||
+16
-103
@@ -37,36 +37,35 @@ var (
|
|||||||
iconPath = flag.String("icon", "", "Specify an icon for iOS and Android")
|
iconPath = flag.String("icon", "", "Specify an icon for iOS and Android")
|
||||||
)
|
)
|
||||||
|
|
||||||
type buildInfo struct {
|
|
||||||
name string
|
|
||||||
pkg string
|
|
||||||
ldflags string
|
|
||||||
tags string
|
|
||||||
target string
|
|
||||||
appID string
|
|
||||||
version int
|
|
||||||
dir string
|
|
||||||
archs []string
|
|
||||||
minsdk int
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Usage = func() {
|
flag.Usage = func() {
|
||||||
fmt.Fprint(os.Stderr, mainUsage)
|
fmt.Fprint(os.Stderr, mainUsage)
|
||||||
}
|
}
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
if err := mainErr(); err != nil {
|
if err := flagValidate(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "gogio: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
buildInfo, err := newBuildInfo(getPkgAbsPath())
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "gogio: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if err := build(buildInfo); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "gogio: %v\n", err)
|
fmt.Fprintf(os.Stderr, "gogio: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func mainErr() error {
|
func flagValidate() error {
|
||||||
pkg := flag.Arg(0)
|
pkgPathArg := flag.Arg(0)
|
||||||
if pkg == "" {
|
if pkgPathArg == "" {
|
||||||
return errors.New("specify a package")
|
return errors.New("specify a package")
|
||||||
}
|
}
|
||||||
|
if _, err := filepath.Abs(pkgPathArg); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if *target == "" {
|
if *target == "" {
|
||||||
return errors.New("please specify -target")
|
return errors.New("please specify -target")
|
||||||
}
|
}
|
||||||
@@ -80,95 +79,9 @@ func mainErr() error {
|
|||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid -buildmode %s", *buildMode)
|
return fmt.Errorf("invalid -buildmode %s", *buildMode)
|
||||||
}
|
}
|
||||||
// Find package name.
|
|
||||||
pkgPath, err := runCmd(exec.Command("go", "list", "-f", "{{.ImportPath}}", pkg))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dir, err := runCmd(exec.Command("go", "list", "-f", "{{.Dir}}", pkg))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
elems := strings.Split(pkgPath, "/")
|
|
||||||
name := elems[len(elems)-1]
|
|
||||||
bi := &buildInfo{
|
|
||||||
name: name,
|
|
||||||
pkg: pkg,
|
|
||||||
target: *target,
|
|
||||||
appID: *appID,
|
|
||||||
dir: dir,
|
|
||||||
version: *version,
|
|
||||||
minsdk: *minsdk,
|
|
||||||
tags: *extraTags,
|
|
||||||
}
|
|
||||||
if bi.appID == "" {
|
|
||||||
bi.appID = appIDFromPackage(pkgPath)
|
|
||||||
}
|
|
||||||
var ldflags []string
|
|
||||||
if extra := *extraLdflags; extra != "" {
|
|
||||||
ldflags = append(ldflags, strings.Split(extra, " ")...)
|
|
||||||
}
|
|
||||||
// Pass appID along, to be used for logging on platforms like Android.
|
|
||||||
ldflags = append(ldflags, fmt.Sprintf("-X gioui.org/app/internal/log.appID=%s", bi.appID))
|
|
||||||
|
|
||||||
switch *target {
|
|
||||||
case "js":
|
|
||||||
bi.archs = []string{"wasm"}
|
|
||||||
case "ios", "tvos":
|
|
||||||
// Only 64-bit support.
|
|
||||||
bi.archs = []string{"arm64", "amd64"}
|
|
||||||
case "android":
|
|
||||||
bi.archs = []string{"arm", "arm64", "386", "amd64"}
|
|
||||||
}
|
|
||||||
if *archNames != "" {
|
|
||||||
bi.archs = strings.Split(*archNames, ",")
|
|
||||||
}
|
|
||||||
if appArgs := flag.Args()[1:]; len(appArgs) > 0 {
|
|
||||||
// Pass along arguments to the app.
|
|
||||||
ldflags = append(ldflags, fmt.Sprintf("-X gioui.org/app.extraArgs=%s", strings.Join(appArgs, "|")))
|
|
||||||
}
|
|
||||||
if m := *linkMode; m != "" {
|
|
||||||
ldflags = append(ldflags, "-linkmode="+m)
|
|
||||||
}
|
|
||||||
bi.ldflags = strings.Join(ldflags, " ")
|
|
||||||
if err := build(bi); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func appIDFromPackage(pkgPath string) string {
|
|
||||||
elems := strings.Split(pkgPath, "/")
|
|
||||||
domain := strings.Split(elems[0], ".")
|
|
||||||
name := ""
|
|
||||||
if len(elems) > 1 {
|
|
||||||
name = "." + elems[len(elems)-1]
|
|
||||||
}
|
|
||||||
if len(elems) < 2 && len(domain) < 2 {
|
|
||||||
name = "." + domain[0]
|
|
||||||
domain[0] = "localhost"
|
|
||||||
} else {
|
|
||||||
for i := 0; i < len(domain)/2; i++ {
|
|
||||||
opp := len(domain) - 1 - i
|
|
||||||
domain[i], domain[opp] = domain[opp], domain[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pkgDomain := strings.Join(domain, ".")
|
|
||||||
appid := []rune(pkgDomain + name)
|
|
||||||
|
|
||||||
// a Java-language-style package name may contain upper- and lower-case
|
|
||||||
// letters and underscores with individual parts separated by '.'.
|
|
||||||
// https://developer.android.com/guide/topics/manifest/manifest-element
|
|
||||||
for i, c := range appid {
|
|
||||||
if !('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' ||
|
|
||||||
c == '_' || c == '.') {
|
|
||||||
appid[i] = '_'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return string(appid)
|
|
||||||
}
|
|
||||||
|
|
||||||
func build(bi *buildInfo) error {
|
func build(bi *buildInfo) error {
|
||||||
tmpDir, err := ioutil.TempDir("", "gogio-")
|
tmpDir, err := ioutil.TempDir("", "gogio-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -15,32 +15,3 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
|
||||||
type expval struct {
|
|
||||||
in, out string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAppID(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
tests := []expval{
|
|
||||||
{"example", "localhost.example"},
|
|
||||||
{"example.com", "com.example"},
|
|
||||||
{"www.example.com", "com.example.www"},
|
|
||||||
{"examplecom/app", "examplecom.app"},
|
|
||||||
{"example.com/app", "com.example.app"},
|
|
||||||
{"www.example.com/app", "com.example.www.app"},
|
|
||||||
{"www.en.example.com/app", "com.example.en.www.app"},
|
|
||||||
{"example.com/dir/app", "com.example.app"},
|
|
||||||
{"example.com/dir.ext/app", "com.example.app"},
|
|
||||||
{"example.com/dir/app.ext", "com.example.app.ext"},
|
|
||||||
{"example-com.net/dir/app", "net.example_com.app"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, test := range tests {
|
|
||||||
got := appIDFromPackage(test.in)
|
|
||||||
if exp := test.out; got != exp {
|
|
||||||
t.Errorf("(%d): expected '%s', got '%s'", i, exp, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user