github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/snap/plugins/juju_go.py (about) 1 # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- 2 # 3 # Copyright (C) 2020 Canonical Ltd 4 # 5 # This program is free software: you can redistribute it and/or modify 6 # it under the terms of the GNU General Public License version 3 as 7 # published by the Free Software Foundation. 8 # 9 # This program is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # GNU General Public License for more details. 13 # 14 # You should have received a copy of the GNU General Public License 15 # along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 """The juju-go plugin used for snapping juju. 18 19 This plugin uses the common plugin keywords as well as those for "sources". 20 For more information check the 'plugins' topic for the former and the 21 'sources' topic for the latter. 22 23 Additionally, this plugin uses the following plugin-specific keywords: 24 25 - go-channel 26 (string, default: latest/stable) 27 The Snap Store channel to install go from. 28 29 - go-buildtags 30 (list of strings) 31 Tags to use during the go build. Default is not to use any build tags. 32 """ 33 from typing import Any, Dict, List, Set 34 35 from snapcraft.plugins.v2 import PluginV2 36 37 38 class PluginImpl(PluginV2): 39 @classmethod 40 def get_schema(cls) -> Dict[str, Any]: 41 return { 42 "$schema": "http://json-schema.org/draft-04/schema#", 43 "type": "object", 44 "additionalProperties": False, 45 "properties": { 46 "go-channel": { 47 "type": "string", 48 "default": "latest/stable", 49 }, 50 "go-buildtags": { 51 "type": "array", 52 "uniqueItems": True, 53 "items": {"type": "string"}, 54 "default": [], 55 }, 56 "go-packages": { 57 "type": "array", 58 "minitems": 1, 59 "uniqueItems": True, 60 "items": {"type": "string"}, 61 "default": ["./..."], 62 }, 63 "go-external-strings": { 64 "type": "object", 65 "additionalProperties": {"type": "string"}, 66 "default": {}, 67 }, 68 "go-static": { 69 "type": "boolean", 70 "default": False, 71 }, 72 "go-strip": { 73 "type": "boolean", 74 "default": False, 75 }, 76 "go-cgo-enabled": { 77 "type": "string", 78 "default": "0", 79 }, 80 "go-cgo-cc": { 81 "type": "string", 82 "default": "gcc", 83 }, 84 "go-cgo-cflags": { 85 "type": "string", 86 "default": "", 87 }, 88 "go-cgo-ldflags": { 89 "type": "string", 90 "default": "", 91 }, 92 "go-cgo-ldflags-allow": { 93 "type": "string", 94 "default": "", 95 }, 96 "go-cgo-ld-library-path": { 97 "type": "string", 98 "default": "", 99 }, 100 }, 101 "required": ["source"], 102 } 103 104 def get_build_snaps(self) -> Set[str]: 105 return {f"go/{self.options.go_channel}"} 106 107 def get_build_packages(self) -> Set[str]: 108 if self.options.go_cgo_cc != "musl-gcc": 109 return {"gcc"} 110 return set() 111 112 def get_build_environment(self) -> Dict[str, str]: 113 env = { 114 "GOBIN": "${SNAPCRAFT_PART_INSTALL}/bin", 115 "CGO_ENABLED": self.options.go_cgo_enabled, 116 } 117 118 if self.options.go_cgo_enabled == "1": 119 env.update({ 120 "SNAPCRAFT_GO_CGO_CFLAGS": f"-I${{SNAPCRAFT_STAGE}}/libs/include {self.options.go_cgo_cflags}", 121 "SNAPCRAFT_GO_CGO_LDFLAGS": f"-L${{SNAPCRAFT_STAGE}}/libs {self.options.go_cgo_ldflags}", 122 "SNAPCRAFT_GO_CGO_LDFLAGS_ALLOW": self.options.go_cgo_ldflags_allow, 123 "SNAPCRAFT_GO_LD_LIBRARY_PATH": f"${{SNAPCRAFT_STAGE}} {self.options.go_cgo_ld_library_path}", 124 }) 125 126 ld_flags = '' 127 if self.options.go_strip: 128 ld_flags += '-s -w ' 129 if self.options.go_static: 130 ld_flags += '-extldflags "-static" ' 131 if self.options.go_cgo_enabled == "1": 132 ld_flags += '-linkmode "external" ' 133 ld_flags = ld_flags.strip() 134 135 if len(self.options.go_external_strings) > 0: 136 for k, v in self.options.go_external_strings.items(): 137 ld_flags += f' -X {k}={v}' 138 139 env.update({ 140 "SNAPCRAFT_GO_LDFLAGS": f'{ld_flags}' 141 }) 142 return env 143 144 def get_build_commands(self) -> List[str]: 145 if self.options.go_buildtags: 146 tags = "-tags={}".format(",".join(self.options.go_buildtags)) 147 else: 148 tags = "" 149 150 cmd = f'go install -p "${{SNAPCRAFT_PARALLEL_BUILD_COUNT}}" {tags} -ldflags "${{SNAPCRAFT_GO_LDFLAGS}}"' 151 for go_package in self.options.go_packages: 152 cmd += f" {go_package}" 153 154 cmds = [] 155 cmds.append("go mod download") 156 157 if self.options.go_cgo_enabled == "1": 158 cmds.append(f'export PATH=/usr/local/musl/bin:$PATH') 159 cmds.append(f'export CGO_CFLAGS="${{SNAPCRAFT_GO_CGO_CFLAGS}}"') 160 cmds.append(f'export CGO_LDFLAGS="${{SNAPCRAFT_GO_CGO_LDFLAGS}}"') 161 cmds.append(f'export CGO_LDFLAGS_ALLOW="${{SNAPCRAFT_GO_CGO_LDFLAGS_ALLOW}}"') 162 cmds.append(f'export LD_LIBRARY_PATH="${{SNAPCRAFT_GO_LD_LIBRARY_PATH}}"') 163 cmds.append(f'export CC={self.options.go_cgo_cc}') 164 165 cmds.append(cmd) 166 return cmds