@@ -36,17 +36,19 @@ source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
36
36
version=" "
37
37
os=" ${GOOS:- linux} "
38
38
arch=" ${GOARCH:- amd64} "
39
+ output_path=" "
39
40
slim=" ${CODER_SLIM_BUILD:- 0} "
41
+ agpl=" ${CODER_BUILD_AGPL:- 0} "
40
42
sign_darwin=" ${CODER_SIGN_DARWIN:- 0} "
41
43
sign_windows=" ${CODER_SIGN_WINDOWS:- 0} "
42
- bin_ident=" com.coder.cli"
43
- output_path=" "
44
- agpl=" ${CODER_BUILD_AGPL:- 0} "
45
44
boringcrypto=${CODER_BUILD_BORINGCRYPTO:- 0}
46
- debug=0
47
45
dylib=0
46
+ windows_resources=" ${CODER_WINDOWS_RESOURCES:- 0} "
47
+ debug=0
48
+
49
+ bin_ident=" com.coder.cli"
48
50
49
- args=" $( getopt -o " " -l version:,os:,arch:,output:,slim,agpl,sign-darwin,boringcrypto,dylib,debug -- " $@ " ) "
51
+ args=" $( getopt -o " " -l version:,os:,arch:,output:,slim,agpl,sign-darwin,sign-windows, boringcrypto,dylib,windows-resources ,debug -- " $@ " ) "
50
52
eval set -- " $args "
51
53
while true ; do
52
54
case " $1 " in
@@ -79,6 +81,10 @@ while true; do
79
81
sign_darwin=1
80
82
shift
81
83
;;
84
+ --sign-windows)
85
+ sign_windows=1
86
+ shift
87
+ ;;
82
88
--boringcrypto)
83
89
boringcrypto=1
84
90
shift
@@ -87,6 +93,10 @@ while true; do
87
93
dylib=1
88
94
shift
89
95
;;
96
+ --windows-resources)
97
+ windows_resources=1
98
+ shift
99
+ ;;
90
100
--debug)
91
101
debug=1
92
102
shift
@@ -115,11 +125,13 @@ if [[ "$sign_darwin" == 1 ]]; then
115
125
dependencies rcodesign
116
126
requiredenvs AC_CERTIFICATE_FILE AC_CERTIFICATE_PASSWORD_FILE
117
127
fi
118
-
119
128
if [[ " $sign_windows " == 1 ]]; then
120
129
dependencies java
121
130
requiredenvs JSIGN_PATH EV_KEYSTORE EV_KEY EV_CERTIFICATE_PATH EV_TSA_URL GCLOUD_ACCESS_TOKEN
122
131
fi
132
+ if [[ " $windows_resources " == 1 ]]; then
133
+ dependencies go-winres
134
+ fi
123
135
124
136
ldflags=(
125
137
-X " 'github.com/coder/coder/v2/buildinfo.tag=$version '"
@@ -204,10 +216,100 @@ if [[ "$boringcrypto" == 1 ]]; then
204
216
goexp=" boringcrypto"
205
217
fi
206
218
219
+ # On Windows, we use go-winres to embed the resources into the binary.
220
+ if [[ " $windows_resources " == 1 ]] && [[ " $os " == " windows" ]]; then
221
+ # Convert the version to a format that Windows understands.
222
+ # Remove any trailing data after a "+" or "-".
223
+ version_windows=$version
224
+ version_windows=" ${version_windows% +* } "
225
+ version_windows=" ${version_windows% -* } "
226
+ # If there wasn't any extra data, add a .0 to the version. Otherwise, add
227
+ # a .1 to the version to signify that this is not a release build so it can
228
+ # be distinguished from a release build.
229
+ non_release_build=0
230
+ if [[ " $version_windows " == " $version " ]]; then
231
+ version_windows+=" .0"
232
+ else
233
+ version_windows+=" .1"
234
+ non_release_build=1
235
+ fi
236
+
237
+ if [[ ! " $version_windows " =~ ^[0-9]+\. [0-9]+\. [0-9]+\. [0-1]$ ]]; then
238
+ error " Computed invalid windows version format: $version_windows "
239
+ fi
240
+
241
+ # File description changes based on slimness, AGPL status, and architecture.
242
+ file_description=" Coder"
243
+ if [[ " $agpl " == 1 ]]; then
244
+ file_description+=" AGPL"
245
+ fi
246
+ if [[ " $slim " == 1 ]]; then
247
+ file_description+=" CLI"
248
+ fi
249
+ if [[ " $non_release_build " == 1 ]]; then
250
+ file_description+=" (development build)"
251
+ fi
252
+
253
+ # Because this writes to a file with the OS and arch in the filename, we
254
+ # don't support concurrent builds for the same OS and arch (irregardless of
255
+ # slimness or AGPL status).
256
+ #
257
+ # This is fine since we only embed resources during dogfood and release
258
+ # builds, which use make (which will build all slim targets in parallel,
259
+ # then all non-slim targets in parallel).
260
+ expected_rsrc_file=" ./buildinfo/resources/resources_windows_${arch} .syso"
261
+ if [[ -f " $expected_rsrc_file " ]]; then
262
+ rm " $expected_rsrc_file "
263
+ fi
264
+ touch " $expected_rsrc_file "
265
+
266
+ pushd ./buildinfo/resources
267
+ GOARCH=" $arch " go-winres simply \
268
+ --arch " $arch " \
269
+ --out " resources" \
270
+ --product-version " $version_windows " \
271
+ --file-version " $version_windows " \
272
+ --manifest " cli" \
273
+ --file-description " $file_description " \
274
+ --product-name " Coder" \
275
+ --copyright " Copyright $( date +%Y) Coder Technologies Inc." \
276
+ --original-filename " coder.exe" \
277
+ --icon ../../scripts/win-installer/coder.ico
278
+ popd
279
+
280
+ if [[ ! -f " $expected_rsrc_file " ]]; then
281
+ error " Failed to generate $expected_rsrc_file "
282
+ fi
283
+ fi
284
+
285
+ set +e
207
286
GOEXPERIMENT=" $goexp " CGO_ENABLED=" $cgo " GOOS=" $os " GOARCH=" $arch " GOARM=" $arm_version " \
208
287
go build \
209
288
" ${build_args[@]} " \
210
289
" $cmd_path " 1>&2
290
+ exit_code=$?
291
+ set -e
292
+
293
+ # Clean up the resources file if it was generated.
294
+ if [[ " $windows_resources " == 1 ]] && [[ " $os " == " windows" ]]; then
295
+ rm " $expected_rsrc_file "
296
+ fi
297
+
298
+ if [[ " $exit_code " != 0 ]]; then
299
+ exit " $exit_code "
300
+ fi
301
+
302
+ # If we did embed resources, verify that they were included.
303
+ if [[ " $windows_resources " == 1 ]] && [[ " $os " == " windows" ]]; then
304
+ winres_dir=$( mktemp -d)
305
+ if ! go-winres extract --dir " $winres_dir " " $output_path " 1>&2 ; then
306
+ rm -rf " $winres_dir "
307
+ error " Compiled binary does not contain embedded resources"
308
+ fi
309
+ # If go-winres didn't return an error, it means it did find embedded
310
+ # resources.
311
+ rm -rf " $winres_dir "
312
+ fi
211
313
212
314
if [[ " $sign_darwin " == 1 ]] && [[ " $os " == " darwin" ]]; then
213
315
execrelative ./sign_darwin.sh " $output_path " " $bin_ident " 1>&2
0 commit comments