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