Fixes a bug inadvertently caused by 6c0a577 where setting update_seed
[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         # if we have PKGCACHE, and either update_seed is empty or 'no', make and use binpkgs
137         elif [ -n "${clst_PKGCACHE}" ] && [ -z "${clst_update_seed}" -o "${clst_update_seed}" = "no" ]
138         then
139                 export clst_myemergeopts="${clst_myemergeopts} --usepkg --buildpkg --newuse"
140                 export bootstrap_opts="${bootstrap_opts} -r"
141         fi
142 }
143
144 setup_binutils(){
145         if [ -x /usr/bin/binutils-config ]
146         then
147                 mythang=$( cd /etc/env.d/binutils; ls ${clst_CHOST}-* | head -n 1 )
148                 if [ -z "${mythang}" ]
149                 then
150                         mythang=1
151                 fi
152                 binutils-config ${mythang}; update_env_settings
153         fi
154 }
155
156 setup_gcc(){
157         if [ -x /usr/bin/gcc-config ]
158         then
159                 mythang=$( cd /etc/env.d/gcc; ls ${clst_CHOST}-* | head -n 1 )
160                 if [ -z "${mythang}" ]
161                 then
162                         mythang=1
163                 fi
164                 gcc-config ${mythang}; update_env_settings
165         fi
166 }
167
168 setup_pkgmgr(){
169         # We need to merge our package manager with USE="build" set in case it is
170         # portage to avoid frying our /etc/portage/make.conf file.  Otherwise, we could
171         # just let emerge system could merge it.
172         # Use --update or portage won't reinstall the same version.
173         [ -e /etc/portage/make.conf ] && echo 'USE="${USE} build"' >> /etc/portage/make.conf
174         run_merge --oneshot --nodeps --update sys-apps/portage
175         sed -i '/USE="${USE} build"/d' /etc/portage/make.conf
176 }
177
178 cleanup_distcc() {
179         LIBDIR=$(get_libdir)
180         rm -rf /etc/distcc/hosts
181         for i in cc gcc c++ g++; do
182                 rm -f /usr/${LIBDIR}/distcc/bin/${i}
183                 ln -s /usr/bin/distcc /usr/${LIBDIR}/distcc/bin/${i}
184         done
185         rm -f /usr/${LIBDIR}/distcc/bin/*-wrapper
186 }
187
188 cleanup_icecream() {
189         LIBDIR=$(get_libdir)
190         for i in cc gcc c++ g++; do
191                 rm -f /usr/${LIBDIR}/icecc/bin/${i}
192                 ln -s /usr/bin/icecc /usr/${LIBDIR}/icecc/bin/${i}
193         done
194         rm -f /usr/${LIBDIR}/icecc/bin/*-wrapper
195 }
196
197 cleanup_stages() {
198         make_destpath
199         if [ -n "${clst_DISTCC}" ]
200         then
201                 cleanup_distcc
202         fi
203         if [ -n "${clst_ICECREAM}" ]
204         then
205                 cleanup_icecream
206         fi
207         case ${clst_target} in
208                 stage3|system)
209                         run_merge --depclean --with-bdeps=y
210                         ;;
211                 *)
212                         echo "Skipping depclean operation for ${clst_target}"
213                         ;;
214         esac
215         case ${clst_target} in
216                 stage1|stage2|stage3|system)
217                         rm -f /var/lib/portage/world
218                         touch /var/lib/portage/world
219                         ;;
220                 *)
221                         echo "Skipping removal of world file for ${clst_target}"
222                         ;;
223         esac
224
225         rm -f /var/log/emerge.log /var/log/portage/elog/*
226 }
227
228 update_env_settings(){
229         [ -x /usr/sbin/env-update ] && /usr/sbin/env-update
230         source /etc/profile
231         [ -f /tmp/envscript ] && source /tmp/envscript
232 }
233
234 die() {
235         echo "$1"
236         exit 1
237 }
238
239 make_destpath() {
240         # ROOT is / by default, so remove any ROOT= settings from make.conf
241         sed -i '/ROOT=/d' /etc/portage/make.conf
242         export ROOT=/
243         if [ "${1}" != "/" -a -n "${1}" ]
244         then
245                 echo "ROOT=\"${1}\"" >> /etc/portage/make.conf
246                 export ROOT=${1}
247         fi
248         if [ ! -d ${ROOT} ]
249         then
250                 install -d ${ROOT}
251         fi
252 }
253
254 run_merge() {
255         # Sets up the ROOT= parameter
256         # with no options ROOT=/
257         make_destpath ${clst_root_path}
258
259         export EMERGE_WARNING_DELAY=0
260         export CLEAN_DELAY=0
261         export EBEEP_IGNORE=0
262         export EPAUSE_IGNORE=0
263         export CONFIG_PROTECT="-*"
264
265         if [ -n "${clst_VERBOSE}" ]
266         then
267                 echo "ROOT=${ROOT} emerge ${clst_myemergeopts} -pt $@" || exit 1
268                 emerge ${clst_myemergeopts} -pt $@ || exit 3
269                 echo "Press any key within 15 seconds to pause the build..."
270                 read -s -t 15 -n 1
271                 if [ $? -eq 0 ]
272                 then
273                         echo "Press any key to continue..."
274                         read -s -n 1
275                 fi
276         fi
277
278         echo "emerge ${clst_myemergeopts} $@" || exit 1
279
280         emerge ${clst_myemergeopts} $@ || exit 1
281 }
282
283 show_debug() {
284         if [ "${clst_DEBUG}" = "1" ]
285         then
286                 unset PACKAGES
287                 echo "DEBUG:"
288                 echo "Profile/target info:"
289                 echo "Profile inheritance:"
290                 python -c 'import portage; print portage.settings.profiles'
291                 echo
292                 # TODO: make this work on non-portage
293                 emerge --info
294                 # TODO: grab our entire env
295                 # <zmedico> to get see the ebuild env you can do something like:
296                 # `set > /tmp/env_dump.${EBUILD_PHASE}` inside /etc/portage/bashrc
297                 # XXX: Also, portageq does *not* source profile.bashrc at any time.
298                 echo
299                 echo "BOOTSTRAP_USE:            $(portageq envvar BOOTSTRAP_USE)"
300                 echo
301                 echo "USE (profile):         $(portageq envvar USE)"
302                 echo "FEATURES (profile):    $(portageq envvar FEATURES)"
303                 echo
304                 echo "ARCH:                  $(portageq envvar ARCH)"
305                 echo "CHOST:                 $(portageq envvar CHOST)"
306                 echo "CFLAGS:                $(portageq envvar CFLAGS)"
307                 echo
308                 echo "These should be blank on non-multilib profiles."
309                 echo "ABI:                   $(portageq envvar ABI)"
310                 echo "DEFAULT_ABI:           $(portageq envvar DEFAULT_ABI)"
311                 echo "KERNEL_ABI:            $(portageq envvar KERNEL_ABI)"
312                 echo "LIBDIR:                $(get_libdir)"
313                 echo "MULTILIB_ABIS:         $(portageq envvar MULTILIB_ABIS)"
314                 echo "PROFILE_ARCH:          $(portageq envvar PROFILE_ARCH)"
315                 echo
316         fi
317 }
318
319 run_default_funcs() {
320         if [ "${RUN_DEFAULT_FUNCS}" != "no" ]
321         then
322                 update_env_settings
323                 setup_myfeatures
324                 show_debug
325         fi
326 }
327
328 # Functions
329 # Copy libs of a executable in the chroot
330 function copy_libs() {
331         # Check if it's a dynamix exec
332         ldd ${1} > /dev/null 2>&1 || return
333
334         for lib in `ldd ${1} | awk '{ print $3 }'`
335         do
336                 echo ${lib}
337                 if [ -e ${lib} ]
338                 then
339                         if [ ! -e ${clst_root_path}/${lib} ]
340                         then
341                                 copy_file ${lib}
342                                 [ -e "${clst_root_path}/${lib}" ] && \
343                                 strip -R .comment -R .note ${clst_root_path}/${lib} \
344                                 || echo "WARNING : Cannot strip lib ${clst_root_path}/${lib} !"
345                         fi
346                 else
347                         echo "WARNING : Some library was not found for ${lib} !"
348                 fi
349         done
350 }
351
352 function copy_symlink() {
353         STACK=${2}
354         [ "${STACK}" = "" ] && STACK=16 || STACK=$((${STACK} - 1 ))
355
356         if [ ${STACK} -le 0 ]
357         then
358                 echo "WARNING : ${TARGET} : too many levels of symbolic links !"
359                 return
360         fi
361
362         [ ! -e ${clst_root_path}/`dirname ${1}` ] && \
363                 mkdir -p ${clst_root_path}/`dirname ${1}`
364         [ ! -e ${clst_root_path}/${1} ] && \
365                 cp -vfdp ${1} ${clst_root_path}/${1}
366
367         if [[ -n $(type -p realpath) ]]; then
368                 TARGET=`realpath ${1}`
369         else
370                 TARGET=`readlink -f ${1}`
371         fi
372         if [ -h ${TARGET} ]
373         then
374                 copy_symlink ${TARGET} ${STACK}
375         else
376                 copy_file ${TARGET}
377         fi
378 }
379
380 function copy_file() {
381         f="${1}"
382
383         if [ ! -e "${f}" ]
384         then
385                 echo "WARNING : File not found : ${f}"
386                 continue
387         fi
388
389         [ ! -e ${clst_root_path}/`dirname ${f}` ] && \
390                 mkdir -p ${clst_root_path}/`dirname ${f}`
391         [ ! -e ${clst_root_path}/${f} ] && \
392                 cp -vfdp ${f} ${clst_root_path}/${f}
393         if [ -x ${f} -a ! -h ${f} ]
394         then
395                 copy_libs ${f}
396                 strip -R .comment -R .note ${clst_root_path}/${f} > /dev/null 2>&1
397         elif [ -h ${f} ]
398         then
399                 copy_symlink ${f}
400         fi
401 }
402
403 create_handbook_icon() {
404         # This function creates a local icon to the Gentoo Handbook
405         echo "[Desktop Entry]
406 Encoding=UTF-8
407 Version=1.0
408 Type=Link
409 URL=file:///mnt/cdrom/docs/handbook/html/index.html
410 Terminal=false
411 Name=Gentoo Linux Handbook
412 GenericName=Gentoo Linux Handbook
413 Comment=This is a link to the local copy of the Gentoo Linux Handbook.
414 Icon=text-editor" > /usr/share/applications/gentoo-handbook.desktop
415 }
416
417 # We do this everywhere, so why not put it in this script
418 run_default_funcs