воскресенье, 25 марта 2012 г.

glibc downgrade

не удержался - поставил glibc-2.15
где профит, где регресс, где вообще пакет не собрать
потому решил откатить до 2.14, но меня ждал сюрприз - в вики допотопное непотребное нечто
во-первых там не всё что надо
во-вторых оно хочет бинарник
в-третьих слишком много телодвижений - то правь конфиг, то откатывай...
тьфу, короче
потому решил запилить скрипт, который сделает всё красиво
вот, собственно, и он
#!/bin/bash

[[ ${1} == "" ]] && echo -e "Usage: bash ${0} [VERSION] [ARCH] \nexample: bash ${0} 2.14.1-r2 32" && exit 1
[[ ${2} == "" ]] && echo -e "Usage: bash ${0} [VERSION] [ARCH] \nexample: bash ${0} 2.14.1-r2 32" && exit 1

AVAILABLE=`emerge -p glibc | awk '/sys-libs\/glibc/ {print $4}'`
[[ "${AVAILABLE/sys-libs\/glibc-/}" > "${1}" ]] && echo -e "you need mask:\n>sys-libs/glibc-${1}" && exit 1

##### find and define some stuff
export "$(emerge --info | grep 'PORTDIR=' | tr -d \")"
export "$(emerge --info | grep 'PORTAGE_TMPDIR=' | tr -d \")"
export "$(emerge --info | grep 'CFLAGS=' | tr -d \")"
export "$(emerge --info | grep 'CXXFLAGS=' | tr -d \")"
export "$(emerge --info | grep 'LDFLAGS=' | tr -d \")"

DIR="${PORTAGE_TMPDIR}/portage/sys-libs/glibc-${1}/image"

##### binary package for subj
quickpkg sys-libs/glibc

##### you need to make portage think that it has not installed glibc yet
rm -Rf /var/db/pkg/sys-libs/glibc-*

##### compile target glibc
ebuild ${PORTDIR}/sys-libs/glibc/glibc-${1}.ebuild install || exit 1

##### fix environment
case ${2} in
32 ) export LDFLAGS="-L${DIR}/lib -L${DIR}/usr/lib $LDFLAGS";;
64 ) export LDFLAGS="-L${DIR}/lib64 -L${DIR}/usr/lib64 -L${DIR}/lib32 -L${DIR}/usr/lib32 $LDFLAGS";;
esac

export CXXFLAGS="-I${DIR}/usr/include $CXXFLAGS"
export CFLAGS="-I${DIR}/usr/include $CFLAGS"

##### let's go
ALL_TARGETS="$(emerge -pve system | awk '/ebuild/ {print $4}' | grep -v libc | grep -v 'dev-lang/python' )"
for target in ${ALL_TARGETS};do
  export TARGETS+=" =${target}"
done

emerge -avO1 --keep-going=y ${TARGETS}

##### we need rebuild current python
VER="$(python -V 2>&1 | awk '{print $2}')"
CURRENT_PYTHON="$(ls -1 /var/db/pkg/dev-lang/ | grep python-${VER}*)"

ebuild ${PORTDIR}/dev-lang/python/${CURRENT_PYTHON}.ebuild clean configure

sed -e "s|BASECFLAGS=|BASECFLAGS= -I${DIR}/usr/include |" \
 -i ${PORTAGE_TMPDIR}/portage/dev-lang/${CURRENT_PYTHON}/work/Python-${VER}/Makefile

ebuild ${PORTDIR}/dev-lang/python/${CURRENT_PYTHON}.ebuild merge

##### unset previously defined vars
unset LDFLAGS CXXFLAGS CFLAGS 

##### workaround for glib/pkgconfig
FFI_VER="$(ls -1 /var/db/pkg/dev-libs/ | grep libffi)"

case ${2} in
32 ) export LIBFFI_LIBS="-L/usr/lib -lffi" && export LIBFFI_CFLAGS="-I/usr/lib/${FFI_VER}/include";;
64 ) export LIBFFI_LIBS="-L/usr/lib64 -L/usr/lib32/ -lffi" && export LIBFFI_CFLAGS="-I/usr/lib64/${FFI_VER}/include -I/usr/lib32/${FFI_VER}/include";;
esac

##### rebuild system
emerge -aveD --keep-going=y system
emerge -aveD --keep-going=y world
и так - что это такое:
1. пара проверок - защит от дурака
2. вытаскиваем из окружения необходимое нам
3. на всякий случай делаем бинарный пакет для текущей версии glibc (даже в самой плохой ситуации tar или live+tar спасут)
4. собираем нужную нам версию, но ДО этапа установки в корень
5. кучка неких архитектурно(и не очень) зависимых фиксов некоторых переменных для того, чтобы мы могли использовать нужную нам версию для сборки системы
6. собственно пересобираем system, за исключением самой glibc, с нужной нам версией
все пакеты будут до упора пытаться собраться - для этого и стоит --keep-going=y
7. ну а далее...мы обнуляем переменные и собираем всю систему, включая саму glibc, как обычно
но добавляем фикс для рекурсии glib/pkgconfig

Использование: скрипт версия битность
например: ./glibc-downgrade 2.14.1-r2 32
версия обязательно полная - включая ревизию

после того, как скрипт отработает, естественно, прогнать
revdep-rebuild -i -- -avD
P.S. и никакой попаболи :3