blob: 5e40436bbe2bc1b205840906c21a246dc0f89c0e [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001#!/bin/sh
2
3nl="
4"
5
6log() {
7 # shellcheck disable=SC2039
8 local IFS=" "
9 printf '%s\n' "$*"
10}
11
12log_error() {
13 # shellcheck disable=SC2039
14 local IFS=" "
15 printf 'Error: %s\n' "$*" >&2
16}
17
18link_contents() {
19 # shellcheck disable=SC2039
20 local src="$1" dest="$2" IFS="$nl" dirs dir base
21
22 if [ -n "$(find "$src" -mindepth 1 -maxdepth 1 -name "*.go" -not -type d)" ]; then
23 log_error "$src is already a Go library"
24 return 1
25 fi
26
27 dirs="$(find "$src" -mindepth 1 -maxdepth 1 -type d)"
28 for dir in $dirs; do
29 base="${dir##*/}"
30 if [ -d "$dest/$base" ]; then
31 case "$dir" in
32 *$GO_BUILD_DEPENDS_SRC/$GO_PKG)
33 log "$GO_PKG is already installed. Please check for circular dependencies."
34 ;;
35 *)
36 link_contents "$src/$base" "$dest/$base"
37 ;;
38 esac
39 else
40 log "...${src#$GO_BUILD_DEPENDS_SRC}/$base"
41 ln -sf "$src/$base" "$dest/$base"
42 fi
43 done
44
45 return 0
46}
47
48configure() {
49 # shellcheck disable=SC2039
50 local files code testdata gomod pattern extra IFS file dest
51
52 cd "$BUILD_DIR" || return 1
53
54 files="$(find ./ -path "*/.*" -prune -o -not -type d -print)"
55
56 if [ "$GO_INSTALL_ALL" != 1 ]; then
57 code="$(printf '%s\n' "$files" | grep '\.\(c\|cc\|cpp\|go\|h\|hh\|hpp\|proto\|s\)$')"
58 testdata="$(printf '%s\n' "$files" | grep '/testdata/')"
59 gomod="$(printf '%s\n' "$files" | grep '/go\.\(mod\|sum\)$')"
60
61 for pattern in $GO_INSTALL_EXTRA; do
62 extra="$(printf '%s\n' "$extra"; printf '%s\n' "$files" | grep -e "$pattern")"
63 done
64
65 files="$(printf '%s\n%s\n%s\n%s\n' "$code" "$testdata" "$gomod" "$extra" | grep -v '^[[:space:]]*$' | sort -u)"
66 fi
67
68 IFS="$nl"
69
70 log "Copying files from $BUILD_DIR into $GO_BUILD_DIR/src/$GO_PKG"
71 mkdir -p "$GO_BUILD_DIR/src"
72 for file in $files; do
73 log "${file#./}"
74 dest="$GO_BUILD_DIR/src/$GO_PKG/${file#./}"
75 mkdir -p "${dest%/*}"
76 cp -fpR "$file" "$dest"
77 done
78 log
79
80 if [ "$GO_SOURCE_ONLY" != 1 ]; then
81 if [ -d "$GO_BUILD_DEPENDS_SRC" ]; then
82 log "Symlinking directories from $GO_BUILD_DEPENDS_SRC into $GO_BUILD_DIR/src"
83 link_contents "$GO_BUILD_DEPENDS_SRC" "$GO_BUILD_DIR/src"
84 else
85 log "$GO_BUILD_DEPENDS_SRC does not exist, skipping symlinks"
86 fi
87 else
88 log "Not building binaries, skipping symlinks"
89 fi
90 log
91
92 return 0
93}
94
95build() {
96 # shellcheck disable=SC2039
97 local modargs pattern targets retval
98
99 cd "$GO_BUILD_DIR" || return 1
100
101 if [ -f "$BUILD_DIR/go.mod" ] ; then
102 mkdir -p "$GO_MOD_CACHE_DIR"
103 modargs="$GO_MOD_ARGS"
104 fi
105
106 log "Finding targets"
107 # shellcheck disable=SC2086
108 targets="$(go list $modargs $GO_BUILD_PKG)"
109 for pattern in $GO_EXCLUDES; do
110 targets="$(printf '%s\n' "$targets" | grep -v "$pattern")"
111 done
112 log
113
114 if [ "$GO_GO_GENERATE" = 1 ]; then
115 log "Calling go generate"
116 # shellcheck disable=SC2086
117 GOOS='' GOARCH='' GO386='' GOARM='' GOMIPS='' GOMIPS64='' \
118 go generate -v $targets
119 log
120 fi
121
122 if [ "$GO_SOURCE_ONLY" = 1 ]; then
123 return 0
124 fi
125
126 log "Building targets"
127 mkdir -p "$GO_BUILD_DIR/bin" "$GO_BUILD_CACHE_DIR"
128 # shellcheck disable=SC2086
129 go install $modargs "$@" $targets
130 retval="$?"
131 log
132
133 if [ "$retval" -eq 0 ] && [ -z "$(find "$GO_BUILD_BIN_DIR" -maxdepth 0 -type d -not -empty 2>/dev/null)" ]; then
134 log_error "No binaries were built"
135 retval=1
136 fi
137
138 if [ "$retval" -ne 0 ]; then
139 cache_cleanup
140 fi
141
142 return "$retval"
143}
144
145install_bin() {
146 # shellcheck disable=SC2039
147 local dest="$1"
148 install -d -m0755 "$dest/$GO_INSTALL_BIN_PATH"
149 install -m0755 "$GO_BUILD_BIN_DIR"/* "$dest/$GO_INSTALL_BIN_PATH/"
150}
151
152install_src() {
153 # shellcheck disable=SC2039
154 local dest="$1" dir="${GO_PKG%/*}"
155 install -d -m0755 "$dest/$GO_BUILD_DEPENDS_PATH/src/$dir"
156 cp -fpR "$GO_BUILD_DIR/src/$GO_PKG" "$dest/$GO_BUILD_DEPENDS_PATH/src/$dir/"
157}
158
159cache_cleanup() {
160 if ! [ -d "$GO_MOD_CACHE_DIR" ]; then
161 return 0
162 fi
163
164 # in case go is called without -modcacherw
165 find "$GO_MOD_CACHE_DIR" -type d -not -perm -u+w -exec chmod u+w '{}' +
166
167 if [ -n "$CONFIG_GOLANG_MOD_CACHE_WORLD_READABLE" ]; then
168 find "$GO_MOD_CACHE_DIR" -type d -not -perm -go+rx -exec chmod go+rx '{}' +
169 find "$GO_MOD_CACHE_DIR" -not -type d -not -perm -go+r -exec chmod go+r '{}' +
170 fi
171
172 return 0
173}
174
175
176if [ "$#" -lt 1 ]; then
177 log_error "Missing command"
178 exit 1
179fi
180
181command="$1"
182shift 1
183
184case "$command" in
185 configure)
186 configure
187 ;;
188 build)
189 build "$@"
190 ;;
191 install_bin)
192 install_bin "$@"
193 ;;
194 install_src)
195 install_src "$@"
196 ;;
197 cache_cleanup)
198 cache_cleanup
199 ;;
200 *)
201 log_error "Invalid command \"$command\""
202 exit 1
203 ;;
204esac