-
Notifications
You must be signed in to change notification settings - Fork 51
/
windows.go
118 lines (100 loc) · 3.6 KB
/
windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
//
// Windows cross build using mingw-w64
//
import (
"errors"
"os"
"strings"
"github.com/apex/log"
"github.com/ooni/probe-cli/v3/internal/cmd/buildtool/internal/buildtoolmodel"
"github.com/ooni/probe-cli/v3/internal/must"
"github.com/ooni/probe-cli/v3/internal/runtimex"
"github.com/ooni/probe-cli/v3/internal/shellx"
"github.com/spf13/cobra"
)
// windowsSubcommand returns the windows sucommand.
func windowsSubcommand() *cobra.Command {
return &cobra.Command{
Use: "windows",
Short: "Builds ooniprobe and miniooni for windows",
Run: func(cmd *cobra.Command, args []string) {
windowsBuildAll(&buildDeps{})
},
Args: cobra.NoArgs,
}
}
// windowsBuildAll is the main function of the windows subcommand.
func windowsBuildAll(deps buildtoolmodel.Dependencies) {
deps.PsiphonMaybeCopyConfigFiles()
deps.GolangCheck()
deps.WindowsMingwCheck()
archs := []string{"386", "amd64"}
products := []*product{productMiniooni, productOoniprobe}
for _, arch := range archs {
for _, product := range products {
windowsBuildPackage(deps, arch, product)
}
}
}
// windowsBuildPackage builds the given package for windows
// compiling for the specified architecture.
func windowsBuildPackage(deps buildtoolmodel.Dependencies, goarch string, product *product) {
log.Infof("building %s for windows/%s", product.Pkg, goarch)
argv := runtimex.Try1(shellx.NewArgv("go", "build"))
if deps.PsiphonFilesExist() {
argv.Append("-tags", "ooni_psiphon_config")
}
argv.Append("-ldflags", "-s -w")
argv.Append("-o", product.DestinationPath("windows", goarch))
argv.Append(product.Pkg)
envp := &shellx.Envp{}
switch goarch {
case "amd64":
envp.Append("CC", windowsMingwAmd64Compiler)
case "386":
envp.Append("CC", windowsMingw386Compiler)
default:
panic(errors.New("unsupported windows goarch"))
}
envp.Append("CGO_ENABLED", "1")
envp.Append("GOARCH", goarch)
envp.Append("GOOS", "windows")
runtimex.Try0(shellx.RunEx(defaultShellxConfig(), argv, envp))
}
// windowsMingwExpectedVersion is the expected version of mingw-w64,
// which may be overriden by setting the EXPECTED_MINGW_W64_VERSION
// environment variable before starting the build.
var windowsMingwExpectedVersion = "12.2.0"
// windowsMingwEnvironmentVariable is the name of the environment variable
// that overrides the expected mingw version.
const windowsMingwEnvironmentVariable = "EXPECTED_MINGW_W64_VERSION"
// windowsMingwAmd64Compiler is the amd64 compiler.
const windowsMingwAmd64Compiler = "x86_64-w64-mingw32-gcc"
// windowsMingw386Compiler is the 386 compiler.
const windowsMingw386Compiler = "i686-w64-mingw32-gcc"
// windowsMingwCheck checks we're using the correct mingw version.
func windowsMingwCheck() {
windowsMingwCheckFor(windowsMingwAmd64Compiler)
windowsMingwCheckFor(windowsMingw386Compiler)
}
// windowsMingwCheckFor implements mingwCheck for the given compiler.
func windowsMingwCheckFor(compiler string) {
expected := windowsMingwExpectedVersionGetter()
firstLine := string(must.FirstLineBytes(must.RunOutputQuiet(compiler, "--version")))
v := strings.Split(firstLine, " ")
runtimex.Assert(len(v) >= 3, "expected to see three tokens or more")
if got := v[2]; got != expected {
log.Fatalf("expected mingw %s but got %s", expected, got)
}
log.Infof("using %s %s", compiler, expected)
}
// windowsMingwEexpectedVersionGetter returns the correct expected mingw version.
func windowsMingwExpectedVersionGetter() string {
value := os.Getenv(windowsMingwEnvironmentVariable)
if value == "" {
return windowsMingwExpectedVersion
}
log.Infof("mingw version overriden using %s", windowsMingwEnvironmentVariable)
return value
}