mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-29 04:02:45 +01:00
d8b34b136a
Fixes #1144
269 lines
6.2 KiB
Go
269 lines
6.2 KiB
Go
// Copyright 2020 The Ebiten Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/hajimehoshi/go2dotnet/gowasm2csharp"
|
|
)
|
|
|
|
const ebitenmonogameName = "ebitenmonogame"
|
|
|
|
var (
|
|
flagA bool // -a
|
|
flagGcflags string // -gcflags
|
|
flagI bool // -i
|
|
flagLdflags string // -ldflags
|
|
flagN bool // -n
|
|
flagTags string // -tags
|
|
flagTrimpath bool // -trimpath
|
|
flagV bool // -v
|
|
flagWork bool // -work
|
|
flagX bool // -x
|
|
|
|
flagNamespace string // -namespace
|
|
flagO string // -o
|
|
)
|
|
|
|
func main() {
|
|
if err := checkGOOS(); err != nil {
|
|
fmt.Fprintf(os.Stderr, "%s: %v\n", ebitenmonogameName, err)
|
|
os.Exit(2)
|
|
}
|
|
|
|
var flagset flag.FlagSet
|
|
flag.Usage = func() {
|
|
fmt.Fprintf(os.Stderr, "%s [-namespace namespace] [-o output] [build flags] [package]\n", ebitenmonogameName)
|
|
os.Exit(2)
|
|
}
|
|
|
|
flagset.BoolVar(&flagA, "a", false, "")
|
|
flagset.StringVar(&flagGcflags, "gcflags", "", "")
|
|
flagset.BoolVar(&flagI, "i", false, "")
|
|
flagset.StringVar(&flagLdflags, "ldflags", "", "")
|
|
flagset.BoolVar(&flagN, "n", false, "")
|
|
flagset.StringVar(&flagTags, "tags", "", "")
|
|
flagset.BoolVar(&flagTrimpath, "trimpath", false, "")
|
|
flagset.BoolVar(&flagV, "v", false, "")
|
|
flagset.BoolVar(&flagWork, "work", false, "")
|
|
flagset.BoolVar(&flagX, "x", false, "")
|
|
|
|
flagset.StringVar(&flagNamespace, "namespace", "", "")
|
|
flagset.StringVar(&flagO, "o", "", "")
|
|
|
|
flagset.Parse(os.Args[1:])
|
|
|
|
if flagNamespace == "" {
|
|
fmt.Fprintln(os.Stderr, "-namespace must be specified")
|
|
os.Exit(2)
|
|
}
|
|
if flagO == "" {
|
|
fmt.Fprintln(os.Stderr, "-o must be specified")
|
|
os.Exit(2)
|
|
}
|
|
|
|
if flagLdflags != "" {
|
|
flagLdflags += " "
|
|
}
|
|
flagLdflags = "-X github.com/hajimehoshi/ebiten/internal/monogame.namespace=" + flagNamespace
|
|
if flagTags != "" {
|
|
flagTags += ","
|
|
}
|
|
flagTags += "monogame"
|
|
|
|
var src string
|
|
switch srcs := flagset.Args(); len(srcs) {
|
|
case 0:
|
|
src = "."
|
|
case 1:
|
|
src = srcs[0]
|
|
default:
|
|
flag.Usage()
|
|
}
|
|
if err := run(src); err != nil {
|
|
fmt.Fprintf(os.Stderr, "%s: %v\n", ebitenmonogameName, err)
|
|
os.Exit(2)
|
|
}
|
|
}
|
|
|
|
func checkGOOS() error {
|
|
out, err := exec.Command("go", "env", "GOOS").Output()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
goos := strings.TrimSpace(string(out))
|
|
if goos != "windows" {
|
|
fmt.Fprintln(os.Stderr, "Warning: The output project is buildable on Windows.")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func run(src string) error {
|
|
// TODO: Check src is a main package?
|
|
|
|
// Generate a wasm binary.
|
|
env := []string{
|
|
"GOOS=js",
|
|
"GOARCH=wasm",
|
|
}
|
|
|
|
dir, err := ioutil.TempDir("", "ebitenmonogame")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if flagWork {
|
|
fmt.Fprintf(os.Stderr, "The temporary work directory: %s\n", dir)
|
|
return
|
|
}
|
|
os.RemoveAll(dir)
|
|
}()
|
|
|
|
wasmFile := filepath.Join(dir, "tmp.wasm")
|
|
|
|
if err := runGo("build", []string{src}, env, "-o", wasmFile); err != nil {
|
|
return err
|
|
}
|
|
if flagN {
|
|
return nil
|
|
}
|
|
|
|
autogenDir := filepath.Join(flagO, "autogen")
|
|
if flagV {
|
|
fmt.Fprintf(os.Stderr, "Writing %s%s*.cs\n", autogenDir, string(filepath.Separator))
|
|
}
|
|
if err := os.MkdirAll(autogenDir, 0755); err != nil {
|
|
return err
|
|
}
|
|
if err := gowasm2csharp.Generate(autogenDir, wasmFile, flagNamespace+".AutoGen"); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := writeFile(filepath.Join(flagO, "GoGame.cs"), replaceNamespace(gogame_cs)); err != nil {
|
|
return err
|
|
}
|
|
if err := writeFile(filepath.Join(flagO, "Program.cs"), replaceNamespace(program_cs)); err != nil {
|
|
return err
|
|
}
|
|
abs, err := filepath.Abs(flagO)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
project := filepath.Base(abs)
|
|
if err := writeFile(filepath.Join(flagO, project+".csproj"), replaceNamespace(project_csproj)); err != nil {
|
|
return err
|
|
}
|
|
if err := writeFile(filepath.Join(flagO, "Content", "Content.mgcb"), replaceNamespace(content_mgcb)); err != nil {
|
|
return err
|
|
}
|
|
if err := writeFile(filepath.Join(flagO, "Content", "Shader.fx"), replaceNamespace(shader_fx)); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func runGo(subcmd string, srcs []string, env []string, args ...string) error {
|
|
cmd := exec.Command("go", subcmd)
|
|
if flagA {
|
|
cmd.Args = append(cmd.Args, "-a")
|
|
}
|
|
if flagGcflags != "" {
|
|
cmd.Args = append(cmd.Args, "-gcflags", flagGcflags)
|
|
}
|
|
if flagI {
|
|
cmd.Args = append(cmd.Args, "-i")
|
|
}
|
|
if flagLdflags != "" {
|
|
cmd.Args = append(cmd.Args, "-ldflags", flagLdflags)
|
|
}
|
|
if flagTags != "" {
|
|
cmd.Args = append(cmd.Args, "-tags", flagTags)
|
|
}
|
|
if flagTrimpath {
|
|
cmd.Args = append(cmd.Args, "-trimpath")
|
|
}
|
|
if flagV {
|
|
cmd.Args = append(cmd.Args, "-v")
|
|
}
|
|
if flagWork {
|
|
cmd.Args = append(cmd.Args, "-work")
|
|
}
|
|
if flagX {
|
|
cmd.Args = append(cmd.Args, "-x")
|
|
}
|
|
cmd.Args = append(cmd.Args, args...)
|
|
cmd.Args = append(cmd.Args, srcs...)
|
|
if len(env) > 0 {
|
|
cmd.Env = append([]string{}, env...)
|
|
}
|
|
|
|
if flagX || flagN {
|
|
env := strings.Join(cmd.Env, " ")
|
|
if env != "" {
|
|
env += " "
|
|
}
|
|
fmt.Fprintf(os.Stderr, "%s%s\n", env, strings.Join(cmd.Args, " "))
|
|
}
|
|
if flagN {
|
|
return nil
|
|
}
|
|
|
|
if len(cmd.Env) > 0 {
|
|
cmd.Env = append(os.Environ(), cmd.Env...)
|
|
}
|
|
|
|
buf := &bytes.Buffer{}
|
|
buf.WriteByte('\n')
|
|
if flagV {
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
} else {
|
|
cmd.Stdout = buf
|
|
cmd.Stderr = buf
|
|
}
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("%s failed: %v%s", strings.Join(cmd.Args, " "), err, buf)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func writeFile(dst string, src []byte) error {
|
|
if flagV {
|
|
fmt.Fprintf(os.Stderr, "Writing %s\n", dst)
|
|
}
|
|
|
|
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
|
|
return err
|
|
}
|
|
if err := ioutil.WriteFile(dst, src, 0644); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func replaceNamespace(src []byte) []byte {
|
|
return []byte(strings.ReplaceAll(string(src), "{{.Namespace}}", flagNamespace))
|
|
}
|