Moved creating of stage1 package list to the beginning of stage1-chroot.sh so we...
[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 # We do this everywhere, so why not put it in this script
18 run_default_funcs
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         if [ -n "${clst_CCACHE}" ]
68         then
69                 export clst_myfeatures="${clst_myfeatures} ccache"
70                 #if [ "${clst_AUTORESUME}" = "1" -a -e /tmp/.clst_ccache ]
71                 #then
72                 #       echo "CCACHE Autoresume point found not emerging ccache"
73                 #else
74                         clst_root_path=/ run_emerge --oneshot --nodeps ccache || exit 1
75                 #       touch /tmp/.clst_ccache
76                 #fi
77         fi
78
79         if [ -n "${clst_DISTCC}" ]
80         then
81                 export clst_myfeatures="${clst_myfeatures} distcc"
82                 export DISTCC_HOSTS="${clst_distcc_hosts}"
83                 #if [ "${clst_AUTORESUME}" = "1" -a -e /tmp/.clst_distcc ]
84                 #then
85                 #       echo "DISTCC Autoresume point found not emerging distcc"
86                 #else
87                         USE="-gtk -gnome" clst_root_path=/ run_emerge --oneshot --nodeps distcc || exit 1
88                         #touch /tmp/.clst_distcc
89                 #fi
90                 mkdir -p /etc/distcc
91                 echo "${clst_distcc_hosts}" > /etc/distcc/hosts
92
93                 # This sets up automatic cross-distcc-fu according to
94                 # http://www.gentoo.org/doc/en/cross-compiling-distcc.xml
95                 CHOST=$(portageq envvar CHOST)
96                 # TODO: change to use get_libdir
97                 cd /usr/lib/distcc/bin
98                 rm cc gcc g++ c++ 2>/dev/null
99                 echo -e '#!/bin/bash\nexec /usr/lib/distcc/bin/'${CHOST}'-g${0:$[-2]} "$@"' > ${CHOST}-wrapper
100                 chmod a+x /usr/lib/distcc/bin/${CHOST}-wrapper
101                 for i in cc gcc g++ c++; do ln -s ${CHOST}-wrapper ${i}; done
102         fi
103
104         if [ -n "${clst_ICECREAM}" ]
105         then
106                 clst_root_path=/ run_emerge --oneshot --nodeps sys-devel/icecream || exit 1
107
108                 # This sets up automatic cross-icecc-fu according to
109                 # http://gentoo-wiki.com/HOWTO_Setup_An_ICECREAM_Compile_Cluster#Icecream_and_cross-compiling
110                 CHOST=$(portageq envvar CHOST)
111                 LIBDIR=$(get_libdir)
112                 cd /usr/${LIBDIR}/icecc/bin
113                 rm cc gcc g++ c++ 2>/dev/null
114                 echo -e '#!/bin/bash\nexec /usr/'${LIBDIR}'/icecc/bin/'${CHOST}'-g${0:$[-2]} "$@"' > ${CHOST}-wrapper
115                 chmod a+x ${CHOST}-wrapper
116                 for i in cc gcc g++ c++; do ln -s ${CHOST}-wrapper ${i}; done
117                 export PATH="/usr/lib/icecc/bin:${PATH}"
118                 export PREROOTPATH="/usr/lib/icecc/bin"
119         fi
120         export FEATURES="${clst_myfeatures}"
121 }
122
123 setup_myemergeopts(){
124         if [ -n "${clst_VERBOSE}" ]
125         then
126                 clst_myemergeopts="--verbose"
127         else
128                 clst_myemergeopts="--quiet"
129         fi
130         if [ -n "${clst_FETCH}" ]
131         then
132                 export bootstrap_opts="-f"
133                 export clst_myemergeopts="${clst_myemergeopts} -f"
134         elif [ -n "${clst_PKGCACHE}" ]
135         then
136                 export clst_myemergeopts="${clst_myemergeopts} --usepkg --buildpkg --newuse"
137                 export bootstrap_opts="-r"
138         fi
139 }
140
141 setup_portage(){
142         # portage needs to be merged manually with USE="build" set to avoid frying
143         # our make.conf. emerge system could merge it otherwise.
144 #       if [ "${clst_AUTORESUME}" = "1" -a -e /tmp/.clst_portage ]
145 #       then
146 #               echo "Portage Autoresume point found not emerging portage"
147 #       else
148                 USE="build" run_emerge --oneshot --nodeps portage
149 #               touch /tmp/.clst_portage || exit 1
150 #       fi
151 }
152
153 setup_gcc(){
154         if [ -x /usr/bin/gcc-config ]
155         then
156                 mythang=$( cd /etc/env.d/gcc; ls ${clst_CHOST}-* | head -n 1 )
157                 if [ -z "${mythang}" ]
158                 then
159                         mythang=1
160                 fi
161                 gcc-config ${mythang}; update_env_settings
162         fi
163 }
164
165 setup_binutils(){
166         if [ -x /usr/bin/binutils-config ]
167         then
168                 mythang=$( cd /etc/env.d/binutils; ls ${clst_CHOST}-* | head -n 1 )
169                 if [ -z "${mythang}" ]
170                 then
171                         mythang=1
172                 fi
173                 binutils-config ${mythang}; update_env_settings
174         fi
175 }
176
177 cleanup_distcc() {
178         rm -rf /etc/distcc/hosts
179         for i in cc gcc c++ g++; do
180                 # TODO: change to use get_libdir
181                 rm -f /usr/lib/distcc/bin/${i}
182                 ln -s /usr/bin/distcc /usr/lib/distcc/bin/${i}
183         done
184         rm -f /usr/lib/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         if [ -n "${clst_DISTCC}" ]
198         then
199                 cleanup_distcc
200         fi
201         if [ -n "${clst_ICECREAM}" ]
202         then
203                 cleanup_icecream
204         fi
205         case ${clst_target} in
206                 stage1|stage2|stage3)
207                         rm -f /var/lib/portage/world
208                         touch /var/lib/portage/world
209                         ;;
210                 *)
211                         echo "Skipping removal of world file for ${clst_target}"
212                         ;;
213         esac
214
215         rm -f /var/log/emerge.log /var/log/portage/elog/*
216         rm -rf /var/tmp/*
217 }
218
219 update_env_settings(){
220         which env-update > /dev/null 2>&1
221         ret=$?
222         if [ $ret -eq 0 ]
223         then
224                 ENV_UPDATE=`which env-update`
225                 ${ENV_UPDATE}
226         else
227                 echo "WARNING: env-update not found, skipping!"
228         fi
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         if  [ "${1}" = "" ]
240         then
241                 export ROOT=/
242         else
243                 export ROOT=${1}
244                 if [ ! -d ${ROOT} ]
245                 then
246                         install -d ${ROOT}
247                 fi
248         fi
249 }
250
251 run_emerge() {
252         # Sets up the ROOT= parameter
253         # with no options ROOT=/
254         make_destpath ${clst_root_path}
255         
256         export EMERGE_WARNING_DELAY=0   
257         export CLEAN_DELAY=0
258         export EBEEP_IGNORE=0
259         export EPAUSE_IGNORE=0
260         export CONFIG_PROTECT="-*"
261
262         if [ -n "${clst_VERBOSE}" ]
263         then
264                 echo "ROOT=${ROOT} emerge ${clst_myemergeopts} -pt $@" || exit 1
265                 emerge ${clst_myemergeopts} -pt $@ || exit 3
266                 echo "Press any key within 15 seconds to pause the build..."
267                 read -s -t 15 -n 1
268                 if [ $? -eq 0 ]
269                 then
270                         echo "Press any key to continue..."
271                         read -s -n 1
272                 fi
273         fi
274
275         echo "emerge ${clst_myemergeopts} $@" || exit 1
276
277         emerge ${clst_myemergeopts} $@ || exit 1
278 }
279
280 show_debug() {
281         if [ "${clst_DEBUG}" = "1" ]
282         then
283                 unset PACKAGES
284                 echo "DEBUG:"
285                 echo "Profile/target info:"
286                 echo "Profile inheritance:"
287                 python -c 'import portage; print portage.settings.profiles'
288                 echo
289                 echo "STAGE1_USE:            $(portageq envvar STAGE1_USE)"
290                 echo
291                 echo "USE (profile):         $(portageq envvar USE)"
292                 echo "USE (stage1):          ${USE}"
293                 echo "FEATURES (profile):    $(portageq envvar FEATURES)"
294                 echo "FEATURES (stage1):     ${FEATURES}"
295                 echo
296                 echo "ARCH:                  $(portageq envvar ARCH)"
297                 echo "CHOST:                 $(portageq envvar CHOST)"
298                 echo "CFLAGS:                $(portageq envvar CFLAGS)"
299                 echo
300                 echo "PROFILE_ARCH:          $(portageq envvar PROFILE_ARCH)"
301                 echo
302                 echo "ABI:                   $(portageq envvar ABI)"
303                 echo "DEFAULT_ABI:           $(portageq envvar DEFAULT_ABI)"
304                 echo "KERNEL_ABI:            $(portageq envvar KERNEL_ABI)"
305                 echo "MULTILIB_ABIS:         $(portageq envvar MULTILIB_ABIS)"
306                 echo
307                 ### XXX: This is temporary until we make --debug force-enable --verbose
308                 if [ -n "${clst_buildpkgs}" ]
309                 then
310                         PACKAGES=${clst_buildpkgs}
311                 elif [ -n "${clst_packages}" ]
312                 then
313                         PACKAGES=${clst_packages}
314                 fi
315                 if [ -n "${PACKAGES}" ]
316                 then
317                         echo "Packages:"
318                         echo "${PACKAGES}"
319                         echo
320                 fi
321                 ### XXX: end of section to remove
322         fi
323 }
324
325 run_default_funcs() {
326         if [ -z "${RUN_DEFAULT_FUNCS}" ]
327         then
328                 update_env_settings
329                 setup_myfeatures
330                 show_debug
331         fi
332 }
333
334 # Functions
335 # Copy libs of a executable in the chroot
336 function copy_libs() {
337         # Check if it's a dynamix exec
338         ldd ${1} > /dev/null 2>&1 || return
339
340         for lib in `ldd ${1} | awk '{ print $3 }'`
341         do
342                 echo ${lib}
343                 if [ -e ${lib} ]
344                 then
345                         if [ ! -e ${clst_root_path}/${lib} ]
346                         then
347                                 copy_file ${lib}
348                                 [ -e "${clst_root_path}/${lib}" ] && \
349                                 strip -R .comment -R .note ${clst_root_path}/${lib} \
350                                 || echo "WARNING : Cannot strip lib ${clst_root_path}/${lib} !"
351                         fi
352                 else
353                         echo "WARNING : Some library was not found for ${lib} !"
354                 fi
355         done
356 }
357
358 function copy_symlink() {
359         STACK=${2}
360         [ "${STACK}" = "" ] && STACK=16 || STACK=$((${STACK} - 1 ))
361
362         if [ ${STACK} -le 0 ] 
363         then
364                 echo "WARNING : ${TARGET} : too many levels of symbolic links !"
365                 return
366         fi
367
368         [ ! -e ${clst_root_path}/`dirname ${1}` ] && \
369                 mkdir -p ${clst_root_path}/`dirname ${1}`
370         [ ! -e ${clst_root_path}/${1} ] && \
371                 cp -vfdp ${1} ${clst_root_path}/${1}
372         
373         if [[ -n $(type -p realpath) ]]; then
374                 TARGET=`realpath ${1}`
375         else
376                 TARGET=`readlink -f ${1}`
377         fi
378         if [ -h ${TARGET} ]
379         then
380                 copy_symlink ${TARGET} ${STACK}
381         else
382                 copy_file ${TARGET}
383         fi
384 }
385
386 function copy_file() {
387         f="${1}"
388
389         if [ ! -e "${f}" ]
390         then
391                 echo "WARNING : File not found : ${f}"
392                 continue
393         fi
394
395         [ ! -e ${clst_root_path}/`dirname ${f}` ] && \
396                 mkdir -p ${clst_root_path}/`dirname ${f}`
397         [ ! -e ${clst_root_path}/${f} ] && \
398                 cp -vfdp ${f} ${clst_root_path}/${f}
399         if [ -x ${f} -a ! -h ${f} ]
400         then
401                 copy_libs ${f}
402                 strip -R .comment -R .note ${clst_root_path}/${f} > /dev/null 2>&1
403         elif [ -h ${f} ]
404         then
405                 copy_symlink ${f}
406         fi
407 }
408
409 create_handbook_icon() {
410         # This function creates a local icon to the Gentoo Handbook
411         echo "[Desktop Entry]
412 Encoding=UTF-8
413 Version=1.0
414 Type=Link
415 URL=file:///mnt/cdrom/docs/handbook/html/index.html
416 Terminal=false
417 Name=Gentoo Linux Handbook
418 GenericName=Gentoo Linux Handbook
419 Comment=This is a link to the local copy of the Gentoo Linux Handbook.
420 Icon=text-editor" > /usr/share/applications/gentoo-handbook.desktop
421 }