Собираем bash, запускающийся где угодно.
Ну, если быть честным, то не совсем где угодно, а на любом дистрибутиве линукса. Возможно, так же заработает и на других *NIX системах, хотя я в этом и не уверен: проверить не на чем, а знание матчасти в этом отношении подкачало.
И так, наша цель собрать минималистичный bash свежей версии, без зависимостей и не требующий установки, чтобы потом запускать его с флешки или, как в моем случае, для выполнения скриптов для bash 4 в условиях CentOS 5.5, поставляющегося с ископаемым bash 3.2.
Кстати, только сегодня узнал, что на той неделе вышел CentOS 5.6, с более актуальными версиями софта, но в моем случае это ничего не меняет.
Для пущего осложнения жизни собирать будем 32-битный bash (чтобы запускался и на 32-х и на 64-х битах) в 64-битной Ubuntu.
Далее, пошаговые инструкции:
$ sudo apt-get install build-essential gcc-multilib
Это мы устанавливаем инструменты для сборки + библиотеки для кросс-компиляции под x86 (помним, что Ubuntu у нас x86_64 и компилятор в ней по дефолту тоже 64-битный).$ wget http://ftp.gnu.org/gnu/bash/bash-4.2.tar.gz && tar -xzf bash-4.2.tar.gz && cd cd bash-4.2/
Качаем и распаковываем исходники bash. Я привел ссылку на актуальную на момент написания этого поста версию, однако возможно, вам в будущем захочется bash 4.3 или даже 5.0 ;-)$ export CC="gcc -m32" CFLAGS="-m32"
Это и есть главная хитрость, необходимая для сборки 32-битного bash. То ли я не до конца разобрался, то ли у них Makefile корявый, но каждой из этих опций по отдельности недостаточно для сборки не под текущую архитектуру. Равно как и не работают параметры –host и –target у скрипта ./configure.$ ./configure --enable-static-link --without-bash-malloc
Конфигурируем сборку. Параметр –enable-static-link требует статически линковать исполняемый файл с необходимыми библиотеками, тем самым минимизируя зависимости, а –without-bash-malloc устраняет один не вполне понятный для меня конфликт при линковке. Так же возможно вам захочется добавить свои параметры, включив дополнительный функционал. В моем случае нужен был –enable-array-variables, ради которого все и затевалось.$ make
Собираем :-) Если у вас многоядерный процессор, можно добавить параметр -j N, где N - количество параллельных потоков сборки. Обычно его рекомендуют ставить равным удвоенному количеству реальных ядер. Кстати, в моем случае этот параметр существенно ускорил сборку, так что игнорировать его не стоит.
Если все шаги завершились успешно, то мы должны получить в текущем каталоге исполняемый файл bash, о котором утилита file должна говорить примерно следующее:
|
|
Обратите внимание на выделенные жирным фрагменты. Если они отличаются, то значит при сборке что-то пошло не так, и bash собрался 64-х битный, либо со внешними зависимостями.
Если хочется, можно немного уменьшить размер бинарника, сделав $ strip bash
.
У меня это дало экономию аж в 202365 байта.
Теперь этот файл можно копировать куда угодно и запускать, а он должен работать.