Skip to content

Commit 195d24f

Browse files
committed
dev-lang/go: optimize the ebuild
Signed-off-by: Ryan Qian <i@bitbili.net>
1 parent 87de268 commit 195d24f

File tree

2 files changed

+282
-229
lines changed

2 files changed

+282
-229
lines changed

dev-lang/go/go-1.20.13.ebuild

+142-117
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,32 @@
33

44
EAPI=8
55

6-
export CBUILD=${CBUILD:-${CHOST}}
7-
export CTARGET=${CTARGET:-${CHOST}}
8-
9-
MY_PV=${PV/_/}
10-
116
inherit toolchain-funcs
127

138
DESCRIPTION="A concurrent garbage collected and typesafe programming language"
149
HOMEPAGE="https://go.dev"
10+
SRC_URI="https://storage.googleapis.com/golang/go${PV//_/}.src.tar.gz "
1511

16-
SRC_URI="https://storage.googleapis.com/golang/go${MY_PV}.src.tar.gz "
17-
S="${WORKDIR}"/go
12+
LICENSE="BSD"
1813
KEYWORDS="-* ~amd64 ~arm ~arm64 ~loong ~mips ~ppc64 ~riscv ~s390 ~x86 ~amd64-linux ~x86-linux ~arm64-macos ~x64-macos ~x64-solaris"
1914

20-
[[ $PV =~ ^([[:digit:]]+)\.([[:digit:]]+)(\.([[:digit:]]+))?(_.*)?$ ]] || true
21-
PV_MINOR="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}"
22-
PV_PATCH="${BASH_REMATCH[4]}"
23-
GOROOT_VALUE="/usr/lib/go${PV_MINOR}"
24-
25-
LICENSE="BSD"
26-
SLOT="${PV_MINOR}/${PV_PATCH:-0}"
2715
IUSE="abi_mips_o32 abi_mips_n64 cpu_flags_x86_sse2"
2816

17+
PV_MAJOR2MINOR="$(ver_cut 1-2)"
18+
PV_PATCH="$(ver_cut 3)"
19+
SLOT="${PV_MAJOR2MINOR}/${PV_PATCH:-0}"
20+
21+
# the installation path is fixed to "${EPREFIX}${GOROOT_VALUE}"
22+
GOROOT_VALUE="/usr/lib/go${PV_MAJOR2MINOR}"
23+
S="${WORKDIR}"/go
24+
25+
# see https://go.dev/doc/go1.20#bootstrap
26+
BOOTSTRAP_MIN_VER="1.17.13"
27+
2928
BDEPEND="
3029
|| (
31-
dev-lang/go
32-
dev-lang/go-bootstrap
30+
>=dev-lang/go-${BOOTSTRAP_MIN_VER}
31+
>=dev-lang/go-bootstrap-${BOOTSTRAP_MIN_VER}
3332
)
3433
"
3534
RDEPEND="app-eselect/eselect-go"
@@ -40,16 +39,15 @@ QA_EXECSTACK='*.syso'
4039
# Do not complain about CFLAGS, etc, since Go doesn't use them.
4140
QA_FLAGS_IGNORED='.*'
4241

43-
# The tools in /usr/lib/go.* should not cause the multilib-strict check to fail.
44-
QA_MULTILIB_PATHS="usr/lib/go.*/pkg/tool/.*/.*"
42+
# The tools in /usr/lib/go${PV_MAJOR2MINOR} should not cause the multilib-strict check to fail.
43+
QA_MULTILIB_PATHS="usr/lib/go${PV_MAJOR2MINOR}/pkg/tool/.*/.*"
4544

4645
# This package triggers "unrecognized elf file(s)" notices on riscv.
4746
# https://bugs.gentoo.org/794046
4847
QA_PREBUILT='.*'
4948

50-
# Do not strip this package. Stripping is unsupported upstream and may
51-
# fail.
52-
RESTRICT+=" strip"
49+
# Do not strip this package. Stripping is unsupported upstream and may fail.
50+
RESTRICT="strip"
5351

