golang: Move package scripts into golang-build.sh
authorJeffery To <redacted>
Wed, 26 Aug 2020 08:17:05 +0000 (16:17 +0800)
committerJeffery To <redacted>
Tue, 6 Oct 2020 08:34:40 +0000 (16:34 +0800)
This also adds GO_PKG_INSTALL_BIN_PATH which determines the path where
binaries are installed by GoPackage/Package/Install/Bin (this was
previously hard-coded to /usr/bin).

Signed-off-by: Jeffery To <redacted>
lang/golang/golang-build.sh
lang/golang/golang-package.mk
lang/golang/golang-values.mk

index d39949dca9fa60f548078c91624450618c4c7316..5e40436bbe2bc1b205840906c21a246dc0f89c0e 100644 (file)
@@ -1,5 +1,8 @@
 #!/bin/sh
 
+nl="
+"
+
 log() {
        # shellcheck disable=SC2039
        local IFS=" "
@@ -12,6 +15,147 @@ log_error() {
        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
@@ -38,6 +182,18 @@ command="$1"
 shift 1
 
 case "$command" in
+       configure)
+               configure
+               ;;
+       build)
+               build "$@"
+               ;;
+       install_bin)
+               install_bin "$@"
+               ;;
+       install_src)
+               install_src "$@"
+               ;;
        cache_cleanup)
                cache_cleanup
                ;;
index b3d01857f481b1358c53115bd24d0b5f657b900c..8c62e6399a5075f1e40a2850ee352cef0672b1ea 100644 (file)
@@ -111,22 +111,29 @@ include $(GO_INCLUDE_DIR)/golang-values.mk
 #   parameter to the -tags option for 'go install'.
 #
 #   e.g. GO_PKG_TAGS:=release,noupgrade
+#
+#
+# GO_PKG_INSTALL_BIN_PATH - target directory path, default /usr/bin
+#
+#   Directory path under "dest_dir" where binaries will be installed by
+#   '$(call GoPackage/Package/Install/Bin,dest_dir)'.
+#
+#   e.g. GO_PKG_INSTALL_BIN_PATH:=/sbin
 
 # Credit for this package build process (GoPackage/Build/Configure and
 # GoPackage/Build/Compile) belong to Debian's dh-golang completely.
 # https://salsa.debian.org/go-team/packages/dh-golang
 
 
-# for building packages, not user code
-GO_PKG_PATH:=/usr/share/gocode
-
 GO_PKG_BUILD_PKG?=$(strip $(GO_PKG))/...
+GO_PKG_INSTALL_BIN_PATH?=/usr/bin
 
 GO_PKG_WORK_DIR_NAME:=.go_work
 GO_PKG_BUILD_DIR=$(PKG_BUILD_DIR)/$(GO_PKG_WORK_DIR_NAME)/build
 GO_PKG_BUILD_BIN_DIR=$(GO_PKG_BUILD_DIR)/bin$(if $(GO_HOST_TARGET_DIFFERENT),/$(GO_OS_ARCH))
 
-GO_PKG_BUILD_DEPENDS_SRC=$(STAGING_DIR)$(GO_PKG_PATH)/src
+GO_PKG_BUILD_DEPENDS_PATH:=/usr/share/gocode
+GO_PKG_BUILD_DEPENDS_SRC=$(STAGING_DIR)$(GO_PKG_BUILD_DEPENDS_PATH)/src
 
 ifdef CONFIG_PKG_ASLR_PIE_ALL
   ifeq ($(strip $(PKG_ASLR_PIE)),1)
@@ -164,6 +171,21 @@ define GoPackage/GoSubMenu
   CATEGORY:=Languages
 endef
 
