diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 162faf630..d7c822424 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - go: ['1.12.17', '1.13.15', '1.14.10', '1.15.3'] + go: ['1.13.15', '1.14.10', '1.15.3'] name: Test with Go ${{ matrix.go }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} env: diff --git a/go.mod b/go.mod index 9acc3ac7a..babbbb29d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/hajimehoshi/ebiten/v2 -go 1.12 +go 1.13 require ( github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200707082815-5321531c36a2 diff --git a/goversion.go b/goversion.go index edffd6472..42de102f6 100644 --- a/goversion.go +++ b/goversion.go @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build go1.12 +// +build go1.13 package ebiten -// Ebiten forces to use Go 1.12 or later, since +// Ebiten forces to use Go 1.13 or later, since // 1) Between Go 1.10 and Go 1.11, ioutil.TempFile's behavior is different. Ebiten forces the Go version in order to avoid confusion. (#777) // 2) FuncOf in syscall/js is defined as of Go 1.12. +// 3) os.UserConfigDir is defined as of Go 1.13. -const __EBITEN_REQUIRES_GO_VERSION_1_12_OR_LATER__ = true +const __EBITEN_REQUIRES_GO_VERSION_1_13_OR_LATER__ = true diff --git a/init.go b/init.go index 4de656168..7f61ca8aa 100644 --- a/init.go +++ b/init.go @@ -18,7 +18,7 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/graphicscommand" ) -var _ = __EBITEN_REQUIRES_GO_VERSION_1_12_OR_LATER__ +var _ = __EBITEN_REQUIRES_GO_VERSION_1_13_OR_LATER__ func init() { graphicscommand.SetGraphicsDriver(uiDriver().Graphics()) diff --git a/internal/glfw/gen.go b/internal/glfw/gen.go index 3d82973bb..42323a0e3 100644 --- a/internal/glfw/gen.go +++ b/internal/glfw/gen.go @@ -17,7 +17,11 @@ package main import ( + "bytes" + "crypto/sha256" + "encoding/hex" "fmt" + "io/ioutil" "os" "os/exec" "path/filepath" @@ -107,11 +111,10 @@ func run() error { return err } - in, err := os.Open(dll) + in, err := ioutil.ReadFile(dll) if err != nil { return err } - defer in.Close() out, err := os.Create(fmt.Sprintf("glfwdll_windows_%s.go", arch)) if err != nil { @@ -120,10 +123,27 @@ func run() error { defer out.Close() // As the file name already specified the build environment, buildtags are not requried. - if err := file2byteslice.Write(out, in, true, "", "glfw", "glfwDLLCompressed"); err != nil { + if err := file2byteslice.Write(out, bytes.NewReader(in), true, "", "glfw", "glfwDLLCompressed"); err != nil { return err } + // Dump the hash + hashout, err := os.Create(fmt.Sprintf("glfwdllhash_windows_%s.go", arch)) + if err != nil { + return err + } + defer hashout.Close() + hash := sha256.Sum256(in) + if _, err := fmt.Fprintf(hashout, `// Code generated by gen.go. DO NOT EDIT. + +package glfw + +const glfwDLLHash = "%s" +`, hex.EncodeToString(hash[:])); err != nil { + return err + } + + // Clean up the files. for _, o := range objs { if err := os.Remove(o); err != nil { return err diff --git a/internal/glfw/glfwdllhash_windows_386.go b/internal/glfw/glfwdllhash_windows_386.go new file mode 100644 index 000000000..302ebfffe --- /dev/null +++ b/internal/glfw/glfwdllhash_windows_386.go @@ -0,0 +1,5 @@ +// Code generated by gen.go. DO NOT EDIT. + +package glfw + +const glfwDLLHash = "93ce68219cb0e920a0b9f04a38bbeff104f530a643fd0a792215572525869f90" diff --git a/internal/glfw/glfwdllhash_windows_amd64.go b/internal/glfw/glfwdllhash_windows_amd64.go new file mode 100644 index 000000000..c3d3eaf0d --- /dev/null +++ b/internal/glfw/glfwdllhash_windows_amd64.go @@ -0,0 +1,5 @@ +// Code generated by gen.go. DO NOT EDIT. + +package glfw + +const glfwDLLHash = "9297f0b5337eb17f170398f4e027f59a8daf502cb45cff9b74b615d70d8369c2" diff --git a/internal/glfw/load_windows.go b/internal/glfw/load_windows.go index 889afe064..35d2a6042 100644 --- a/internal/glfw/load_windows.go +++ b/internal/glfw/load_windows.go @@ -19,8 +19,8 @@ import ( "compress/gzip" "fmt" "io" - "io/ioutil" "os" + "path/filepath" "unsafe" "golang.org/x/sys/windows" @@ -28,7 +28,6 @@ import ( type dll struct { d *windows.LazyDLL - path string procs map[string]*windows.LazyProc } @@ -47,37 +46,45 @@ func (d *dll) call(name string, args ...uintptr) uintptr { return r } -func createTempDLL(content io.Reader) (string, error) { - f, err := ioutil.TempFile("", "glfw.*.dll") - if err != nil { - return "", err - } - defer f.Close() - - fn := f.Name() - - if _, err := io.Copy(f, content); err != nil { - return "", err - } - - return fn, nil -} - func loadDLL() (*dll, error) { - f, err := gzip.NewReader(bytes.NewReader(glfwDLLCompressed)) + cachedir, err := os.UserCacheDir() if err != nil { return nil, err } - defer f.Close() - fn, err := createTempDLL(f) - if err != nil { + dir := filepath.Join(cachedir, "ebiten") + if err := os.MkdirAll(dir, 0755); err != nil { return nil, err } + fn := filepath.Join(dir, glfwDLLHash+".dll") + if _, err := os.Stat(fn); err != nil { + if !os.IsNotExist(err) { + return nil, err + } + + f, err := gzip.NewReader(bytes.NewReader(glfwDLLCompressed)) + if err != nil { + return nil, err + } + defer f.Close() + + out, err := os.Create(fn) + if err != nil { + return nil, err + } + defer out.Close() + + if _, err := io.Copy(out, f); err != nil { + return nil, err + } + if err := out.Sync(); err != nil { + return nil, err + } + } + return &dll{ - d: windows.NewLazyDLL(fn), - path: fn, + d: windows.NewLazyDLL(fn), }, nil } @@ -85,9 +92,6 @@ func (d *dll) unload() error { if err := windows.FreeLibrary(windows.Handle(d.d.Handle())); err != nil { return err } - if err := os.Remove(d.path); err != nil { - return err - } return nil }