5452
DOCS=(
5553
CONTRIBUTING.md
@@ -60,171 +58,198 @@ DOCS=(
6058

6159
go_arch() {
6260
# By chance most portage arch names match Go
63-
local tc_arch=$(tc-arch $@)
61+
local tc_arch
62+
tc_arch="$(tc-arch "$1")"
6463
case "${tc_arch}" in
65-
arm64-macos) echo arm64;;
66-
x86) echo 386;;
67-
x64-*) echo amd64;;
68-
loong) echo loong64;;
69-
mips) if use abi_mips_o32; then
70-
[[ $(tc-endian $@) = big ]] && echo mips || echo mipsle
64+
arm64*) echo arm64 ;;
65+
loong) echo loong64 ;;
66+
mips)
67+
if use abi_mips_o32; then
68+
[[ $(tc-endian "$1") == big ]] && echo mips || echo mipsle
7169
elif use abi_mips_n64; then
72-
[[ $(tc-endian $@) = big ]] && echo mips64 || echo mips64le
73-
fi ;;
74-
ppc64) [[ $(tc-endian $@) = big ]] && echo ppc64 || echo ppc64le ;;
70+
[[ $(tc-endian "$1") == big ]] && echo mips64 || echo mips64le
71+
fi
72+
;;
73+
ppc64) [[ $(tc-endian "$1") == big ]] && echo ppc64 || echo ppc64le ;;
7574
riscv) echo riscv64 ;;
76-
s390) echo s390x ;;
77-
*) echo "${tc_arch}";;
75+
s390) echo s390x ;;
76+
x64-*) echo amd64 ;;
77+
x86) echo 386 ;;
78+
*) echo "${tc_arch}" ;;
7879
esac
7980
}
8081

8182
go_arm() {
82-
case "${1:-${CHOST}}" in
83-
armv5*) echo 5;;
84-
armv6*) echo 6;;
85-
armv7*) echo 7;;
83+
local host="$CHOST"
84+
case "$host" in
85+
armv5*) echo 5 ;;
86+
armv6*) echo 6 ;;
87+
armv7*) echo 7 ;;
8688
*)
87-
die "unknown GOARM for ${1:-${CHOST}}"
89+
die "unknown GOARM for $host"
8890
;;
8991
esac
9092
}
9193

9294
go_os() {
93-
case "${1:-${CHOST}}" in
94-
*-linux*) echo linux;;
95-
*-darwin*) echo darwin;;
96-
*-freebsd*) echo freebsd;;
97-
*-netbsd*) echo netbsd;;
98-
*-openbsd*) echo openbsd;;
99-
*-solaris*) echo solaris;;
95+
local host="${1:-$CHOST}"
96+
case "$host" in
97+
*-linux*) echo linux ;;
98+
*-darwin*) echo darwin ;;
99+
*-freebsd*) echo freebsd ;;
100+
*-netbsd*) echo netbsd ;;
101+
*-openbsd*) echo openbsd ;;
102+
*-solaris*) echo solaris ;;
100103
*-cygwin*|*-interix*|*-winnt*)
101104
echo windows
102105
;;
103106
*)
104-
die "unknown GOOS for ${1:-${CHOST}}"
107+
die "unknown GOOS for $host"
105108
;;
106109
esac
107110
}
108111

109112
go_tuple() {
110-
echo "$(go_os $@)_$(go_arch $@)"
113+
echo "$(go_os "$1")_$(go_arch "$1")"
111114
}
112115

113116
go_cross_compile() {
114-
[[ $(go_tuple ${CBUILD}) != $(go_tuple) ]]
117+
[[ $(go_tuple "$CBUILD") != $(go_tuple) ]]
118+
}
119+
120+
declare -g GO_LATEST_PVR
121+
pkg_setup() {
122+
GO_LATEST_PVR="$(best_version -b dev-lang/go)"
115123
}
116124

117125
src_compile() {
118-
if has_version -b dev-lang/go; then
119-
export GOROOT_BOOTSTRAP="${BROOT}$(go env GOROOT)"
126+
local go_ver=0
127+
if [[ -n $GO_LATEST_PVR ]]; then
128+
go_ver="${GO_LATEST_PVR#dev-lang/go-}"
129+
fi
130+
if ver_test "$go_ver" -ge "$BOOTSTRAP_MIN_VER"; then
131+
go_ver="$(ver_cut 1-2 "$go_ver")"
132+
GOROOT_BOOTSTRAP="${BROOT}/usr/lib/go${go_ver}"
120133
elif has_version -b dev-lang/go-bootstrap; then
121-
export GOROOT_BOOTSTRAP="${BROOT}/usr/lib/go-bootstrap"
134+
GOROOT_BOOTSTRAP="${BROOT}/usr/lib/go-bootstrap"
122135
else
123136
eerror "Go cannot be built without go or go-bootstrap installed"
124137
die "Should not be here, please report a bug"
125138
fi
126139

127-
export GOROOT_FINAL="${EPREFIX}${GOROOT_VALUE}"
128-
export GOROOT="${PWD}"
129-
export GOBIN="${GOROOT}/bin"
140+
GOROOT_FINAL="${EPREFIX}${GOROOT_VALUE}"
130141

131142
# Go's build script does not use BUILD/HOST/TARGET consistently. :(
132-
export GOHOSTARCH=$(go_arch ${CBUILD})
133-
export GOHOSTOS=$(go_os ${CBUILD})
134-
export CC=$(tc-getBUILD_CC)
135-
136-
export GOARCH=$(go_arch)
137-
export GOOS=$(go_os)
138-
export CC_FOR_TARGET=$(tc-getCC)
139-
export CXX_FOR_TARGET=$(tc-getCXX)
140-
use arm && export GOARM=$(go_arm)
141-
use x86 && export GO386=$(usex cpu_flags_x86_sse2 '' 'softfloat')
142-
143-
cd src
143+
GOHOSTARCH=$(go_arch "$CBUILD")
144+
CC="$(tc-getBUILD_CC)"
145+
CXX="$(tc-getBUILD_CXX)"
146+
147+
GOARCH=$(go_arch)
148+
GOOS=$(go_os)
149+
CC_FOR_TARGET=$(tc-getCC)
150+
CXX_FOR_TARGET=$(tc-getCXX)
151+
use arm && GOARM=$(go_arm) && export GOARM
152+
use x86 && GO386=$(usex cpu_flags_x86_sse2 '' 'softfloat') && export GO386
153+
154+
export \
155+
GOROOT_BOOTSTRAP \
156+
GOROOT_FINAL \
157+
GOHOSTARCH \
158+
CC \
159+
CXX \
160+
GOARCH \
161+
GOOS \
162+
CC_FOR_TARGET \
163+
CXX_FOR_TARGET
164+
cd src || die
144165
bash -x ./make.bash || die "build failed"
145166
}
146167