+GO_PKG_BUILD_CONFIG_VARS= \
+       GO_PKG="$(strip $(GO_PKG))" \
+       GO_INSTALL_EXTRA="$(strip $(GO_PKG_INSTALL_EXTRA))" \
+       GO_INSTALL_ALL="$(strip $(GO_PKG_INSTALL_ALL))" \
+       GO_SOURCE_ONLY="$(strip $(GO_PKG_SOURCE_ONLY))" \
+       GO_BUILD_PKG="$(strip $(GO_PKG_BUILD_PKG))" \
+       GO_EXCLUDES="$(strip $(GO_PKG_EXCLUDES))" \
+       GO_GO_GENERATE="$(strip $(GO_PKG_GO_GENERATE))" \
+       GO_INSTALL_BIN_PATH="$(strip $(GO_PKG_INSTALL_BIN_PATH))" \
+       BUILD_DIR="$(PKG_BUILD_DIR)" \
+       GO_BUILD_DIR="$(GO_PKG_BUILD_DIR)" \
+       GO_BUILD_BIN_DIR="$(GO_PKG_BUILD_BIN_DIR)" \
+       GO_BUILD_DEPENDS_PATH="$(GO_PKG_BUILD_DEPENDS_PATH)" \
+       GO_BUILD_DEPENDS_SRC="$(GO_PKG_BUILD_DEPENDS_SRC)"
+
 GO_PKG_TARGET_VARS= \
        GOOS="$(GO_OS)" \
        GOARCH="$(GO_ARCH)" \
@@ -185,12 +207,10 @@ GO_PKG_BUILD_VARS= \
        GOMODCACHE="$(GO_MOD_CACHE_DIR)" \
        GOENV=off
 
-GO_PKG_DEFAULT_VARS= \
+GO_PKG_VARS= \
        $(GO_PKG_TARGET_VARS) \
        $(GO_PKG_BUILD_VARS)
 
-GO_PKG_VARS=$(GO_PKG_DEFAULT_VARS)
-
 GO_PKG_DEFAULT_LDFLAGS= \
        -buildid '$(SOURCE_DATE_EPOCH)' \
        -linkmode external \
@@ -212,127 +232,18 @@ GO_PKG_INSTALL_ARGS= \
        $(if $(GO_PKG_CUSTOM_LDFLAGS),-ldflags "$(GO_PKG_CUSTOM_LDFLAGS) $(GO_PKG_DEFAULT_LDFLAGS)") \
        $(if $(GO_PKG_TAGS),-tags "$(GO_PKG_TAGS)")
 
-# false if directory does not exist
-GoPackage/is_dir_not_empty=$$$$($(FIND) "$(1)" -maxdepth 0 -type d \! -empty 2>/dev/null)
-
-GoPackage/has_binaries=$(call GoPackage/is_dir_not_empty,$(GO_PKG_BUILD_BIN_DIR))
-
 define GoPackage/Build/Configure
