Fix update_seed use by not using nor building binary packages during the seed update.
[catalyst.git] / targets / support / chroot-functions.sh
1 #!/bin/bash
2
3 # Set the profile
4 eselect profile set ${clst_target_profile}
5
6 # Trap these signals and kill ourselves if recieved
7 # Force ourselves to die if any of these signals are recieved
8 # most likely our controlling terminal is gone
9 trap "echo SIGTERM signal recieved killing $0 with pid $$;kill -9 $$" SIGTERM
10 trap "echo SIGHUP signal recieved killing $0 with pid $$;kill -9 $$" SIGHUP
11 trap "echo SIGKILL signal recieved killing $0 with pid $$;kill -9 $$" SIGKILL
12
13 #SIGINT interrupt character (usually Ctrl-C)
14 #       * example: high-level sequence of events
15 #       * my process (call it "P") is running
16 #       * user types ctrl-c
17 #       * kernel recognizes this and generates SIGINT signal
18 trap "echo SIGINT signal recieved killing $0 with pid $$;kill -9 $$" SIGINT
19
20 check_genkernel_version(){
21         if [ -x /usr/bin/genkernel ]
22         then
23                 genkernel_version=$(genkernel --version)
24                 genkernel_version_major=${genkernel_version%%.*}
25                 genkernel_version_minor_sub=${genkernel_version#${genkernel_version_major}.}
26                 genkernel_version_minor=${genkernel_version_minor_sub%%.*}
27                 genkernel_version_sub=${genkernel_version##*.}
28                 if [ -n "${genkernel_version}" -a "${genkernel_version_major}" -eq '3' -a "${genkernel_version_minor}" -ge '3' ]
29                 then
30                         echo "Genkernel version ${genkernel_version} found ... continuing"
31                 else
32                         echo "ERROR: Your genkernel version is too low in your seed stage.  genkernel version 3.3.0"
33                         echo "or greater is required."
34                         exit 1
35                 fi
36         else
37                 exit 1
38         fi
39 }
40
41 get_libdir() {
42         ABI=$(portageq envvar ABI)
43         DEFAULT_ABI=$(portageq envvar DEFAULT_ABI)
44         LIBDIR_default=$(portageq envvar LIBDIR_default)
45
46         local abi
47         if [ $# -gt 0 ]
48         then
49                 abi=${1}
50         elif [ -n "${ABI}" ]
51         then
52                 abi=${ABI}
53         elif [ -n "${DEFAULT_ABI}" ]
54         then
55                 abi=${DEFAULT_ABI}
56         else
57                 abi="default"
58         fi
59
60         local var="LIBDIR_${abi}"
61         var=$(portageq envvar ${var})
62         echo ${var}
63 }
64
65 setup_myfeatures(){
66         setup_myemergeopts
67         export FEATURES="-news clean-logs"
68         if [ -n "${clst_CCACHE}" ]
69         then
70                 export clst_myfeatures="${clst_myfeatures} ccache"
71                 clst_root_path=/ run_merge --oneshot --noreplace dev-util/ccache || exit 1
72         fi
73
74         if [ -n "${clst_DISTCC}" ]
75         then
76                 export clst_myfeatures="${clst_myfeatures} distcc"
77                 export DISTCC_HOSTS="${clst_distcc_hosts}"
78                 [ -e /etc/portage/make.conf ] && \
79                         echo 'USE="${USE} -avahi -gtk -gnome"' >> /etc/portage/make.conf
80                 # We install distcc to / on stage1, then use --noreplace, so we need to
81                 # have some way to check if we need to reinstall distcc without being
82                 # able to rely on USE, so we check for the distcc user and force a
83                 # reinstall if it isn't found.
84                 if [ "$(getent passwd distcc | cut -d: -f1)" != "distcc" ]
85                 then
86                         clst_root_path=/ run_merge --oneshot sys-devel/distcc || exit 1
87                 else
88                         clst_root_path=/ run_merge --oneshot --noreplace sys-devel/distcc || exit 1
89                 fi
90                 sed -i '/USE="${USE} -avahi -gtk -gnome"/d' /etc/portage/make.conf
91                 mkdir -p /etc/distcc
92                 echo "${clst_distcc_hosts}" > /etc/distcc/hosts
93
94                 # This sets up automatic cross-distcc-fu according to
95                 # http://www.gentoo.org/doc/en/cross-compiling-distcc.xml
96                 CHOST=$(portageq envvar CHOST)
97                 LIBDIR=$(get_libdir)
98                 cd /usr/${LIBDIR}/distcc/bin
99                 rm cc gcc g++ c++ 2>/dev/null
100                 echo -e '#!/bin/bash\nexec /usr/'${LIBDIR}'/distcc/bin/'${CHOST}'-g${0:$[-2]} "$@"' > ${CHOST}-wrapper
101                 chmod a+x /usr/${LIBDIR}/distcc/bin/${CHOST}-wrapper
102                 for i in cc gcc g++ c++; do ln -s ${CHOST}-wrapper ${i}; done
103         fi
104
105         if [ -n "${clst_ICECREAM}" ]
106         then
107                 clst_root_path=/ run_merge --oneshot --noreplace sys-devel/icecream || exit 1
108
109                 # This sets up automatic cross-icecc-fu according to
110                 # http://gentoo-wiki.com/HOWTO_Setup_An_ICECREAM_Compile_Cluster#Icecream_and_cross-compiling
111                 CHOST=$(portageq envvar CHOST)
112                 LIBDIR=$(get_libdir)
113                 cd /usr/${LIBDIR}/icecc/bin
114                 rm cc gcc g++ c++ 2>/dev/null
115                 echo -e '#!/bin/bash\nexec /usr/'${LIBDIR}'/icecc/bin/'${CHOST}'-g${0:$[-2]} "$@"' > ${CHOST}-wrapper
116                 chmod a+x ${CHOST}-wrapper
117                 for i in cc gcc g++ c++; do ln -s ${CHOST}-wrapper ${i}; done
118                 export PATH="/usr/lib/icecc/bin:${PATH}"
119                 export PREROOTPATH="/usr/lib/icecc/bin"
120         fi
121         export FEATURES="${clst_myfeatures} -news"
122 }
123
124 setup_myemergeopts(){
125         if [ -n "${clst_VERBOSE}" ]
126         then
127                 clst_myemergeopts="--verbose"
128         else
129                 clst_myemergeopts="--quiet"
130                 bootstrap_opts="${bootstrap_opts} -q"
131         fi
132         if [ -n "${clst_FETCH}" ]
133         then
134                 export bootstrap_opts="${bootstrap_opts} -f"
135                 export clst_myemergeopts="${clst_myemergeopts} -f"
136         elif [ -n "${clst_PKGCACHE}" -a -z "${clst_update_seed}" ]
137         then
138                 export clst_myemergeopts="${clst_myemergeopts} --usepkg --buildpkg --newuse"
139                 export bootstrap_opts="${bootstrap_opts} -r"
140         fi
141 }
142
143 setup_binutils(){
144         if [ -x /usr/bin/binutils-config ]
145         then
146                 mythang=$( cd /etc/env.d/binutils; ls ${clst_CHOST}-* | head -n 1 )
147                 if [ -z "${mythang}" ]
148                 then
149                         mythang=1
150                 fi
151                 binutils-config ${mythang}; update_env_settings
152         fi
153 }
154
155 setup_gcc(){
156         if [ -x /usr/bin/gcc-config ]
157         then
158                 mythang=$( cd /etc/env.d/gcc; ls ${clst_CHOST}-* | head -n 1 )
159                 if [ -z "${mythang}" ]
160                 then
161                         mythang=1
162                 fi
163                 gcc-config ${mythang}; update_env_settings
164         fi
165 }
166
167 setup_pkgmgr(){
168         # We need to merge our package manager with USE="build" set in case it is
169         # portage to avoid frying our /etc/portage/make.conf file.  Otherwise, we could
170         # just let emerge system could merge it.
171         # Use --update or portage won't reinstall the same version.
172         [ -e /etc/portage/make.conf ] && echo 'USE="${USE} build"' >> /etc/portage/make.conf
173         run_merge --oneshot --nodeps --update sys-apps/portage
174         sed -i '/USE="${USE} build"/d' /etc/portage/make.conf
175 }
176
177 cleanup_distcc() {
178         LIBDIR=$(get_libdir)
179         rm -rf /etc/distcc/hosts
180         for i in cc gcc c++ g++; do
181                 rm -f /usr/${LIBDIR}/distcc/bin/${i}
182                 ln -s /usr/bin/distcc /usr/${LIBDIR}/distcc/bin/${i}
183         done
184         rm -f /usr/${LIBDIR}/distcc/bin/*-wrapper
185 }
186
187 cleanup_icecream() {
188         LIBDIR=$(get_libdir)
189         for i in cc gcc c++ g++; do
190                 rm -f /usr/${LIBDIR}/icecc/bin/${i}
191                 ln -s /usr/bin/icecc /usr/${LIBDIR}/icecc/bin/${i}
192         done
193         rm -f /usr/${LIBDIR}/icecc/bin/*-wrapper
194 }
195
196 cleanup_stages() {
197         make_destpath
198         if [ -n "${clst_DISTCC}" ]
199         then
200                 cleanup_distcc
201         fi
202         if [ -n "${clst_ICECREAM}" ]
203         then
204                 cleanup_icecream
205         fi
206         case ${clst_target} in
207                 stage3|system)
208                         run_merge --depclean --with-bdeps=y
209                         ;;
210                 *)
211                         echo "Skipping depclean operation for ${clst_target}"
212                         ;;
213         esac
214         case ${clst_target} in
215                 stage1|stage2|stage3|system)
216                         rm -f /var/lib/portage/world
217                         touch /var/lib/portage/world
218                         ;;
219                 *)
220                         echo "Skipping removal of world file for ${clst_target}"
221                         ;;
222         esac
223
224         rm -f /var/log/emerge.log /var/log/portage/elog/*
225 }
226
227 update_env_settings(){
228         [ -x /usr/sbin/env-update ] && /usr/sbin/env-update
229         source /etc/profile
230         [ -f /tmp/envscript ] && source /tmp/envscript
231 }
232
233 die() {
234         echo "$1"
235         exit 1
236 }
237
238 make_destpath() {
239         # ROOT is / by default, so remove any ROOT= settings from make.conf
240         sed -i '/ROOT=/d' /etc/portage/make.conf
241         export ROOT=/
242         if [ "${1}" != "/" -a -n "${1}" ]
243         then
244                 echo "ROOT=\"${1}\"" >> /etc/portage/make.conf
245                 export ROOT=${1}
246         fi
247         if [ ! -d ${ROOT} ]
248         then
249                 install -d ${ROOT}
250         fi
251 }
252
253 run_merge() {
254         # Sets up the ROOT= parameter
255         # with no options ROOT=/
256         make_destpath ${clst_root_path}
257
258         export EMERGE_WARNING_DELAY=0
259         export CLEAN_DELAY=0
260         export EBEEP_IGNORE=0
261         export EPAUSE_IGNORE=0
262         export CONFIG_PROTECT="-*"
263
264         if [ -n "${clst_VERBOSE}" ]
265         then
266                 echo "ROOT=${ROOT} emerge ${clst_myemergeopts} -pt $@" || exit 1
267                 emerge ${clst_myemergeopts} -pt $@ || exit 3
268                 echo "Press any key within 15 seconds to pause the build..."
269                 read -s -t 15 -n 1
270                 if [ $? -eq 0 ]
271                 then
272                         echo "Press any key to continue..."
273                         read -s -n 1
274                 fi
275         fi
276
277         echo "emerge ${clst_myemergeopts} $@" || exit 1
278
279         emerge ${clst_myemergeopts} $@ || exit 1
280 }
281
282 show_debug() {
283         if [ "${clst_DEBUG}" = "1" ]
284         then
285                 unset PACKAGES
286                 echo "DEBUG:"
287                 echo "Profile/target info:"
288                 echo "Profile inheritance:"
289                 python -c 'import portage; print portage.settings.profiles'
290                 echo
291                 # TODO: make this work on non-portage
292                 emerge --info
293                 # TODO: grab our entire env
294                 # <zmedico> to get see the ebuild env you can do something like:
295                 # `set > /tmp/env_dump.${EBUILD_PHASE}` inside /etc/portage/bashrc
296                 # XXX: Also, portageq does *not* source profile.bashrc at any time.
297                 echo
298                 echo "BOOTSTRAP_USE:            $(portageq envvar BOOTSTRAP_USE)"
299                 echo
300                 echo "USE (profile):         $(portageq envvar USE)"
301                 echo "FEATURES (profile):    $(portageq envvar FEATURES)"
302                 echo
303                 echo "ARCH:                  $(portageq envvar ARCH)"
304                 echo "CHOST:                 $(portageq envvar CHOST)"
305                 echo "CFLAGS:                $(portageq envvar CFLAGS)"
306                 echo
307                 echo "These should be blank on non-multilib profiles."
308                 echo "ABI:                   $(portageq envvar ABI)"
309                 echo "DEFAULT_ABI:           $(portageq envvar DEFAULT_ABI)"
310                 echo "KERNEL_ABI:            $(portageq envvar KERNEL_ABI)"
311                 echo "LIBDIR:                $(get_libdir)"
312                 echo "MULTILIB_ABIS:         $(portageq envvar MULTILIB_ABIS)"
313                 echo "PROFILE_ARCH:          $(portageq envvar PROFILE_ARCH)"
314                 echo
315         fi
316 }
317
318 run_default_funcs() {
319         if [ "${RUN_DEFAULT_FUNCS}" != "no" ]
320         then
321                 update_env_settings
322                 setup_myfeatures
323                 show_debug
324         fi
325 }
326
327 # Functions
328 # Copy libs of a executable in the chroot
329 function copy_libs() {
330         # Check if it's a dynamix exec
331         ldd ${1} > /dev/null 2>&1 || return
332
333         for lib in `ldd ${1} | awk '{ print $3 }'`
334         do
335                 echo ${lib}
336                 if [ -e ${lib} ]
337                 then
338                         if [ ! -e ${clst_root_path}/${lib} ]
339                         then
340                                 copy_file ${lib}
341                                 [ -e "${clst_root_path}/${lib}" ] && \
342                                 strip -R .comment -R .note ${clst_root_path}/${lib} \
343                                 || echo "WARNING : Cannot strip lib ${clst_root_path}/${lib} !"
344                         fi
345                 else
346                         echo "WARNING : Some library was not found for ${lib} !"
347                 fi
348         done
349 }
350
351 function copy_symlink() {
352         STACK=${2}
353         [ "${STACK}" = "" ] && STACK=16 || STACK=$((${STACK} - 1 ))
354
355         if [ ${STACK} -le 0 ]
356         then
357                 echo "WARNING : ${TARGET} : too many levels of symbolic links !"
358                 return
359         fi
360
361         [ ! -e ${clst_root_path}/`dirname ${1}` ] && \
362                 mkdir -p ${clst_root_path}/`dirname ${1}`
363         [ ! -e ${clst_root_path}/${1} ] && \
364                 cp -vfdp ${1} ${clst_root_path}/${1}
365
366         if [[ -n $(type -p realpath) ]]; then
367                 TARGET=`realpath ${1}`
368         else
369                 TARGET=`readlink -f ${1}`
370         fi
371         if [ -h ${TARGET} ]
372         then
373                 copy_symlink ${TARGET} ${STACK}
374         else
375                 copy_file ${TARGET}
376         fi
377 }
378
379 function copy_file() {
380         f="${1}"
381
382         if [ ! -e "${f}" ]
383         then
384                 echo "WARNING : File not found : ${f}"
385                 continue
386         fi
387
388         [ ! -e ${clst_root_path}/`dirname ${f}` ] && \
389                 mkdir -p ${clst_root_path}/`dirname ${f}`
390         [ ! -e ${clst_root_path}/${f} ] && \
391                 cp -vfdp ${f} ${clst_root_path}/${f}
392         if [ -x ${f} -a ! -h ${f} ]
393         then
394                 copy_libs ${f}
395                 strip -R .comment -R .note ${clst_root_path}/${f} > /dev/null 2>&1
396         elif [ -h ${f} ]
397         then
398                 copy_symlink ${f}
399         fi
400 }
401
402 create_handbook_icon() {
403         # This function creates a local icon to the Gentoo Handbook
404         echo "[Desktop Entry]
405 Encoding=UTF-8
406 Version=1.0
407 Type=Link
408 URL=file:///mnt/cdrom/docs/handbook/html/index.html
409 Terminal=false
410 Name=Gentoo Linux Handbook
411 GenericName=Gentoo Linux Handbook
412 Comment=This is a link to the local copy of the Gentoo Linux Handbook.
413 Icon=text-editor" > /usr/share/applications/gentoo-handbook.desktop
414 }
415
416 # We do this everywhere, so why not put it in this script
417 run_default_funcs