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