-       ( \
-               cd "$(PKG_BUILD_DIR)" ; \
-               mkdir -p \
-                       "$(GO_PKG_BUILD_DIR)/bin" "$(GO_PKG_BUILD_DIR)/src" \
-                       "$(GO_BUILD_CACHE_DIR)" "$(GO_MOD_CACHE_DIR)" ; \
-               \
-               files="$$$$($(FIND) ./ \
-                       -type d -a \( -path "./.git" -o -path "./$(GO_PKG_WORK_DIR_NAME)" \) -prune -o \
-                       \! -type d -print | \
-                       sed 's|^\./||')" ; \
-               \
-               if [ "$(strip $(GO_PKG_INSTALL_ALL))" != 1 ]; then \
-                       code="$$$$(echo "$$$$files" | grep '\.\(c\|cc\|cpp\|go\|h\|hh\|hpp\|proto\|s\)$$$$')" ; \
-                       testdata="$$$$(echo "$$$$files" | grep '\(^\|/\)testdata/')" ; \
-                       gomod="$$$$(echo "$$$$files" | grep '\(^\|/\)go\.\(mod\|sum\)$$$$')" ; \
-                       \
-                       for pattern in $(GO_PKG_INSTALL_EXTRA); do \
-                               extra="$$$$(echo "$$$$extra"; echo "$$$$files" | grep "$$$$pattern")" ; \
-                       done ; \
-                       \
-                       files="$$$$(echo "$$$$code"; echo "$$$$testdata"; echo "$$$$gomod"; echo "$$$$extra")" ; \
-                       files="$$$$(echo "$$$$files" | grep -v '^[[:space:]]*$$$$' | sort -u)" ; \
-               fi ; \
-               \
-               IFS=$$$$'\n' ; \
-               \
-               echo "Copying files from $(PKG_BUILD_DIR) into $(GO_PKG_BUILD_DIR)/src/$(strip $(GO_PKG))" ; \
-               for file in $$$$files; do \
-                       echo "$$$$file" ; \
-                       dest="$(GO_PKG_BUILD_DIR)/src/$(strip $(GO_PKG))/$$$$file" ; \
-                       mkdir -p "$$$$(dirname "$$$$dest")" ; \
-                       $(CP) "$$$$file" "$$$$dest" ; \
-               done ; \
-               echo ; \
-               \
-               link_contents() { \
-                       local src="$$$$1" ; \
-                       local dest="$$$$2" ; \
-                       local dirs dir base ; \
-                       \
-                       if [ -n "$$$$($(FIND) "$$$$src" -mindepth 1 -maxdepth 1 -name "*.go" \! -type d)" ]; then \
-                               echo "$$$$src is already a Go library" ; \
-                               return 1 ; \
-                       fi ; \
-                       \
-                       dirs="$$$$($(FIND) "$$$$src" -mindepth 1 -maxdepth 1 -type d)" ; \
-                       for dir in $$$$dirs; do \
-                               base="$$$$(basename "$$$$dir")" ; \
-                               if [ -d "$$$$dest/$$$$base" ]; then \
-                                       case "$$$$dir" in \
-                                       *$(GO_PKG_PATH)/src/$(strip $(GO_PKG))) \
-                                               echo "$(strip $(GO_PKG)) is already installed. Please check for circular dependencies." ;; \
-                                       *) \
-                                               link_contents "$$$$src/$$$$base" "$$$$dest/$$$$base" ;; \
-                                       esac ; \
-                               else \
-                                       echo "...$$$${src#$(GO_PKG_BUILD_DEPENDS_SRC)}/$$$$base" ; \
-                                       $(LN) "$$$$src/$$$$base" "$$$$dest/$$$$base" ; \
-                               fi ; \
-                       done ; \
-               } ; \
-               \
-               if [ "$(strip $(GO_PKG_SOURCE_ONLY))" != 1 ]; then \
-                       if [ -d "$(GO_PKG_BUILD_DEPENDS_SRC)" ]; then \
-                               echo "Symlinking directories from $(GO_PKG_BUILD_DEPENDS_SRC) into $(GO_PKG_BUILD_DIR)/src" ; \
-                               link_contents "$(GO_PKG_BUILD_DEPENDS_SRC)" "$(GO_PKG_BUILD_DIR)/src" ; \
-                       else \
-                               echo "$(GO_PKG_BUILD_DEPENDS_SRC) does not exist, skipping symlinks" ; \
-                       fi ; \
-               else \
-                       echo "Not building binaries, skipping symlinks" ; \
-               fi ; \
-               echo ; \
-       )
+       $(GO_GENERAL_BUILD_CONFIG_VARS) \
+       $(GO_PKG_BUILD_CONFIG_VARS) \
+       $(SHELL) $(GO_INCLUDE_DIR)/golang-build.sh configure
 endef
 
 # $(1) additional arguments for go command line (optional)
 define GoPackage/Build/Compile
-       ( \
-               cd "$(GO_PKG_BUILD_DIR)" ; \
-               export $(GO_PKG_VARS) ; \
-               if [ -f "$(PKG_BUILD_DIR)/go.mod" ] ; then \
-                       modargs="$(GO_MOD_ARGS)" ; \
-               fi ; \
-               \
-               echo "Finding targets" ; \
-               targets="$$$$(go list $$$$modargs $(GO_PKG_BUILD_PKG))" ; \
-               for pattern in $(GO_PKG_EXCLUDES); do \
-                       targets="$$$$(echo "$$$$targets" | grep -v "$$$$pattern")" ; \
-               done ; \
-               echo ; \
-               \
-               if [ "$(strip $(GO_PKG_GO_GENERATE))" = 1 ]; then \
-                       echo "Calling go generate" ; \
-                       go generate -v $(1) $$$$targets ; \
-                       echo ; \
-               fi ; \
-               \
-               if [ "$(strip $(GO_PKG_SOURCE_ONLY))" != 1 ]; then \
-                       echo "Building targets" ; \
-                       go install $(GO_PKG_INSTALL_ARGS) $$$$modargs $(1) $$$$targets ; \
-                       retval="$$$$?" ; \
-                       echo ; \
-                       \
-                       if [ "$$$$retval" -eq 0 ] && [ -z "$(call GoPackage/has_binaries)" ]; then \
-                               echo "No binaries were generated, consider adding GO_PKG_SOURCE_ONLY:=1 to Makefile" ; \
-                               echo ; \
-                       fi ; \
-                       \
-                       if [ "$$$$retval" -ne 0 ]; then \
-                               $(call Go/CacheCleanup) ; \
-                       fi ; \
-               fi ; \
-               exit "$$$$retval" ; \
-       )
+       $(GO_GENERAL_BUILD_CONFIG_VARS) \
+       $(GO_PKG_BUILD_CONFIG_VARS) \
+       $(GO_PKG_VARS) \
+       $(SHELL) $(GO_INCLUDE_DIR)/golang-build.sh build $(GO_PKG_INSTALL_ARGS) $(1)
 endef
 
 define GoPackage/Build/InstallDev
