// Copyright 2021 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. // +build ignore package main import ( "bytes" "fmt" "io" "io/fs" "os" "os/exec" "path/filepath" "regexp" "strings" ) const oboeVersion = "1.5.0" func main() { if err := run(); err != nil { panic(err) } } func run() error { if err := clean(); err != nil { return err } tmp, err := os.MkdirTemp("", "oboe-") if err != nil { return err } defer os.RemoveAll(tmp) if err := prepareOboe(tmp); err != nil { return err } return nil } func clean() error { fmt.Printf("Cleaning *.cpp and *.h files\n") if err := filepath.Walk(".", func(path string, info fs.FileInfo, err error) error { if err != nil { return err } if info.IsDir() && path != "." { return filepath.SkipDir } base := filepath.Base(path) if base == "README-oboe.md" { return os.Remove(base) } if base == "LICENSE-oboe" { return os.Remove(base) } if !strings.HasPrefix(base, "oboe_") { return nil } if !strings.HasSuffix(base, ".cpp") && !strings.HasSuffix(base, ".h") { return nil } return os.Remove(base) }); err != nil { return err } return nil } func prepareOboe(tmp string) error { fn := oboeVersion + ".tar.gz" if e, err := exists(fn); err != nil { return err } else if !e { url := "https://github.com/google/oboe/archive/refs/tags/" + fn fmt.Fprintf(os.Stderr, "%s not found: please download it from %s\n", fn, url) return nil } fmt.Printf("Copying %s to %s\n", fn, filepath.Join(tmp, fn)) in, err := os.Open(fn) if err != nil { return err } defer in.Close() out, err := os.Create(filepath.Join(tmp, fn)) if err != nil { return err } defer out.Close() if _, err := io.Copy(out, in); err != nil { return err } fmt.Printf("Extracting %s\n", fn) cmd := exec.Command("tar", "-xzf", fn) cmd.Stderr = os.Stderr cmd.Dir = tmp if err := cmd.Run(); err != nil { return err } reInclude := regexp.MustCompile(`(?m)^#include\s+([<"])(.+)[>"]$`) fmt.Printf("Copying *.cpp and *.h files\n") for _, dir := range []string{"src", "include"} { dir := dir indir := filepath.Join(tmp, "oboe-"+oboeVersion, dir) if err := filepath.Walk(indir, func(path string, info fs.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { return nil } if !strings.HasSuffix(path, ".cpp") && !strings.HasSuffix(path, ".h") { return nil } f, err := filepath.Rel(indir, path) if err != nil { return err } ext := filepath.Ext(f) curTs := strings.Split(f[:len(f)-len(ext)], string(filepath.Separator)) outfn := "oboe_" + strings.Join(curTs, "_") + "_android" + ext if _, err := os.Stat(outfn); err == nil { return fmt.Errorf("%s must not exist", outfn) } in, err := os.ReadFile(path) if err != nil { return err } // Replace #include paths. in = reInclude.ReplaceAllFunc(in, func(inc []byte) []byte { m := reInclude.FindSubmatch(inc) f := string(m[2]) searchDirs := []string{filepath.Dir(path)} if dir == "src" { searchDirs = append(searchDirs, filepath.Join(tmp, "oboe-"+oboeVersion, "src")) } searchDirs = append(searchDirs, filepath.Join(tmp, "oboe-"+oboeVersion, "include")) for _, searchDir := range searchDirs { path := filepath.Join(searchDir, f) e, err := exists(path) if err != nil { panic(err) } if !e { continue } f, err := filepath.Rel(filepath.Join(tmp, "oboe-"+oboeVersion), path) if err != nil { panic(err) } ext := filepath.Ext(f) ts := strings.Split(f[:len(f)-len(ext)], string(filepath.Separator)) // The first token is 'src' or 'include'. Remove this. ts = ts[1:] newpath := "oboe_" + strings.Join(ts, "_") + "_android" + ext return []byte(`#include "` + newpath + `"`) } return inc }) out, err := os.Create(outfn) if err != nil { return err } defer out.Close() if _, err := io.Copy(out, bytes.NewReader(in)); err != nil { return err } return nil }); err != nil { return err } } fmt.Printf("Copying README.md and LICENSE\n") for _, f := range []string{"README.md", "LICENSE"} { infn := filepath.Join(tmp, "oboe-"+oboeVersion, f) ext := filepath.Ext(f) outfn := f[:len(f)-len(ext)] + "-oboe" + ext in, err := os.Open(infn) if err != nil { return err } defer in.Close() out, err := os.Create(outfn) if err != nil { return err } defer out.Close() if _, err := io.Copy(out, in); err != nil { return err } } return nil } func exists(path string) (bool, error) { if _, err := os.Stat(path); err != nil { if os.IsNotExist(err) { return false, nil } return false, err } return true, nil }