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