1################################################################################
2# Golang package infrastructure
3#
4# This file implements an infrastructure that eases development of package .mk
5# files for Go packages. It should be used for all packages that are written in
6# go.
7#
8# See the Buildroot documentation for details on the usage of this
9# infrastructure
10#
11#
12# In terms of implementation, this golang infrastructure requires the .mk file
13# to only specify metadata information about the package: name, version,
14# download URL, etc.
15#
16# We still allow the package .mk file to override what the different steps are
17# doing, if needed. For example, if <PKG>_BUILD_CMDS is already defined, it is
18# used as the list of commands to perform to build the package, instead of the
19# default golang behavior. The package can also define some post operation
20# hooks.
21#
22################################################################################
23
24GO_BIN = $(HOST_DIR)/bin/go
25
26################################################################################
27# inner-golang-package -- defines how the configuration, compilation and
28# installation of a Go package should be done, implements a few hooks to tune
29# the build process for Go specificities and calls the generic package
30# infrastructure to generate the necessary make targets
31#
32#  argument 1 is the lowercase package name
33#  argument 2 is the uppercase package name, including a HOST_ prefix for host
34#             packages
35#  argument 3 is the uppercase package name, without the HOST_ prefix for host
36#             packages
37#  argument 4 is the type (target or host)
38#
39################################################################################
40
41define inner-golang-package
42
43$(2)_BUILD_OPTS += \
44	-ldflags "$$($(2)_LDFLAGS)" \
45	-modcacherw \
46	-tags "$$($(2)_TAGS)" \
47	-trimpath \
48	-p $$(PARALLEL_JOBS) \
49	-buildvcs=false
50
51# Target packages need the Go compiler on the host at download time (for
52# vendoring), and at build and install time.
53$(2)_DOWNLOAD_DEPENDENCIES += host-go
54$(2)_DEPENDENCIES += host-go
55
56$(2)_BUILD_TARGETS ?= .
57
58# If the build target is just ".", then we assume the binary to be
59# produced is named after the package. If however, a build target has
60# been specified, we assume that the binaries to be produced are named
61# after each build target building them (below in <pkg>_BUILD_CMDS).
62ifeq ($$($(2)_BUILD_TARGETS),.)
63$(2)_BIN_NAME ?= $$($(2)_RAWNAME)
64endif
65
66$(2)_INSTALL_BINS ?= $$($(2)_RAWNAME)
67
68# Source files in Go usually use an import path resolved around
69# domain/vendor/software. We infer domain/vendor/software from the upstream URL
70# of the project.
71$(2)_SRC_DOMAIN = $$(call domain,$$($(2)_SITE))
72$(2)_SRC_VENDOR = $$(word 1,$$(subst /, ,$$(call notdomain,$$($(2)_SITE))))
73$(2)_SRC_SOFTWARE = $$(word 2,$$(subst /, ,$$(call notdomain,$$($(2)_SITE))))
74
75# $(2)_GOMOD is the root Go module path for the project, inferred if not set.
76# If the go.mod file does not exist, one is written with this root path.
77$(2)_GOMOD ?= $$($(2)_SRC_DOMAIN)/$$($(2)_SRC_VENDOR)/$$($(2)_SRC_SOFTWARE)
78
79# Generate a go.mod file if it doesn't exist. Note: Go is configured
80# to use the "vendor" dir and not make network calls.
81define $(2)_GEN_GOMOD
82	if [ ! -f $$(@D)/go.mod ]; then \
83		printf "module $$($(2)_GOMOD)\n" > $$(@D)/go.mod; \
84	fi
85endef
86$(2)_POST_PATCH_HOOKS += $(2)_GEN_GOMOD
87
88$(2)_DOWNLOAD_POST_PROCESS = go
89$(2)_DL_ENV += \
90	$$(HOST_GO_COMMON_ENV) \
91	GOPROXY=direct \
92	$$($(2)_GO_ENV)
93
94# Because we append vendored info, we can't rely on the values being empty
95# once we eventually get into the generic-package infra. So, we duplicate
96# the heuristics here
97ifndef $(2)_LICENSE
98  ifdef $(3)_LICENSE
99    $(2)_LICENSE = $$($(3)_LICENSE)
100  endif
101endif
102
103# Due to vendoring, it is pretty likely that not all licenses are
104# listed in <pkg>_LICENSE. If the license is unset, it is "unknown"
105# so adding unknowns to some unknown is still some other unkown,
106# so don't append the blurb in that case.
107ifneq ($$($(2)_LICENSE),)
108$(2)_LICENSE += , vendored dependencies licenses probably not listed
109endif
110
111# Build step. Only define it if not already defined by the package .mk
112# file.
113ifndef $(2)_BUILD_CMDS
114ifeq ($(4),target)
115
116ifeq ($(BR2_STATIC_LIBS),y)
117$(2)_LDFLAGS += -extldflags '-static'
118$(2)_TAGS += osusergo netgo
119endif
120
121# Build package for target
122define $(2)_BUILD_CMDS
123	$$(foreach d,$$($(2)_BUILD_TARGETS),\
124		cd $$(@D); \
125		$$(HOST_GO_TARGET_ENV) \
126			$$($(2)_GO_ENV) \
127			$$(GO_BIN) build -v $$($(2)_BUILD_OPTS) \
128			-o $$(@D)/bin/$$(or $$($(2)_BIN_NAME),$$(notdir $$(d))) \
129			$$($(2)_GOMOD)/$$(d)
130	)
131endef
132else
133# Build package for host
134define $(2)_BUILD_CMDS
135	$$(foreach d,$$($(2)_BUILD_TARGETS),\
136		cd $$(@D); \
137		$$(HOST_GO_HOST_ENV) \
138			$$($(2)_GO_ENV) \
139			$$(GO_BIN) build -v $$($(2)_BUILD_OPTS) \
140			-o $$(@D)/bin/$$(or $$($(2)_BIN_NAME),$$(notdir $$(d))) \
141			$$($(2)_GOMOD)/$$(d)
142	)
143endef
144endif
145endif
146
147# Target installation step. Only define it if not already defined by the
148# package .mk file.
149ifndef $(2)_INSTALL_TARGET_CMDS
150define $(2)_INSTALL_TARGET_CMDS
151	$$(foreach d,$$($(2)_INSTALL_BINS),\
152		$$(INSTALL) -D -m 0755 $$(@D)/bin/$$(d) $$(TARGET_DIR)/usr/bin/$$(d)
153	)
154endef
155endif
156
157# Host installation step
158ifndef $(2)_INSTALL_CMDS
159define $(2)_INSTALL_CMDS
160	$$(foreach d,$$($(2)_INSTALL_BINS),\
161		$$(INSTALL) -D -m 0755 $$(@D)/bin/$$(d) $$(HOST_DIR)/bin/$$(d)
162	)
163endef
164endif
165
166# Call the generic package infrastructure to generate the necessary make
167# targets
168$(call inner-generic-package,$(1),$(2),$(3),$(4))
169
170endef # inner-golang-package
171
172################################################################################
173# golang-package -- the target generator macro for Go packages
174################################################################################
175
176golang-package = $(call inner-golang-package,$(pkgname),$(call UPPERCASE,$(pkgname)),$(call UPPERCASE,$(pkgname)),target)
177host-golang-package = $(call inner-golang-package,host-$(pkgname),$(call UPPERCASE,host-$(pkgname)),$(call UPPERCASE,$(pkgname)),host)
178