From e8448d7a2a7dd79ae5c8f23f072eace23de1bed8 Mon Sep 17 00:00:00 2001 From: pg9182 <96569817+pg9182@users.noreply.github.com> Date: Tue, 16 Apr 2024 03:44:30 -0400 Subject: [PATCH] all: Rework build process --- .github/workflows/plugins.yml | 33 +- build.go | 504 +++++++++++++++++++++++++ plugins/tf2vpk/main.go | 13 +- plugins/tf2vpk/rsrc_windows_386.syso | Bin 1028 -> 0 bytes plugins/tf2vpk/rsrc_windows_amd64.syso | Bin 1028 -> 0 bytes plugins/tf2vpk/rsrc_windows_arm64.syso | Bin 1028 -> 0 bytes z7plugin/genver/main.go | 112 ------ 7 files changed, 512 insertions(+), 150 deletions(-) create mode 100644 build.go delete mode 100644 plugins/tf2vpk/rsrc_windows_386.syso delete mode 100644 plugins/tf2vpk/rsrc_windows_amd64.syso delete mode 100644 plugins/tf2vpk/rsrc_windows_arm64.syso delete mode 100644 z7plugin/genver/main.go diff --git a/.github/workflows/plugins.yml b/.github/workflows/plugins.yml index 8f66b1f..e2c4dca 100644 --- a/.github/workflows/plugins.yml +++ b/.github/workflows/plugins.yml @@ -5,40 +5,19 @@ on: workflow_dispatch: jobs: - list: - name: list - runs-on: windows-latest - outputs: - plugins: ${{ steps.list.outputs.plugins }} - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: 'go.mod' - - run: echo "plugins=$(go list -json ./plugins/... | jq -cs 'map(.ImportPath|split("/")[-1])')" >> $GITHUB_OUTPUT - id: list - shell: bash - build: - needs: list - name: ${{matrix.plugin}} runs-on: windows-latest - strategy: - fail-fast: false - matrix: - plugin: ${{fromJSON(needs.list.outputs.plugins)}} steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version-file: 'go.mod' - run: go mod download - - run: go generate ./plugins/${{matrix.plugin}} - - env: { CGO_ENABLED: 1, GOOS: windows, GOARCH: amd64, CC: gcc, MSYSTEM: MINGW64 } - run: go build -buildmode=c-shared -ldflags '-s -w -extldflags=-static' -trimpath -v -x -o ${{matrix.plugin}}64.dll ./plugins/${{matrix.plugin}} - # - env: { CGO_ENABLED: 1, GOOS: windows, GOARCH: 386, CC: gcc, MSYSTEM: MINGW32 } - # run: go build -buildmode=c-shared -ldflags '-s -w -extldflags=-static' -trimpath -v -x -o ${{matrix.plugin}}32.dll ./plugins/${{matrix.plugin}} + - env: { CGO_ENABLED: 1, GOOS: windows, GOARCH: amd64, CC: x86_64-w64-mingw32-gcc, MSYSTEM: MINGW64 } + run: go run . 64 -ldflags '-s -w -extldflags=-static' -trimpath -v -x ./plugins/... + # - env: { CGO_ENABLED: 1, GOOS: windows, GOARCH: 386, CC: x86_64-w64-mingw32-gcc, MSYSTEM: MINGW32 } + # run: go run . 32 -ldflags '-s -w -extldflags=-static' -trimpath -v -x ./plugins/... - uses: actions/upload-artifact@v4 with: - name: ${{matrix.plugin}} - path: ${{matrix.plugin}}*.dll + name: plugins + path: '*.dll' diff --git a/build.go b/build.go new file mode 100644 index 0000000..6bfb5f0 --- /dev/null +++ b/build.go @@ -0,0 +1,504 @@ +/* +Command 7zplugin compiles a plugin DLL with the specified plugin packages named +by their import paths. + +This exists to allow arbitrary plugin choices to be easily built together since +there can only be one Go runtime in a process, so only one plugin DLL built +using 7zplugin can be used and must contain all desired plugins. + +The arch argument must be set to one of: + + - 64 64-bit x86 (CGO_ENABLED=1 GOOS=windows GOARCH=amd64) + - 32 32-bit x86_64 (CGO_ENABLED=1 GOOS=windows GOARCH=386) + - A64 64-bit arm (CGO_ENABLED=1 GOOS=windows GOARCH=arm64) + +Specify environment variables for go build (CC, CXX, etc) as arguments before +the flags. + +Flags are passed as-is to go build (see go help build). The only flag explicitly +set by this package is -buildmode=c-shared. It is highly recommended to also set +-ldflags '-s -w -extldflags=-static'. + +Version information is added to the built binary: + + - FileDescription is set to a list of packages/files used to build the plugin. + - FileVersion is set to YYYY.MM.DD.0 based on the current date, or the unix + timestamp in SOURCE_DATE_EPOCH. If GITHUB_ACTION is set, GITHUB_RUN_NUMBER is + used as the last component. + - InternalName is set to the default output dll basename. + - OriginalFilename is set based on InternalName and the architecture. + - ProductName describes this library. + - ProductVersion describes the target 7-Zip version and architecture. + +An example invocation of this command to build all default plugins (from within +the 7zplugin source dir): + + CC=x86_64-w64-mingw32-gcc go run . 64 -ldflags '-s -w -extldflags=-static' -trimpath -v -x ./plugins/... + +If using 7zplugin as a library, you can build the default plugins combined with +your plugin like: + + CC=x86_64-w64-mingw32-gcc go run github.com/pg9182/7zplugin 64 -ldflags '-s -w -extldflags=-static' -trimpath -v -x github.com/pg9182/7zplugin/plugins/... ./pluginpkg1 ./pluginpkg2 + +Each plugin package or file should contain an init() function which calls +z7plugin.RegisterArc (or imports packages which do). + +The built DLL file should be installed to the Formats directory beside the 7-Zip +executable. The architecture must match that of 7-Zip. +*/ +package main + +import ( + "bufio" + "bytes" + "context" + _ "embed" + "encoding/json" + "errors" + "fmt" + "io" + "os" + "os/exec" + "os/signal" + "path/filepath" + "reflect" + "slices" + "sort" + "strconv" + "strings" + "time" + "unicode" + + "github.com/josephspurrier/goversioninfo" + "github.com/pg9182/7zplugin/z7" +) + +//go:embed build.go +var self []byte +var doc string + +func init() { + var ok bool + if self, ok = bytes.CutPrefix(self, []byte("/*")); !ok { + panic("failed to find start of package doc") + } + if self, _, ok = bytes.Cut(self, []byte("*/")); !ok { + panic("failed to find end of package doc") + } + if crlf := []byte{'\r', '\n'}; bytes.Contains(self, crlf) { + self = bytes.ReplaceAll(self, crlf, []byte{'\n'}) + } else { + self = bytes.ReplaceAll(self, []byte{'\r'}, []byte{'\n'}) + } + doc = string(self) +} + +func help() { + fmt.Printf("usage: %s arch [ENV=VALUE...] [flags] [package...]\n%s", os.Args[0], doc) + os.Exit(0) +} + +var dllname = "go7zPlugin" + +func main() { + var err error + if len(os.Args) <= 1 { + help() + } + + // override the help flag + for i, arg := range os.Args { + if i == 0 { + continue + } + if arg == "-h" || arg == "--help" || arg == "-help" { + help() + } + } + + // expand the arch arg + var arch, z7arch string + switch arch = os.Args[1]; arch { + case "64": + os.Args[1] = "GOARCH=amd64" + z7arch = "x64" + case "32": + os.Args[1] = "GOARCH=386" + z7arch = "x86" + case "ARM64": + os.Args[1] = "GOARCH=arm64" + z7arch = "arm64" + default: + fmt.Fprintf(os.Stderr, "7zplugin: error: unknown arch %q\n", arch) + os.Exit(2) + } + os.Args = slices.Insert(os.Args, 1, "CGO_ENABLED=1", "GOOS=windows") + + // get the current dir + dir, err := os.Getwd() + if err != nil { + fmt.Fprintf(os.Stderr, "7zplugin: error: get working directory: %v\n", err) + os.Exit(2) + } + + // get the current go env + goEnv, err := goEnv() + if err != nil { + fmt.Fprintf(os.Stderr, "7zplugin: error: get go env: %v\n", err) + os.Exit(2) + } + + // show the current go env + fmt.Println("go env") + for _, x := range goEnv { + key, value, _ := strings.Cut(x, "=") + if strings.ContainsFunc(value, unicode.IsSpace) { + fmt.Printf(" %s=%q\n", key, value) + } else { + fmt.Printf(" %s=%s\n", key, value) + } + } + fmt.Println() + + // extract and set env vars from args + fmt.Println("go env override") + var env int + for env = 1; env < len(os.Args); env++ { + key, value, ok := strings.Cut(os.Args[env], "=") + if !ok { + break + } + if strings.ContainsFunc(value, unicode.IsSpace) { + fmt.Printf(" %s=%q\n", key, value) + } else { + fmt.Printf(" %s=%s\n", key, value) + } + if err := os.Setenv(key, value); err != nil { + fmt.Fprintf(os.Stderr, "7zplugin: error: setenv(%q, %q): %v\n", key, value, err) + os.Exit(1) + } + } + os.Args = slices.Delete(os.Args, 1, env) + fmt.Println() + + // extract the output filename from args if present, or set the default + var out string + for i, arg := range os.Args { + if i == 0 { + continue + } + if arg, ok := strings.CutPrefix(arg, "-o="); ok { + out = arg + os.Args = slices.Delete(os.Args, i, i+1) + } else if arg == "-o" { + if i+1 >= len(os.Args) { + fmt.Fprintf(os.Stderr, "error: error: expected output file after -o flag, got nothing\n") + os.Exit(1) + } + out = os.Args[i+1] + os.Args = slices.Delete(os.Args, i, i+2) + } + } + if out == "" { + out = dllname + arch + ".dll" + } + + // extract package names from args + var ( + pkg []string + files []string + ) + for i := len(os.Args) - 1; i >= 1; i-- { + x := os.Args[i] + if strings.HasPrefix(x, "-") { + break // found a flag + } + if strings.HasSuffix(x, ".go") { + if _, err := os.Stat(x); err != nil { + fmt.Fprintf(os.Stderr, "7zplugin: error: expand package list: file %q is not accessible: %v\n", x, err) + if i > 1 && strings.HasPrefix(os.Args[i-1], "-") { + fmt.Fprintf(os.Stderr, "7zplugin: note: if you are trying to specify a go build flag with a value, you must use the syntax '-flag=value rather than -flag value'\n") + } + os.Exit(1) + } + files = append(files, x) + } else { + pkg = append(pkg, x) + } + os.Args = slices.Delete(os.Args, i, i+1) + } + if pkg, err = goList(pkg...); err != nil { + fmt.Fprintf(os.Stderr, "7zplugin: error: expand package list: %v\n", err) + os.Exit(1) + } + + // add the default build flags + os.Args = slices.Insert(os.Args, 1, "-buildmode=c-shared") + + // get the build date + built := time.Now().UTC() + if x, ok := os.LookupEnv("SOURCE_DATE_EPOCH"); ok { + n, err := strconv.ParseInt(x, 0, 64) + if err != nil { + fmt.Fprintf(os.Stderr, "7zplugin: error: parse SOURCE_DATE_EPOCH: %v\n", err) + os.Exit(1) + } + built = time.Unix(n, 0) + } + + // set the version info and default filename + var pluginDesc []string + for _, x := range pkg { + pluginDesc = append(pluginDesc, strings.TrimPrefix(x, "github.com/pg9182/7zplugin/plugins/")) + } + for _, x := range files { + pluginDesc = append(pluginDesc, strings.TrimSuffix(x, ".go")) + } + var ver = goversioninfo.VersionInfo{ + FixedFileInfo: goversioninfo.FixedFileInfo{ + FileVersion: goversioninfo.FileVersion{ + Major: built.Year(), + Minor: int(built.Month()), + Patch: built.Day(), + Build: 0, + }, + }, + StringFileInfo: goversioninfo.StringFileInfo{ + ProductName: "Go Plugins for 7-Zip (github.com/pg9182/7zplugin)", + ProductVersion: "7-Zip " + z7.MY_VERSION_NUMBERS + "+ (" + z7arch + ")", + FileDescription: strings.Join(pluginDesc, ", "), + InternalName: strings.ToUpper(dllname), + OriginalFilename: strings.ToUpper(dllname + arch + ".dll"), + }, + } + if _, ok := os.LookupEnv("GITHUB_ACTION"); ok { + if v, ok := os.LookupEnv("GITHUB_REPOSITORY_OWNER"); ok { + ver.StringFileInfo.CompanyName = v + " (github.com/" + v + ")" + } + if v, ok := os.LookupEnv("GITHUB_RUN_NUMBER"); ok { + if v, err := strconv.ParseInt(v, 10, 16); err == nil { + ver.FixedFileInfo.FileVersion.Build = int(v) + } + } + if v, ok := os.LookupEnv("GITHUB_SHA"); ok { + if len(v) > 7 { + v = v[:7] + } + ver.StringFileInfo.FileVersion = " (" + v + ")" + ver.StringFileInfo.FileVersion + } + } + ver.StringFileInfo.FileVersion = ver.FixedFileInfo.FileVersion.GetVersionString() + ver.StringFileInfo.FileVersion + + // catch ctrl+c + ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) + defer stop() + + // run the build + if err = build(ctx, dir, os.Args[1:], files, pkg, out, ver); err != nil { + + // got ctrl+c + if errors.Is(err, context.Canceled) { + fmt.Fprintf(os.Stderr, "interrupted\n") + } + + // go build exit status non-zero + var ee *exec.ExitError + if errors.As(err, &ee) { + status := ee.ExitCode() + fmt.Fprintf(os.Stderr, "go build exited with status %d\n", status) + os.Exit(status) + } + + // other error + fmt.Fprintf(os.Stderr, "7zplugin: error: %v\n", err) + os.Exit(1) + } +} + +func build(ctx context.Context, dir string, flags []string, files []string, pkg []string, out string, ver goversioninfo.VersionInfo) error { + var err error + + // make a temp dir + td := filepath.Join(dir, "z7plugin-build") // fixed name for reproducibility + if err := os.Mkdir(td, 0777); err != nil { + return fmt.Errorf("create build dir: %w", err) + } + defer func() { + if err := os.RemoveAll(td); err != nil { + fmt.Printf("warning: failed to remove temp dir %s: %v\n", td, err) + return + } + }() + + // show the temp dir + fmt.Printf("in %s\n\n", td) + + // gitignore everything in it + if err := os.WriteFile(filepath.Join(td, ".gitignore"), []byte("*\n"), 0666); err != nil { + return fmt.Errorf("write gitgnore: %w", err) + } + + // copy and show the standalone go files + for _, x := range files { + if buf, err := os.ReadFile(x); err != nil { + return fmt.Errorf("copy standalone go file %s: read: %w", x, err) + } else if err := os.WriteFile(filepath.Join(td, filepath.Base(x)), buf, 0666); err != nil { + return fmt.Errorf("copy standalone go file %s: write: %w", x, err) + } + fmt.Printf("%s\n < %s\n\n", filepath.Base(x), filepath.Join(dir, x)) + } + + // generate the go source + var src bytes.Buffer + fmt.Fprintln(&src, "package main") + fmt.Fprintln(&src) + fmt.Fprintf(&src, "import _ %q\n", "github.com/pg9182/7zplugin/z7plugin") + for _, x := range pkg { + fmt.Fprintf(&src, "import _ %q\n", x) + } + fmt.Fprintln(&src) + fmt.Fprintln(&src, "func main() {}") + + // save the go source + if err := writeFileExcl(filepath.Join(td, "z7plugin.go"), src.Bytes(), 0666); err != nil { + return fmt.Errorf("save generated go source: %w", err) + } + + // show the generated source file + fmt.Println("z7plugin.go") + sc, line := bufio.NewScanner(bytes.NewReader(src.Bytes())), 0 + for sc.Scan() { + line++ + fmt.Printf("%3d | %s\n", line, sc.Text()) + } + fmt.Println() + + // generate the resource files + ver.Build() + ver.Walk() + + // save the resource file syso + if err := ver.WriteSyso(filepath.Join(td, "rsrc.syso"), os.Getenv("GOARCH")); err != nil { + return fmt.Errorf("generate rsrc syso: %w", err) + } + + // show the generated resource file + fmt.Println("rsrc.syso") + for v, i := reflect.ValueOf(ver.StringFileInfo), 0; i < v.NumField(); i++ { + if f := v.Type().Field(i); f.Type.Kind() == reflect.String { + if x := v.Field(i).String(); x != "" { + fmt.Printf("%3d | %-16s %q\n", i+1, f.Name, x) + } + } + } + fmt.Println() + + // resolve the output path + if out, err = filepath.Abs(out); err != nil { + return fmt.Errorf("resolve output path: %w", err) + } + + // actually run the build + cmd := exec.CommandContext(ctx, "go", "build") + cmd.Args = append(cmd.Args, "-o", out) + cmd.Args = append(cmd.Args, flags...) + cmd.Dir = td + cmd.Env = os.Environ() + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Stdin = nil + + // show the build command + for i, arg := range cmd.Args { + if strings.ContainsFunc(arg, unicode.IsSpace) { + arg = strconv.Quote(arg) + } + if i != 0 { + fmt.Print(" ") + } + fmt.Print(arg) + } + fmt.Println() + + if err := cmd.Run(); err != nil { + return fmt.Errorf("go build: %w", err) + } + return nil +} + +func goEnv() ([]string, error) { + var buf bytes.Buffer + + cmd := exec.Command("go", "env", "-json") + cmd.Stdin = nil + cmd.Stdout = &buf + cmd.Stderr = os.Stderr + cmd.Env = os.Environ() + + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("run command %q: %w", cmd.Args, err) + } + + var obj map[string]string + if err := json.Unmarshal(buf.Bytes(), &obj); err != nil { + return nil, fmt.Errorf("parse output of command %q: %w", cmd.Args, err) + } + + var env []string + for k, v := range obj { + env = append(env, k+"="+v) + } + sort.Strings(env) + + return env, nil +} + +func goList(pkg ...string) ([]string, error) { + var buf bytes.Buffer + + cmd := exec.Command("go", "list", "-json", "--") + cmd.Args = append(cmd.Args, pkg...) + cmd.Stdin = nil + cmd.Stdout = &buf + cmd.Stderr = os.Stderr + cmd.Env = os.Environ() + + if err := cmd.Run(); err != nil { + return nil, fmt.Errorf("run command %q: %w", cmd.Args, err) + } + + var imp []string + for dec := json.NewDecoder(&buf); ; { + var obj struct { + ImportPath string + } + if err := dec.Decode(&obj); err != nil { + if err == io.EOF { + break + } + return nil, fmt.Errorf("parse output of command %q: %w", cmd.Args, err) + } + if obj.ImportPath == "" { + return nil, fmt.Errorf("parse output of command %q: missing ImportPath", cmd.Args) + } + imp = append(imp, obj.ImportPath) + } + return imp, nil +} + +func writeFileExcl(name string, data []byte, perm os.FileMode) error { + f, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC|os.O_EXCL, perm) + if err != nil { + return err + } + _, err = f.Write(data) + if err != nil { + os.Remove(name) + return err + } + if err := f.Close(); err != nil { + os.Remove(name) + return err + } + return nil +} diff --git a/plugins/tf2vpk/main.go b/plugins/tf2vpk/main.go index 5e29452..cd24fe6 100644 --- a/plugins/tf2vpk/main.go +++ b/plugins/tf2vpk/main.go @@ -1,6 +1,6 @@ -// Command tf2vpk is a 7-Zip archive format plugin for Respawn VPKs as used in +// Package tf2vpk is a 7-Zip archive format plugin for Respawn VPKs as used in // Titanfall 2. -package main +package tf2vpk import ( "github.com/lxn/win" @@ -9,13 +9,6 @@ import ( "github.com/pg9182/7zplugin/z7plugin" ) -//go:generate go run github.com/pg9182/7zplugin/z7plugin/genver -owner pg9182 -company pg9182 -copyright "© 2024 pg9182 (github.com/pg9182)" -description "Respawn VPK Plugin for 7-Zip" - -// go generate ./plugins/tf2vpk -// CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc go build -buildmode=c-shared -ldflags '-s -w -extldflags=-static' -trimpath -v -x -o tf2vpk64.dll ./plugins/tf2vpk -// CGO_ENABLED=1 GOOS=windows GOARCH=386 CC=i686-w64-mingw32-gcc go build -buildmode=c-shared -ldflags '-s -w -extldflags=-static' -trimpath -v -x -o tf2vpk32.dll ./plugins/tf2vpk -// put the correct one in Program Files/7-Zip/Formats/ (note: arch must match) - func init() { z7plugin.RegisterArc(&z7plugin.CArcInfo{ Name: "VPK0203", @@ -27,5 +20,3 @@ func init() { CreateInArchive: func() {}, // TODO }) } - -func main() {} diff --git a/plugins/tf2vpk/rsrc_windows_386.syso b/plugins/tf2vpk/rsrc_windows_386.syso deleted file mode 100644 index 28e53ef307da70b85583dc7eb2fb541a70a536c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1028 zcma)*K}#D^6ot>2fVdD`7NiiR3kz+GQK*6oK`oUIH6#+mjik}WK#ap=(o$Dl_NP?v zFZADZZT~^(ckg7JiMsG5^X9$#&O7(q^WKC(AZvFeDIJxAYCMX&9!wbx zwcq8x|1#Acct&?SV>?<(6sxbHda(61&^gRQebE&hKOIxk^iRxZ*}DtoQjt2~zoVwZ z?A$X)ux)8go2vW#OfSJ_{Cl8A>U!RY{C#+aj%)ggF@7Ubq2`7@@@}AO45#U=xVD)0 zJH6EjvB>xC;Ch~;4O2{(oV%tfy0fRE6`g_k$}`Yw7}A=o_QdxNQ86e~b%g%|(&FgK{I!(7(}qoOO8-|9&~j`bN`U3YVJ3T3+XG*6zx39mU| zx-u_qmbzZlw@$_?J41ffj^q*j<}GPjhYE&uY!mP>J2uHnqn0mFKrqdL=#}9kFV6afHea73ODe9MZ KmmLr(Im3Usc7GlK diff --git a/plugins/tf2vpk/rsrc_windows_amd64.syso b/plugins/tf2vpk/rsrc_windows_amd64.syso deleted file mode 100644 index 0eae2d232deaf3226a962a21cbf1367dc381c9aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1028 zcma)*K}#D^6ot>2Kye|sER;f&E)+DzRB8nmLbWIjHK+vXrlg6DfixK=6Gd09ia$lc zztDfvb^QmW-@TLROw@%hnK$peRZk}{_w`)^IIbO2(d19eU$FNBm>&w&1b=~= zCbJXI9KyDtRlQf$=WV?PpYm^m8mi@aL-Kdw={xSgSB&wTNQs*3`oz1At`VH3v*g+$ z-s@V{7h<9B-NN-OM+2saEE#u2Wpt-cNegO&IpgVR5r(8Dt3CF;eN^;vRUM(fI#y%} zPc=`z8rY5_&5aNr%*_s~F_>FaR$;DcjZxke%Ww6>AV>O!u9myGGJ!H(+nOQI{+QPs zFkPvaHcMR3>w8DOGCOPhtR3qW9CbJbR6QbBoU2UFP_lyCmuSn*!FW$K_lWnQ^O@)7 z{X^fEh}d15JWq4&t)JDZrJ)kLs|{+6{#TyeQt6HOfON#F-Nhj)n^c&cy>VExZ_HXj L`7b;0h%x*FHAa8D diff --git a/plugins/tf2vpk/rsrc_windows_arm64.syso b/plugins/tf2vpk/rsrc_windows_arm64.syso deleted file mode 100644 index 4ef4d3f4718edfe937bdf9ad8b37c262b7602ed3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1028 zcma)*PfHt76vfY&K-8-4i#Jcb$^X9$#&O7(q^WL=Y0$KZ2kdjd`C`W^+<!V-=^PW zZ0(`=`%kLc1JCI0Cv3;QVnynzuMTWo^>hStU&lIwHz)Kks?cY zqIcx0f$ccb+z9c(-0ZL#gSkaz73QiI80B5D{8mp4a;WdQ#xi?r{On%6fujz`8C4I-73V6`GnCBX_9fb~bAT4@Q~&Wkc0Tjm zynpQb3=z9) 7 { - v = v[:7] - } - ver.StringFileInfo.FileVersion = ver.FixedFileInfo.FileVersion.GetVersionString() + " (" + v + ")" - ver.StringFileInfo.ProductVersion = ver.FixedFileInfo.ProductVersion.GetVersionString() + " (" + v + ")" - } - } - // so the update doesn't make the git repo dirty - if err := os.WriteFile(".gitignore", []byte(".gitignore\n*.syso\n"), 0644); err != nil { - panic(err) - } - } - } - - enc := json.NewEncoder(os.Stdout) - enc.SetIndent("", " ") - enc.Encode(ver.StringFileInfo) - - ver.StringFileInfo.OriginalFilename = ver.StringFileInfo.InternalName + "64.DLL" - ver.Build() - ver.Walk() - if err := ver.WriteSyso("rsrc_windows_amd64.syso", "amd64"); err != nil { - panic(err) - } - - ver.StringFileInfo.OriginalFilename = ver.StringFileInfo.InternalName + "A64.DLL" - ver.Build() - ver.Walk() - if err := ver.WriteSyso("rsrc_windows_arm64.syso", "arm64"); err != nil { - panic(err) - } - - ver.StringFileInfo.OriginalFilename = ver.StringFileInfo.InternalName + "32.DLL" - ver.Build() - ver.Walk() - if err := ver.WriteSyso("rsrc_windows_386.syso", "386"); err != nil { - panic(err) - } -}