b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | #!/bin/sh |
| 2 | |
| 3 | nl=" |
| 4 | " |
| 5 | |
| 6 | log() { |
| 7 | # shellcheck disable=SC2039 |
| 8 | local IFS=" " |
| 9 | printf '%s\n' "$*" |
| 10 | } |
| 11 | |
| 12 | log_error() { |
| 13 | # shellcheck disable=SC2039 |
| 14 | local IFS=" " |
| 15 | printf 'Error: %s\n' "$*" >&2 |
| 16 | } |
| 17 | |
| 18 | link_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 | |
| 48 | configure() { |
| 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 | |
| 95 | build() { |
| 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 | |
| 145 | install_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 | |
| 152 | install_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 | |
| 159 | cache_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 | |
| 176 | if [ "$#" -lt 1 ]; then |
| 177 | log_error "Missing command" |
| 178 | exit 1 |
| 179 | fi |
| 180 | |
| 181 | command="$1" |
| 182 | shift 1 |
| 183 | |
| 184 | case "$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 | ;; |
| 204 | esac |