147168
src_test() {
148169
go_cross_compile && return 0
149170

150-
cd src
151-
PATH="${GOBIN}:${PATH}" \
152-
./run.bash -no-rebuild || die "tests failed"
153-
cd ..
154-
rm -fr pkg/*_race || die
155-
rm -fr pkg/obj/go-build || die
171+
cd src || die
172+
./run.bash -no-rebuild -k || die "tests failed"
156173
}
157174

158175
src_install() {
159-
# There is a known issue which requires the source tree to be installed [1].
160-
# Once this is fixed, we can consider using the doc use flag to control
161-
# installing the doc and src directories.
176+
insinto "${GOROOT_VALUE}"
177+
doins go.env VERSION
162178
# The use of cp is deliberate in order to retain permissions
163-
# [1] https://golang.org/issue/2775
164-
dodir ${GOROOT_VALUE}
165179
cp -R api bin doc lib pkg misc src test "${ED}${GOROOT_VALUE}"
166-
einstalldocs
167180

168-
# testdata directories are not needed on the installed system
169-
rm -fr $(find "${ED}${GOROOT_VALUE}" -iname testdata -type d -print)
181+
# remove the testdata dir, due to I cannot find a way to prevent the QA
182+
# warning messages about 'Unresolved soname dependencies' for those elf
183+
# files that is used for testing on different platforms, ;(
184+
local file
185+
while read -r file; do
186+
[[ -d "$file" ]] && rm -rf "$file" || die
187+
done < <(find "${ED}${GOROOT_VALUE}" -name testdata -type d)
188+
189+
einstalldocs
170190

191+
# do binary link
171192
local bin_path
172193
if go_cross_compile; then
173194
bin_path="bin/$(go_tuple)"
174195
else
175196
bin_path=bin
176197
fi
177198
local f x
178-
for x in ${bin_path}/*; do
199+
for x in "${bin_path}"/*; do
179200
f=${x##*/}
180-
dosym -r ${GOROOT_VALUE}/${bin_path}/${f} /usr/bin/${f}${PV_MINOR}
201+
dosym -r "${GOROOT_VALUE}/${bin_path}/${f}" "/usr/bin/${f}${PV_MAJOR2MINOR}"
181202
done
182203
}
183204

