ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/external/subpack/lang/golang/golang-build.sh b/external/subpack/lang/golang/golang-build.sh
new file mode 100644
index 0000000..5e40436
--- /dev/null
+++ b/external/subpack/lang/golang/golang-build.sh
@@ -0,0 +1,204 @@
+#!/bin/sh
+
+nl="
+"
+
+log() {
+	# shellcheck disable=SC2039
+	local IFS=" "
+	printf '%s\n' "$*"
+}
+
+log_error() {
+	# shellcheck disable=SC2039
+	local IFS=" "
+	printf 'Error: %s\n' "$*" >&2
+}
+
+link_contents() {
+	# shellcheck disable=SC2039
+	local src="$1" dest="$2" IFS="$nl" dirs dir base
+
+	if [ -n "$(find "$src" -mindepth 1 -maxdepth 1 -name "*.go" -not -type d)" ]; then
+		log_error "$src is already a Go library"
+		return 1
+	fi
+
+	dirs="$(find "$src" -mindepth 1 -maxdepth 1 -type d)"
+	for dir in $dirs; do
+		base="${dir##*/}"
+		if [ -d "$dest/$base" ]; then
+			case "$dir" in
+			*$GO_BUILD_DEPENDS_SRC/$GO_PKG)
+				log "$GO_PKG is already installed. Please check for circular dependencies."
+				;;
+			*)
+				link_contents "$src/$base" "$dest/$base"
+				;;
+			esac
+		else
+			log "...${src#$GO_BUILD_DEPENDS_SRC}/$base"
+			ln -sf "$src/$base" "$dest/$base"
+		fi
+	done
+
+	return 0
+}
+
+configure() {
+	# shellcheck disable=SC2039
+	local files code testdata gomod pattern extra IFS file dest
+
+	cd "$BUILD_DIR" || return 1
+
+	files="$(find ./ -path "*/.*" -prune -o -not -type d -print)"
+
+	if [ "$GO_INSTALL_ALL" != 1 ]; then
+		code="$(printf '%s\n' "$files" | grep '\.\(c\|cc\|cpp\|go\|h\|hh\|hpp\|proto\|s\)$')"
+		testdata="$(printf '%s\n' "$files" | grep '/testdata/')"
+		gomod="$(printf '%s\n' "$files" | grep '/go\.\(mod\|sum\)$')"
+
+		for pattern in $GO_INSTALL_EXTRA; do
+			extra="$(printf '%s\n' "$extra"; printf '%s\n' "$files" | grep -e "$pattern")"
+		done
+
+		files="$(printf '%s\n%s\n%s\n%s\n' "$code" "$testdata" "$gomod" "$extra" | grep -v '^[[:space:]]*$' | sort -u)"
+	fi
+
+	IFS="$nl"
+
+	log "Copying files from $BUILD_DIR into $GO_BUILD_DIR/src/$GO_PKG"
+	mkdir -p "$GO_BUILD_DIR/src"
+	for file in $files; do
+		log "${file#./}"
+		dest="$GO_BUILD_DIR/src/$GO_PKG/${file#./}"
+		mkdir -p "${dest%/*}"
+		cp -fpR "$file" "$dest"
+	done
+	log
+
+	if [ "$GO_SOURCE_ONLY" != 1 ]; then
+		if [ -d "$GO_BUILD_DEPENDS_SRC" ]; then
+			log "Symlinking directories from $GO_BUILD_DEPENDS_SRC into $GO_BUILD_DIR/src"
+			link_contents "$GO_BUILD_DEPENDS_SRC" "$GO_BUILD_DIR/src"
+		else
+			log "$GO_BUILD_DEPENDS_SRC does not exist, skipping symlinks"
+		fi
+	else
+		log "Not building binaries, skipping symlinks"
+	fi
+	log
+
+	return 0
+}
+
+build() {
+	# shellcheck disable=SC2039
+	local modargs pattern targets retval
+
+	cd "$GO_BUILD_DIR" || return 1
+
+	if [ -f "$BUILD_DIR/go.mod" ] ; then
+		mkdir -p "$GO_MOD_CACHE_DIR"
+		modargs="$GO_MOD_ARGS"
+	fi
+
+	log "Finding targets"
+	# shellcheck disable=SC2086
+	targets="$(go list $modargs $GO_BUILD_PKG)"
+	for pattern in $GO_EXCLUDES; do
+		targets="$(printf '%s\n' "$targets" | grep -v "$pattern")"
+	done
+	log
+
+	if [ "$GO_GO_GENERATE" = 1 ]; then
+		log "Calling go generate"
+		# shellcheck disable=SC2086
+		GOOS='' GOARCH='' GO386='' GOARM='' GOMIPS='' GOMIPS64='' \
+		go generate -v $targets
+		log
+	fi
+
+	if [ "$GO_SOURCE_ONLY" = 1 ]; then
+		return 0
+	fi
+
+	log "Building targets"
+	mkdir -p "$GO_BUILD_DIR/bin" "$GO_BUILD_CACHE_DIR"
+	# shellcheck disable=SC2086
+	go install $modargs "$@" $targets
+	retval="$?"
+	log
+
+	if [ "$retval" -eq 0 ] && [ -z "$(find "$GO_BUILD_BIN_DIR" -maxdepth 0 -type d -not -empty 2>/dev/null)" ]; then
+		log_error "No binaries were built"
+		retval=1
+	fi
+
+	if [ "$retval" -ne 0 ]; then
+		cache_cleanup
+	fi
+
+	return "$retval"
+}
+
+install_bin() {
+	# shellcheck disable=SC2039
+	local dest="$1"
+	install -d -m0755 "$dest/$GO_INSTALL_BIN_PATH"
+	install -m0755 "$GO_BUILD_BIN_DIR"/* "$dest/$GO_INSTALL_BIN_PATH/"
+}
+
+install_src() {
+	# shellcheck disable=SC2039
+	local dest="$1" dir="${GO_PKG%/*}"
+	install -d -m0755 "$dest/$GO_BUILD_DEPENDS_PATH/src/$dir"
+	cp -fpR "$GO_BUILD_DIR/src/$GO_PKG" "$dest/$GO_BUILD_DEPENDS_PATH/src/$dir/"
+}
+
+cache_cleanup() {
+	if ! [ -d "$GO_MOD_CACHE_DIR" ]; then
+		return 0
+	fi
+
+	# in case go is called without -modcacherw
+	find "$GO_MOD_CACHE_DIR" -type d -not -perm -u+w -exec chmod u+w '{}' +
+
+	if [ -n "$CONFIG_GOLANG_MOD_CACHE_WORLD_READABLE" ]; then
+		find "$GO_MOD_CACHE_DIR"      -type d -not -perm -go+rx -exec chmod go+rx '{}' +
+		find "$GO_MOD_CACHE_DIR" -not -type d -not -perm -go+r  -exec chmod go+r  '{}' +
+	fi
+
+	return 0
+}
+
+
+if [ "$#" -lt 1 ]; then
+	log_error "Missing command"
+	exit 1
+fi
+
+command="$1"
+shift 1
+
+case "$command" in
+	configure)
+		configure
+		;;
+	build)
+		build "$@"
+		;;
+	install_bin)
+		install_bin "$@"
+		;;
+	install_src)
+		install_src "$@"
+		;;
+	cache_cleanup)
+		cache_cleanup
+		;;
+	*)
+		log_error "Invalid command \"$command\""
+		exit 1
+		;;
+esac