@@ -340,20 +251,21 @@ define GoPackage/Build/InstallDev
 endef
 
 define GoPackage/Package/Install/Bin
-       if [ -n "$(call GoPackage/has_binaries)" ]; then \
-               $(INSTALL_DIR) "$(1)/usr/bin" ; \
-               $(INSTALL_BIN) "$(GO_PKG_BUILD_BIN_DIR)"/* "$(1)/usr/bin/" ; \
-       fi
+       $(GO_GENERAL_BUILD_CONFIG_VARS) \
+       $(GO_PKG_BUILD_CONFIG_VARS) \
+       $(SHELL) $(GO_INCLUDE_DIR)/golang-build.sh install_bin "$(1)"
 endef
 
 define GoPackage/Package/Install/Src
-       dir="$$$$(dirname "$(GO_PKG)")" ; \
-       $(INSTALL_DIR) "$(1)$(GO_PKG_PATH)/src/$$$$dir" ; \
-       $(CP) "$(GO_PKG_BUILD_DIR)/src/$(strip $(GO_PKG))" "$(1)$(GO_PKG_PATH)/src/$$$$dir/"
+       $(GO_GENERAL_BUILD_CONFIG_VARS) \
+       $(GO_PKG_BUILD_CONFIG_VARS) \
+       $(SHELL) $(GO_INCLUDE_DIR)/golang-build.sh install_src "$(1)"
 endef
 
 define GoPackage/Package/Install
-       $(call GoPackage/Package/Install/Bin,$(1))
+       $(if $(filter $(GO_PKG_SOURCE_ONLY),1),, \
+               $(call GoPackage/Package/Install/Bin,$(1)) \
+       )
        $(call GoPackage/Package/Install/Src,$(1))
 endef
 
@@ -385,7 +297,11 @@ endef
 
 
 # Deprecated variables - these will be removed after the next OpenWrt release
+GO_PKG_PATH=$(GO_PKG_BUILD_DEPENDS_PATH)
 GO_PKG_WORK_DIR=$(PKG_BUILD_DIR)/$(GO_PKG_WORK_DIR_NAME)
 GO_PKG_CACHE_DIR=$(GO_BUILD_CACHE_DIR)
+GO_PKG_DEFAULT_VARS=$(GO_PKG_VARS)
 GoPackage/Environment=$(GO_PKG_VARS)
+GoPackage/is_dir_not_empty=$$$$($(FIND) "$(1)" -maxdepth 0 -type d \! -empty 2>/dev/null)
+GoPackage/has_binaries=$(call GoPackage/is_dir_not_empty,$(GO_PKG_BUILD_BIN_DIR))
 # End of deprecated variables
index 596270caf4dc0109934996752351478c0d9d203b..7429ae0de81e6c0ce137105d2a375ef371bb7830 100644 (file)
@@ -231,7 +231,9 @@ GO_MOD_ARGS= \
 
 GO_GENERAL_BUILD_CONFIG_VARS= \
        CONFIG_GOLANG_MOD_CACHE_WORLD_READABLE="$(CONFIG_GOLANG_MOD_CACHE_WORLD_READABLE)" \
-       GO_MOD_CACHE_DIR="$(GO_MOD_CACHE_DIR)"
+       GO_BUILD_CACHE_DIR="$(GO_BUILD_CACHE_DIR)" \
+       GO_MOD_CACHE_DIR="$(GO_MOD_CACHE_DIR)" \
+       GO_MOD_ARGS="$(GO_MOD_ARGS)"
 
 define Go/CacheCleanup
        $(GENERAL_BUILD_CONFIG_VARS) \
git clone https://git.99rst.org/PROJECT