@@ -24,27 +24,80 @@ max_freebsd() {
2424 fi
2525 done
2626 if [[ -z " $best " ]]; then
27- echo " Could not find best release for FreeBSD ${BSD_MAJOR} ." 1>&2
27+ echo -e " \e[31merror:\e[0m could not find best release for FreeBSD ${BSD_MAJOR} ." 1>&2
2828 exit 1
2929 fi
3030 echo " ${best} "
3131}
3232
3333latest_freebsd () {
34- local dirs
35- local releases
36- local max_release
34+ local mirror=" ${1} "
35+ local response=
36+ local line=
37+ local lines=
38+ local releases=
39+ local max_release=
40+
41+ response=$( curl --silent --list-only --location " ${mirror} /${BSD_ARCH} /" | grep RELEASE)
42+ if [[ " ${response} " != * RELEASE* ]]; then
43+ echo -e " \e[31merror:\e[0m could not find a candidate release for FreeBSD ${BSD_MAJOR} ." 1>&2
44+ exit 1
45+ fi
46+ readarray -t lines <<< " ${response}"
47+
48+ # shellcheck disable=SC2016
49+ local regex=' /<a.*?>\s*(\d+\.\d+-RELEASE)\s*\/?\s*<\/a>/; print $1'
50+ # not all lines will match: some return `*-RELEASE/` as a line
51+ if [[ " ${response} " == * " <a" * ]]; then
52+ # have HTML output, need to extract it via a regex
53+ releases=()
54+ for line in " ${lines[@]} " ; do
55+ if [[ " ${line} " == * " <a" * ]]; then
56+ # because of the pattern we're extracting, this can't split
57+ # shellcheck disable=SC2207
58+ releases+=($( echo " ${line} " | perl -nle " ${regex} " ) )
59+ fi
60+ done
61+ else
62+ releases=(" ${lines[@]} " )
63+ fi
3764
38- dirs=$( curl --silent --list-only " ${BSD_HOME} /${BSD_ARCH} /" | grep RELEASE)
39- read -r -a releases <<< " ${dirs[@]}"
4065 max_release=$( max_freebsd " ${releases[@]} " )
41-
4266 echo " ${max_release// -RELEASE/ } "
4367}
4468
45- base_release=" $( latest_freebsd) "
46- bsd_ftp=" ${BSD_HOME} /${BSD_ARCH} /${base_release} -RELEASE"
47- bsd_http=" http://${bsd_ftp} "
69+ freebsd_mirror () {
70+ local home=
71+ local code=
72+
73+ set +e
74+ for home in " ${BSD_HOME[@]} " ; do
75+ # we need a timeout in case the server is down to avoid
76+ # infinitely hanging. timeout error code is always 124
77+ # these mirrors can be quite slow, so have a long timeout
78+ timeout 20s curl --silent --list-only --location " ${home} /${BSD_ARCH} /" > /dev/null
79+ code=$?
80+ if [[ " ${code} " == 0 ]]; then
81+ echo " ${home} "
82+ return 0
83+ elif [[ " ${code} " != 124 ]]; then
84+ echo -e " \e[1;33mwarning:\e[0m mirror ${home} does not seem to work." 1>&2
85+ fi
86+ done
87+ set -e
88+
89+ echo -e " \e[31merror:\e[0m could not find a working FreeBSD mirror." 1>&2
90+ exit 1
91+ }
92+
93+ mirror=$( freebsd_mirror)
94+ base_release=$( latest_freebsd " ${mirror} " )
95+ bsd_base_url=" ${mirror} /${BSD_ARCH} /${base_release} -RELEASE"
96+ if [[ " ${bsd_base_url} " == " http" * ]]; then
97+ bsd_url=" ${bsd_base_url} "
98+ else
99+ bsd_url=" http://${bsd_base_url} "
100+ fi
48101
49102main () {
50103 local binutils=2.32 \
@@ -75,7 +128,7 @@ main() {
75128 ./contrib/download_prerequisites
76129 cd ..
77130
78- curl --retry 3 -sSfL " ${bsd_http } /base.txz" -O
131+ curl --retry 3 -sSfL " ${bsd_url } /base.txz" -O
79132 tar -C " ${td} /freebsd" -xJf base.txz ./usr/include ./usr/lib ./lib
80133
81134 cd binutils-build
@@ -87,29 +140,33 @@ main() {
87140
88141 local destdir=" /usr/local/${target} "
89142 cp -r " ${td} /freebsd/usr/include" " ${destdir} "
90- cp " ${td} /freebsd/lib/libc.so.7" " ${destdir} /lib"
91- cp " ${td} /freebsd/lib/libm.so.5" " ${destdir} /lib"
92- cp " ${td} /freebsd/lib/libkvm.so.7" " ${destdir} /lib"
93- cp " ${td} /freebsd/lib/libthr.so.3" " ${destdir} /lib"
94- cp " ${td} /freebsd/lib/libutil.so.9" " ${destdir} /lib"
95- cp " ${td} /freebsd/lib/libdevstat.so.7" " ${destdir} /lib"
143+ cp -r " ${td} /freebsd/lib/" * " ${destdir} /lib"
96144 cp " ${td} /freebsd/usr/lib/libc++.so.1" " ${destdir} /lib"
97145 cp " ${td} /freebsd/usr/lib/libc++.a" " ${destdir} /lib"
98146 cp " ${td} /freebsd/usr/lib" /lib{c,util,m,ssp_nonshared}.a " ${destdir} /lib"
99147 cp " ${td} /freebsd/usr/lib" /lib{rt,execinfo,procstat}.so.1 " ${destdir} /lib"
100148 cp " ${td} /freebsd/usr/lib" /{crt1,Scrt1,crti,crtn}.o " ${destdir} /lib"
101149 cp " ${td} /freebsd/usr/lib" /libkvm.a " ${destdir} /lib"
102150
103- ln -s libc.so.7 " ${destdir} /lib/libc.so"
104- ln -s libc++.so.1 " ${destdir} /lib/libc++.so"
105- ln -s libexecinfo.so.1 " ${destdir} /lib/libexecinfo.so"
106- ln -s libprocstat.so.1 " ${destdir} /lib/libprocstat.so"
107- ln -s libm.so.5 " ${destdir} /lib/libm.so"
108- ln -s librt.so.1 " ${destdir} /lib/librt.so"
109- ln -s libutil.so.9 " ${destdir} /lib/libutil.so"
151+ local lib=
152+ local base=
153+ local link=
154+ for lib in " ${destdir} /lib/" * .so.* ; do
155+ base=$( basename " ${lib} " )
156+ link=" ${base} "
157+ # not strictly necessary since this will always work, but good fallback
158+ while [[ " ${link} " == * .so.* ]]; do
159+ link=" ${link% .* } "
160+ done
161+
162+ # just extra insurance that we won't try to overwrite an existing file
163+ local dstlink=" ${destdir} /lib/${link} "
164+ if [[ -n " ${link} " ]] && [[ " ${link} " != " ${base} " ]] && [[ ! -f " ${dstlink} " ]]; then
165+ ln -s " ${base} " " ${dstlink} "
166+ fi
167+ done
168+
110169 ln -s libthr.so.3 " ${destdir} /lib/libpthread.so"
111- ln -s libdevstat.so.7 " ${destdir} /lib/libdevstat.so"
112- ln -s libkvm.so.7 " ${destdir} /lib/libkvm.so"
113170
114171 cd gcc-build
115172 ../gcc/configure \
@@ -136,7 +193,7 @@ main() {
136193 purge_packages
137194
138195 # store the version info for the FreeBSD release
139- bsd_revision=$( curl --retry 3 -sSfL " ${bsd_http } /REVISION" )
196+ bsd_revision=$( curl --retry 3 -sSfL " ${bsd_url } /REVISION" )
140197 echo " ${base_release} (${bsd_revision} )" > /opt/freebsd-version
141198
142199 rm -rf " ${td} "
0 commit comments