You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

384 lines
11 KiB

  1. #
  2. # Copyright (C) 2018-2020 Jeffery To
  3. #
  4. # This is free software, licensed under the GNU General Public License v2.
  5. # See /LICENSE for more information.
  6. #
  7. ifeq ($(origin GO_INCLUDE_DIR),undefined)
  8. GO_INCLUDE_DIR:=$(dir $(lastword $(MAKEFILE_LIST)))
  9. endif
  10. include $(GO_INCLUDE_DIR)/golang-values.mk
  11. # Variables (all optional, except GO_PKG) to be set in package
  12. # Makefiles:
  13. #
  14. # GO_PKG (required) - name of Go package
  15. #
  16. # Go name of the package.
  17. #
  18. # e.g. GO_PKG:=golang.org/x/text
  19. #
  20. #
  21. # GO_PKG_INSTALL_EXTRA - list of regular expressions, default empty
  22. #
  23. # Additional files/directories to install. By default, only these
  24. # files are installed:
  25. #
  26. # * Files with one of these extensions:
  27. # .go, .c, .cc, .cpp, .h, .hh, .hpp, .proto, .s
  28. #
  29. # * Files in any 'testdata' directory
  30. #
  31. # * go.mod and go.sum, in any directory
  32. #
  33. # e.g. GO_PKG_INSTALL_EXTRA:=example.toml marshal_test.toml
  34. #
  35. #
  36. # GO_PKG_INSTALL_ALL - boolean (0 or 1), default false
  37. #
  38. # If true, install all files regardless of extension or directory.
  39. #
  40. # e.g. GO_PKG_INSTALL_ALL:=1
  41. #
  42. #
  43. # GO_PKG_SOURCE_ONLY - boolean (0 or 1), default false
  44. #
  45. # If true, 'go install' will not be called. If the package does not
  46. # (or should not) build any binaries, then specifying this option will
  47. # save build time.
  48. #
  49. # e.g. GO_PKG_SOURCE_ONLY:=1
  50. #
  51. #
  52. # GO_PKG_BUILD_PKG - list of build targets, default GO_PKG/...
  53. #
  54. # Build targets for compiling this Go package, i.e. arguments passed
  55. # to 'go install'.
  56. #
  57. # e.g. GO_PKG_BUILD_PKG:=github.com/debian/ratt/cmd/...
  58. #
  59. #
  60. # GO_PKG_EXCLUDES - list of regular expressions, default empty
  61. #
  62. # Patterns to exclude from the build targets expanded from
  63. # GO_PKG_BUILD_PKG.
  64. #
  65. # e.g. GO_PKG_EXCLUDES:=examples/
  66. #
  67. #
  68. # GO_PKG_GO_GENERATE - boolean (0 or 1), default false
  69. #
  70. # If true, 'go generate' will be called on all build targets (as
  71. # determined by GO_PKG_BUILD_PKG and GO_PKG_EXCLUDES). This is usually
  72. # not necessary.
  73. #
  74. # e.g. GO_PKG_GO_GENERATE:=1
  75. #
  76. #
  77. # GO_PKG_GCFLAGS - list of options, default empty
  78. #
  79. # Additional go tool compile options to use when building targets.
  80. #
  81. # e.g. GO_PKG_GCFLAGS:=-N -l
  82. #
  83. #
  84. # GO_PKG_LDFLAGS - list of options, default empty
  85. #
  86. # Additional go tool link options to use when building targets.
  87. #
  88. # Note that the OpenWrt build system has an option to strip binaries
  89. # (enabled by default), so -s (Omit the symbol table and debug
  90. # information) and -w (Omit the DWARF symbol table) flags are not
  91. # necessary.
  92. #
  93. # e.g. GO_PKG_LDFLAGS:=-r dir1:dir2 -u
  94. #
  95. #
  96. # GO_PKG_LDFLAGS_X - list of string variable definitions, default empty
  97. #
  98. # Each definition will be passed as the parameter to the -X go tool
  99. # link option, i.e. -ldflags "-X importpath.name=value".
  100. #
  101. # e.g. GO_PKG_LDFLAGS_X:=main.Version=$(PKG_VERSION) main.BuildStamp=$(SOURCE_DATE_EPOCH)
  102. #
  103. #
  104. # GO_PKG_TAGS - list of build tags, default empty
  105. #
  106. # Build tags to consider satisfied during the build, passed as the
  107. # parameter to the -tags option for 'go install'.
  108. #
  109. # e.g. GO_PKG_TAGS:=release,noupgrade
  110. # Credit for this package build process (GoPackage/Build/Configure and
  111. # GoPackage/Build/Compile) belong to Debian's dh-golang completely.
  112. # https://salsa.debian.org/go-team/packages/dh-golang
  113. # for building packages, not user code
  114. GO_PKG_PATH:=/usr/share/gocode
  115. GO_PKG_BUILD_PKG?=$(strip $(GO_PKG))/...
  116. GO_PKG_WORK_DIR_NAME:=.go_work
  117. GO_PKG_WORK_DIR=$(PKG_BUILD_DIR)/$(GO_PKG_WORK_DIR_NAME)
  118. GO_PKG_BUILD_DIR=$(GO_PKG_WORK_DIR)/build
  119. GO_PKG_CACHE_DIR=$(GO_PKG_WORK_DIR)/cache
  120. GO_PKG_BUILD_BIN_DIR=$(GO_PKG_BUILD_DIR)/bin$(if $(GO_HOST_TARGET_DIFFERENT),/$(GO_OS_ARCH))
  121. GO_PKG_BUILD_DEPENDS_SRC=$(STAGING_DIR)$(GO_PKG_PATH)/src
  122. ifdef CONFIG_PKG_ASLR_PIE_ALL
  123. ifeq ($(strip $(PKG_ASLR_PIE)),1)
  124. ifeq ($(GO_TARGET_PIE_SUPPORTED),1)
  125. GO_PKG_ENABLE_PIE:=1
  126. else
  127. $(warning PIE buildmode is not supported for $(GO_OS)/$(GO_ARCH))
  128. endif
  129. endif
  130. endif
  131. ifdef CONFIG_PKG_ASLR_PIE_REGULAR
  132. ifeq ($(strip $(PKG_ASLR_PIE_REGULAR)),1)
  133. ifeq ($(GO_TARGET_PIE_SUPPORTED),1)
  134. GO_PKG_ENABLE_PIE:=1
  135. else
  136. $(warning PIE buildmode is not supported for $(GO_OS)/$(GO_ARCH))
  137. endif
  138. endif
  139. endif
  140. # sstrip causes corrupted section header size
  141. ifneq ($(CONFIG_USE_SSTRIP),)
  142. ifneq ($(CONFIG_DEBUG),)
  143. GO_PKG_STRIP_ARGS:=--strip-unneeded --remove-section=.comment --remove-section=.note
  144. else
  145. GO_PKG_STRIP_ARGS:=--strip-all
  146. endif
  147. STRIP:=$(TARGET_CROSS)strip $(GO_PKG_STRIP_ARGS)
  148. endif
  149. define GoPackage/GoSubMenu
  150. SUBMENU:=Go
  151. SECTION:=lang
  152. CATEGORY:=Languages
  153. endef
  154. GO_PKG_TARGET_VARS= \
  155. GOOS=$(GO_OS) \
  156. GOARCH=$(GO_ARCH) \
  157. GO386=$(GO_386) \
  158. GOARM=$(GO_ARM) \
  159. GOMIPS=$(GO_MIPS) \
  160. GOMIPS64=$(GO_MIPS64) \
  161. CGO_ENABLED=1 \
  162. CC=$(TARGET_CC) \
  163. CXX=$(TARGET_CXX) \
  164. CGO_CFLAGS="$(filter-out $(GO_CFLAGS_TO_REMOVE),$(TARGET_CFLAGS))" \
  165. CGO_CPPFLAGS="$(TARGET_CPPFLAGS)" \
  166. CGO_CXXFLAGS="$(filter-out $(GO_CFLAGS_TO_REMOVE),$(TARGET_CXXFLAGS))" \
  167. CGO_LDFLAGS="$(TARGET_LDFLAGS)"
  168. GO_PKG_BUILD_VARS= \
  169. GOPATH=$(GO_PKG_BUILD_DIR) \
  170. GOCACHE=$(GO_PKG_CACHE_DIR) \
  171. GOENV=off
  172. GO_PKG_DEFAULT_VARS= \
  173. $(GO_PKG_TARGET_VARS) \
  174. $(GO_PKG_BUILD_VARS)
  175. GO_PKG_VARS=$(GO_PKG_DEFAULT_VARS)
  176. # do not use for new code; this will be removed after the next OpenWrt release
  177. GoPackage/Environment=$(GO_PKG_VARS)
  178. GO_PKG_DEFAULT_LDFLAGS= \
  179. -buildid '$(SOURCE_DATE_EPOCH)' \
  180. -linkmode external \
  181. -extldflags '$(patsubst -z%,-Wl$(comma)-z$(comma)%,$(TARGET_LDFLAGS))'
  182. GO_PKG_CUSTOM_LDFLAGS= \
  183. $(GO_PKG_LDFLAGS) \
  184. $(patsubst %,-X %,$(GO_PKG_LDFLAGS_X))
  185. GO_PKG_INSTALL_ARGS= \
  186. -v \
  187. -trimpath \
  188. -ldflags "all=$(GO_PKG_DEFAULT_LDFLAGS)" \
  189. $(if $(filter $(GO_PKG_ENABLE_PIE),1),-buildmode pie) \
  190. $(if $(filter $(GO_ARCH),arm),-installsuffix "v$(GO_ARM)") \
  191. $(if $(filter $(GO_ARCH),mips mipsle),-installsuffix "$(GO_MIPS)") \
  192. $(if $(filter $(GO_ARCH),mips64 mips64le),-installsuffix "$(GO_MIPS64)") \
  193. $(if $(GO_PKG_GCFLAGS),-gcflags "$(GO_PKG_GCFLAGS)") \
  194. $(if $(GO_PKG_CUSTOM_LDFLAGS),-ldflags "$(GO_PKG_CUSTOM_LDFLAGS) $(GO_PKG_DEFAULT_LDFLAGS)") \
  195. $(if $(GO_PKG_TAGS),-tags "$(GO_PKG_TAGS)")
  196. # false if directory does not exist
  197. GoPackage/is_dir_not_empty=$$$$($(FIND) $(1) -maxdepth 0 -type d \! -empty 2>/dev/null)
  198. GoPackage/has_binaries=$(call GoPackage/is_dir_not_empty,$(GO_PKG_BUILD_BIN_DIR))
  199. define GoPackage/Build/Configure
  200. ( \
  201. cd $(PKG_BUILD_DIR) ; \
  202. mkdir -p $(GO_PKG_BUILD_DIR)/bin $(GO_PKG_BUILD_DIR)/src $(GO_PKG_CACHE_DIR) ; \
  203. \
  204. files=$$$$($(FIND) ./ \
  205. -type d -a \( -path './.git' -o -path './$(GO_PKG_WORK_DIR_NAME)' \) -prune -o \
  206. \! -type d -print | \
  207. sed 's|^\./||') ; \
  208. \
  209. if [ "$(strip $(GO_PKG_INSTALL_ALL))" != 1 ]; then \
  210. code=$$$$(echo "$$$$files" | grep '\.\(c\|cc\|cpp\|go\|h\|hh\|hpp\|proto\|s\)$$$$') ; \
  211. testdata=$$$$(echo "$$$$files" | grep '\(^\|/\)testdata/') ; \
  212. gomod=$$$$(echo "$$$$files" | grep '\(^\|/\)go\.\(mod\|sum\)$$$$') ; \
  213. \
  214. for pattern in $(GO_PKG_INSTALL_EXTRA); do \
  215. extra=$$$$(echo "$$$$extra"; echo "$$$$files" | grep "$$$$pattern") ; \
  216. done ; \
  217. \
  218. files=$$$$(echo "$$$$code"; echo "$$$$testdata"; echo "$$$$gomod"; echo "$$$$extra") ; \
  219. files=$$$$(echo "$$$$files" | grep -v '^[[:space:]]*$$$$' | sort -u) ; \
  220. fi ; \
  221. \
  222. IFS=$$$$'\n' ; \
  223. \
  224. echo "Copying files from $(PKG_BUILD_DIR) into $(GO_PKG_BUILD_DIR)/src/$(strip $(GO_PKG))" ; \
  225. for file in $$$$files; do \
  226. echo $$$$file ; \
  227. dest=$(GO_PKG_BUILD_DIR)/src/$(strip $(GO_PKG))/$$$$file ; \
  228. mkdir -p $$$$(dirname $$$$dest) ; \
  229. $(CP) $$$$file $$$$dest ; \
  230. done ; \
  231. echo ; \
  232. \
  233. link_contents() { \
  234. local src=$$$$1 ; \
  235. local dest=$$$$2 ; \
  236. local dirs dir base ; \
  237. \
  238. if [ -n "$$$$($(FIND) $$$$src -mindepth 1 -maxdepth 1 -name '*.go' \! -type d)" ]; then \
  239. echo "$$$$src is already a Go library" ; \
  240. return 1 ; \
  241. fi ; \
  242. \
  243. dirs=$$$$($(FIND) $$$$src -mindepth 1 -maxdepth 1 -type d) ; \
  244. for dir in $$$$dirs; do \
  245. base=$$$$(basename $$$$dir) ; \
  246. if [ -d $$$$dest/$$$$base ]; then \
  247. case $$$$dir in \
  248. *$(GO_PKG_PATH)/src/$(strip $(GO_PKG))) \
  249. echo "$(strip $(GO_PKG)) is already installed. Please check for circular dependencies." ;; \
  250. *) \
  251. link_contents $$$$src/$$$$base $$$$dest/$$$$base ;; \
  252. esac ; \
  253. else \
  254. echo "...$$$${src#$(GO_PKG_BUILD_DEPENDS_SRC)}/$$$$base" ; \
  255. $(LN) $$$$src/$$$$base $$$$dest/$$$$base ; \
  256. fi ; \
  257. done ; \
  258. } ; \
  259. \
  260. if [ "$(strip $(GO_PKG_SOURCE_ONLY))" != 1 ]; then \
  261. if [ -d $(GO_PKG_BUILD_DEPENDS_SRC) ]; then \
  262. echo "Symlinking directories from $(GO_PKG_BUILD_DEPENDS_SRC) into $(GO_PKG_BUILD_DIR)/src" ; \
  263. link_contents $(GO_PKG_BUILD_DEPENDS_SRC) $(GO_PKG_BUILD_DIR)/src ; \
  264. else \
  265. echo "$(GO_PKG_BUILD_DEPENDS_SRC) does not exist, skipping symlinks" ; \
  266. fi ; \
  267. else \
  268. echo "Not building binaries, skipping symlinks" ; \
  269. fi ; \
  270. echo ; \
  271. )
  272. endef
  273. # $(1) additional arguments for go command line (optional)
  274. define GoPackage/Build/Compile
  275. ( \
  276. cd $(GO_PKG_BUILD_DIR) ; \
  277. export $(GO_PKG_VARS) ; \
  278. \
  279. echo "Finding targets" ; \
  280. targets=$$$$(go list $(GO_PKG_BUILD_PKG)) ; \
  281. for pattern in $(GO_PKG_EXCLUDES); do \
  282. targets=$$$$(echo "$$$$targets" | grep -v "$$$$pattern") ; \
  283. done ; \
  284. echo ; \
  285. \
  286. if [ "$(strip $(GO_PKG_GO_GENERATE))" = 1 ]; then \
  287. echo "Calling go generate" ; \
  288. go generate -v $(1) $$$$targets ; \
  289. echo ; \
  290. fi ; \
  291. \
  292. if [ "$(strip $(GO_PKG_SOURCE_ONLY))" != 1 ]; then \
  293. echo "Building targets" ; \
  294. go install $(GO_PKG_INSTALL_ARGS) $(1) $$$$targets ; \
  295. retval=$$$$? ; \
  296. echo ; \
  297. \
  298. if [ "$$$$retval" -eq 0 ] && [ -z "$(call GoPackage/has_binaries)" ]; then \
  299. echo "No binaries were generated, consider adding GO_PKG_SOURCE_ONLY:=1 to Makefile" ; \
  300. echo ; \
  301. fi ; \
  302. \
  303. echo "Cleaning module download cache (golang/go#27455)" ; \
  304. go clean -modcache ; \
  305. echo ; \
  306. fi ; \
  307. exit $$$$retval ; \
  308. )
  309. endef
  310. define GoPackage/Build/InstallDev
  311. $(call GoPackage/Package/Install/Src,$(1))
  312. endef
  313. define GoPackage/Package/Install/Bin
  314. if [ -n "$(call GoPackage/has_binaries)" ]; then \
  315. $(INSTALL_DIR) $(1)/usr/bin ; \
  316. $(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/* $(1)/usr/bin/ ; \
  317. fi
  318. endef
  319. define GoPackage/Package/Install/Src
  320. dir=$$$$(dirname $(GO_PKG)) ; \
  321. $(INSTALL_DIR) $(1)$(GO_PKG_PATH)/src/$$$$dir ; \
  322. $(CP) $(GO_PKG_BUILD_DIR)/src/$(strip $(GO_PKG)) $(1)$(GO_PKG_PATH)/src/$$$$dir/
  323. endef
  324. define GoPackage/Package/Install
  325. $(call GoPackage/Package/Install/Bin,$(1))
  326. $(call GoPackage/Package/Install/Src,$(1))
  327. endef
  328. ifneq ($(strip $(GO_PKG)),)
  329. Build/Configure=$(call GoPackage/Build/Configure)
  330. Build/Compile=$(call GoPackage/Build/Compile)
  331. Build/InstallDev=$(call GoPackage/Build/InstallDev,$(1))
  332. endif
  333. define GoPackage
  334. ifndef Package/$(1)/install
  335. Package/$(1)/install=$$(call GoPackage/Package/Install,$$(1))
  336. endif
  337. endef
  338. define GoBinPackage
  339. ifndef Package/$(1)/install
  340. Package/$(1)/install=$$(call GoPackage/Package/Install/Bin,$$(1))
  341. endif
  342. endef
  343. define GoSrcPackage
  344. ifndef Package/$(1)/install
  345. Package/$(1)/install=$$(call GoPackage/Package/Install/Src,$$(1))
  346. endif
  347. endef