184-
declare -g GO_LATEST_PVR
185-
pkg_preinst() {
186-
GO_LATEST_PVR=$(best_version 'dev-lang/go')
187-
}
188-
189205
pkg_postinst() {
190-
local pvr=${GO_LATEST_PVR#dev-lang/go-} upgrade=false
191-
[[ $pvr =~ ^([[:digit:]]+)\.([[:digit:]]+)(\.([[:digit:]]+))?(_.*)?(-.*)?$ ]] || true
192-
local lmajor="${BASH_REMATCH[1]:-0}"
193-
local lminor="${BASH_REMATCH[2]:-0}"
194-
local nvr="${lmajor}.${lminor}"
195-
if (( ${PV_MINOR%.*} == $lmajor && ${PV_MINOR#*.} > $lminor )) || \
196-
(( ${PV_MINOR%.*} > $lmajor )); then
206+
# check if it's a minor version upgrade
207+
local pre_pvr="${GO_LATEST_PVR#dev-lang/go-}" upgrade=false \
208+
pre_pv_major2minor new_pv_major2minor
209+
pre_pv_major2minor=$(ver_cut 1-2 "$pre_pvr")
210+
if ver_test "$PV_MAJOR2MINOR" -gt "$pre_pv_major2minor"; then
197211
upgrade=true
198-
nvr=${PV_MINOR}
212+
new_pv_major2minor=${PV_MAJOR2MINOR}
199213
fi
200-
local libPath="${EROOT}"/usr/lib/go
201-
local binPath="${EROOT}"/usr/bin/go
214+
215+
# try to switch to the new version if it's a minor version upgrade or it's a
216+
# fresh installation
217+
local eselect_ret=0 \
218+
libPath="${EROOT}"/usr/lib/go \
219+
binPath="${EROOT}"/usr/bin/go
202220
if [[ $upgrade == true && -L $libPath && -L $binPath ]] || \
203221
[[ ! -e $libPath && ! -e $binPath ]]; then
204-
eselect go set go${nvr}
205-
if [[ $? == 0 ]]; then
206-
elog "[eselect] successfully switched to version: go${nvr}"
222+
eselect go set go${new_pv_major2minor} || eselect_ret=$?
223+
if [[ $eselect_ret == 0 ]]; then
224+
elog "[eselect] successfully switched to version: go${new_pv_major2minor}"
207225
elog
208226
else
209-
eerror "[eselect] switch to version go${nvr} error, please handle it manually!"
227+
eerror "[eselect] switch to version go${new_pv_major2minor} error, please handle it manually!"
210228
fi
211229
fi
212230

213-
local dbDir official_go_version_installed
214-
for dbDir in $(ls -1d "${EROOT}"/var/db/pkg/dev-lang/go-1.*); do
215-
if [[ -d "$dbDir" ]] && [[ $(< "$dbDir"/repository) == "gentoo" ]]; then
216-
official_go_version_installed=1
217-
break
231+
# check if the ::gentoo version go pkg is installed,
232+
# cannot use has_version to check the pkg with an overlay name like
233+
# 'dev-lang/go::gentoo', so sad :(
234+
# check the vdb directly
235+
local vdb_path="${EROOT}var/db/pkg" other_go_version_installed line
236+
while read -r line; do
237+
if [[ -f "${line}/repository" ]]; then
238+
if [[ "$(cat "${line}/repository")" != ryans ]]; then
239+
# TODO: is there any way to get the current repo_name?
240+
other_go_version_installed=1
241+
break
242+
fi
218243
fi
219-
done
220-
if [[ -n $official_go_version_installed ]]; then
221-
ewarn "The official version of golang exists, you can"
244+
done < <(find "${vdb_path}/dev-lang/" -name 'go-1*' -maxdepth 1 -type d)
245+
if [[ $other_go_version_installed == 1 ]]; then
246+
ewarn "It seems that other version of golang exists, you can"
222247
ewarn
223-
ewarn "1. Please uninstall the official version by executing:"
224-
ewarn " # emerge -C dev-lang/go::gentoo"
248+
ewarn "1. Please uninstall the other version by executing:"
249+
ewarn " # emerge -C dev-lang/go::gentoo # (or ::gentoo_prefix, or with other repo_name)"
225250
ewarn " and use the eselect to select this slot enabled version:"
226251
ewarn " # eselect go cleanup"
227-
ewarn " to make it work."
252+
ewarn " to make this go package works."
228253
ewarn
229254
ewarn "2. Or, just mask this version if you don't want it by executing:"
230255
ewarn " # echo $'\\\\n'\"dev-lang/go::ryans\" >>/etc/portage/package.mask/golang"
@@ -238,19 +263,19 @@ pkg_postinst() {
238263
echo
239264
fi
240265
elog "To select/switch between available Go version, execute as root:"
241-
elog " # eselect go set (go1.19|go1.20|...)"
242-
elog "ATTENTION: not compatible with dev-lang/go::gentoo version"
266+
elog " # eselect go set (go1.20|go1.21|...)"
267+
elog "ATTENTION: not compatible with dev-lang/go::gentoo (or ::gentoo_prefix) version"
243268

244-
[[ -z ${REPLACING_VERSIONS} ]] && return
269+
[[ -n ${REPLACING_VERSIONS} ]] || return
245270
elog
246-
elog "After ${CATEGORY}/${PN} is updated it is recommended to rebuild"
271+
elog "After ${CATEGORY}/${PN} is updated, it is recommended to rebuild"
247272
elog "all packages compiled with previous versions of ${CATEGORY}/${PN}"
248273
elog "due to the static linking nature of go."
249274
elog "If this is not done, the packages compiled with the older"
250275
elog "version of the compiler will not be updated until they are"
251276
elog "updated individually, which could mean they will have"
252277
elog "vulnerabilities."
253-
elog "Run 'emerge @golang-rebuild' to rebuild all 'go' packages"
278+
elog "Run 'emerge @golang-rebuild' to rebuild all 'go' packages."
254279
elog "See https://bugs.gentoo.org/752153 for more info"
255280
}
256281

0 commit comments

Comments
 (0)