howtomake

скрытый потенциал ручных сборок

крис касперски аргентинский болотный бобер nezumielratonaka нутряк ибн мыщъх, no-email

UNIX-программистам свойственно не зажимать исходники и подавляющее большинство программ распространяются именно так, однако, народ тяготеет к готовым бинарным сборкам, зачастую даже не догадываясь каких возможностей он оказывается лишен! многие пользователи перекомпилируют программы, но немногие делают это правильно! ручная сборка — достаточно сложный, взаимно противоречивый и неочевидный процесс, который мы сейчас попробуем заточить

Зачем мучаться, собирая программу руками (а как же зубами и хвостом), если можно просто скачать готовую бинарную сборку, ведь править исходные тексты большинство из нас все равно не собирается. Вот топ основных причин, по которым исходные тексты лучше готовых дистрибутивов:

  1. сборки есть не для всех платформ (в основном это касается x86-64 и экзотических осей типа QNX или BeOS);
  2. для текущих версий сборки практически всегда отсутствуют, а релизы выходят нечасто, вынуждая нас использовать версию одно-двух годичной давности (и это далеко не преувеличение!), с завистью поглядывая на коллег, собравших последнюю альфу с кучей всяких вкусностей и нововведений;
  3. готовые сборки включают в себя не все фичи, реализованные в исходных текстах (в частности, в состав популярного эмулятора BOCHS входит внешний интерактивный отладчик в стиле Turbo Debugger, в то время как официальные сборки содержат простейший интегрированный отладчик, типа debug.com);
  4. для многих программ существуют расширения, созданные сторонними разработчиками, и устанавливаемые только посредством перекомпиляции;
  5. готовая сборка зачастую включает много лишних компонентов, которые только жрут процессорные ресурсы и память, но лично нам ни хрена не нужны (в частности, программа может поддерживать консольный и графический интерфейсы, и если мы, горячие поклонники командной строки, не собираемся использовать X'ы, то перекомпилировать программу без поддержки GUI сам Джа велел);
  6. официальные сборки компилируются с типовыми опциями оптимизации, общими для всех процессоров, в результате чего код получается неэффективным и неоптимальным или даже вообще неработающим (на старых процессорах типа 80386 или 80486);
  7. при выходе новой версии, всю сборку приходится заново скачивать целиком, вместо того, чтобы забрать только измененные файлы (а для часто обновляемых программ это актуально);
  8. если программа содержит уязвимость, атаковать готовую сборку проще, поскольку хакер знает точное расположение всех машинных команд и раскладку памяти;
  9. заплатки к исходным текстам выходят намного быстрее и чаще, чем к бинарным сборкам (зачастую бинарные сборки не патчатся вообще и приходится скачивать весь «залатанный» дистрибутив целиком);
  10. пользоваться готовыми сборками это не unix-way и совсем не по-хакерски;

Рисунок 1 официальная сборка BOCHS'а не поддерживает x86-64 процессоров и 64-битная версия LINIX'а грустно говорит «sorry, yourCPUisnotcapableofrunning 64-bitkernel» и выпадает в systemhalted

Рисунок 2 после перекомпиляции с ключом «–enable-x86-64» LINUX запускается как из пушки, ухитрясь работать с приличной скоростью даже из-под VM Ware, запущенной на позорном Pentium-III 733

А вот теперь приведем топ основных причин, по которым готовые сборки лучше исходных текстов:

  1. готовая сборка «весит» намного легче исходных текстов, даже сжатых самым лучшим архиватором. к чему нам лишний трафик? особенно достается владельцам медленных dial-up соединений, тем более, что докачку поддерживают далеко не все сервера;
  2. в разархивированном виде исходные тексты занимают очень много места (зачастую, сотни мегабайт), а сама компиляция требует значительного времени, которое, как известно, всегда работает против нас;
  3. «ручная» настройка программы «под себя» требует внимательного чтения мануалов (изучения конфигурационных скриптов), а сборка с опциями по умолчанию в лучшем случае ничем не отличается от официальной сборки, если не сказать хуже;
  4. часто требуется скачивать дополнительные заголовочные файлы и библиотеки, обновлять компилятор etc, что опять-таки требует времени, трафика и дискового пространства, которое не безгранично и тает со скоростью, намного превышающей всеми критикуемую Windows;
  5. качество автоматических инсталляторов в большинстве своем оставляет желать лучшего и скомпилированную программу еще долго приходится дорабатывать напильником, руками, хвостом и головой;
  6. готовые сборки обычно включают в себя «бонусы» типа нестандартных цветовых схем и прочих компонентов, созданных сторонними разработчиками, которых в официальных исходных текстах может и не быть;
  7. существует тысяча причин, по которым собранная «вручную» программа может работать неправильно или нестабильно, например, пользователь активировал «соблазнительную» опцию, находящуюся в стадии «underconstruction» и приводящую к появлению глюков в самых неожиданных местах;
  8. программы, собранные из исходников, значительно труднее удалить из системы, чем rpm-пакет (впрочем, существуют утилиты, автоматизирующие этот процесс);
  9. если необходимые нам опции отсутствуют в официальной сборке (например, поддержка x86-64 в BOCHS), практически всегда можно найти неофициальную сборку, в которой все это сделано за нас, правда, далеко не все неофициальные сборки собраны правильно;
  10. пословица «лучше за день долететь, чем за час добежать» в условиях сурового корпоративного мира неприменима и если готовая сборка гарантированно хоть как-то работает, то эксперименты с ручной компиляцией «за просто так» нам никто не оплатит;

Рисунок 3 графическая «морда» к интегрированному BOCHS-отладчику, входящая в одну из неофициальных сборок

Универсального решения нет! Каждый путь содержит свои минусы и плюсы. Мыщъх рекомендует: сначала скачать готовую сборку, немного поработать с программой, разобраться в структуре каталогов, освоиться с основными возможностями… И только потом уже приступать к экспериментам. По крайней мере, правильно собранный эталон всегда будет перед глазами и если компиляция пойдет наперекосяк (или собранная программа откажет в работе) он поможет установить, что мы делаем не так и в каком направлении вращать хвостом.

Собственно говоря, ручная сборка доступна любому продвинутому пользователю, имеющего минимальный опыт общения с компиляторами, достаточное количество свободного времени и умение читать по-английски без помощи переводчиков.

Компиляция программы всегда начинается с чтения инструкции. Заходим на головной сайт, находим где у них download, скачиваем change-log (changes, what's new, readme) и вдумчиво читаем: чем отличается наша версия от этой и нужны ли нам все эти нововведения или нет? Практика показывает, что большинство программ останавливаются в своем развитии еще в зачатии, а затем «жиреют», наращивая избыточную функциональность, двигаясь по пути Microsoft. Взять хотя бы такую штуку как нож. При желании к нему можно прикрутить штопор, ножницы и даже фонарь! Образуется чудовищное орудие труда, которое хреново режет, еще хуже светит, зато очень внушительно выглядит. На фиг! Не будем гнаться за модой и прогрессом, стремясь использовать последние версии программ, только потому, что они «последние». Машинный код в отличии от молока со временем не портиться и не скисает, а хакеры, в отличии от юзеров, намного более консервативны и с большим недоверием относятся ко всему новому. Как сказал кто-то из них «я не могу работать инструментом, который совершенствуется у меня в руке».

Программа — это не игрушка! Это — инструмент! Даже небольшие изменения интерфейса или особенностей поведения приводят к жутким неудобствам и снижению производительности труда. Хороший хакер работает с клавиатурой как заправский пианист — пальцы так и летают. Все движения заучены наизусть и переучиваться во имя новой версии никто не будет, если кончено, эта версия не содержит чего-то действительно очень сильно необходимого.

Пользователи в этом отношении намного более прогрессивны и качают все, что только попадает в поле их зрения. Существует предубеждение, что лучше всего скачивать стабильные ветви (stable) так же называемые релизами (release), дескать, они работают намного надежнее экспериментальных альфа/бета-версий. Какая-то доля правды в этом есть, но в общем случае, дела обстоят совсем не так. Стабильные версии выходят редко. За это время в них находятся баги, планомерно устраняемые в промежуточных версиях, носящих статус «нестабильных». В перерывах между схватках с багами, разработчики добавляют новые функциональные возможности (или расширяют уже существующие), например, поддерживают передовые протоколы передачи данных или форматы файлов. Какой смысл ждать релиза, когда текущую версию можно скачать прямо сейчас? К тому же, чем больше людей «подсядут» на альфу, тем больше ошибок будет в ней обнаружено! Не стоит надеяться, что другие сделают эту работу за вас! В отличии от Microsoft, разработчики бесплатных программ не могут содержать бригаду бета-тестеров, поэтому, с ошибками вынуждены сражаться сами пользователи. Впрочем, никакого произвола тут нет. Не хотите — не сражайтесь.

Исходные тексты обычно распространяются в архивах, упакованных популярными архиваторами типа pkzip, gzip, bzip, реже — в виде CVS-дерева. А это что еще за хрень? Это, братья мои, — одна из самых популярных систем управления версиями (Concurrent Version System), позволяющая нескольким программистам работать над одним проектом. Система не только отслеживает изменения, синхронизуя файлы всех участников, но еще и разграничивает привилегии — кто и куда может писать. Чем больше команда, тем чаще разборки типа «какая сволочь трогала мой файл и весь вытрогала?». Посторонние лица (анонимные пользователи, не участвующие в проекте) могут только читать.

Чтобы работать с CVS-деревом необходимо установить CVS-клиента (в большинстве UNIX-дистрибутивов он уже установлен), подрубившись к системе под anonymous'ом. В общем случае это делается так: «$cvs -d:pserver:anonymous@server:patch login». На всякий случай ниже приведен конкретный пример, скачивающий CVS-дерево эмулятора BOCHS:

$ cvs -d:pserver:anonymous@cvs.bochs.sourceforge.net:/cvsroot/bochs login

(Logging in to anonymous@cvs.bochs.sourceforge.net)

CVS password: (there is no password, just press Enter)

user$ cvs -z3 -d:pserver:anonymous@cvs.bochs.sf.net:/cvsroot/bochs checkout bochs

cvs server: Updating bochs

U bochs/.bochsrc

U bochs/.conf.AIX.4.3.1

U bochs/.conf.beos-x86-R4

U bochs/.conf.macos

.

. (This might take a few minutes, depending on your network connection.)

.

U bochs/patches/patch.seg-limit-real

Листинг 1 сеанс работы с cvs-сервером на примере BOCHS

Если подключение к серверу завершилось успешно, сразу же после авторизации, начинается процедура checkout'а, то есть синхронизация файлов. Ну нам синхронизовать пока что нечего… вот и приходится скачивать все файлы проекта, что даже на выделенных линиях занимает до фига времени. Файлы передаются в несжатом (точнее очень слабо сжатом) виде и докачка поддерживается лишь частично: файлы скаченные целиком при неожиданном разрыве связи повторно не передаются, но незаконченные файлы начинают скачиваться сначала. При частых разрывах связи это создает жуткий напряг, сопровождаемый традиционным матом, к тому же CVS дерево содержит много лишней «дряни», не попадающий в «упакованный дистрибутив», но мы вынуждены ее качать…

Рисунок 4 многие серверы (в том числе и www.sourceforge.net) позволяют просматривать CVS-дерево через WEB-интерфейс, однако, особого смысла в этом нет и чтобы скачать исходные файлы потребуется штука типа Teleport Pro, так что лучше установить себе CVS-клиента и не мучаться

Так какой же тогда смысл возиться с CVS? Не проще ли (быстрее, дешевле) воспользоваться готовым архивом? Однозначного ответа на вопрос нет и не будет. Начнем с того, что некоторые программы распространяются только через CVS. Архив, если и выкладывается, зачастую содержит не все файлы или не обновляется месяцами. С другой стороны, при выходе новой версии, весь архив приходится перекачивать от начала и до конца (а это очень много мегабайт), в то время как CVS-клиент забирает только реально измененные файлы, что существенно экономит трафик.

Короче говоря, при частных обновлениях, выгодно использовать CVS, в противном случае, лучше скачать готовый архив, выбрав из предложенных архиваторов свой любимый. (Между прочим, даже при отсутствии прав на запись, CVS-клиент все равно отслеживает изменение локальных файлов и если мы что-то подправили в программе, измененные файлы останутся не обновленными!).

При желании скачать стабильную (а не текущую!) версию мы должны использовать ключ «-r» и тогда командная строка будет выглядеть так: «$cvs update -d -r tagname», где tagname — кодовое имя проекта (например, «REL_2_0_2_FINAL»), название которого можно найти на сайте разработчиков или почерпнуть из документации.

Последнюю версию самого CVS-клиента можно скачать с «гнутого» ftp-сервера http://ftp.gnu.org/non-gnu/cvs/ (http://www.tortoisecvs.org/, http://www.wincvs.org/ — версии под Windows), а если возникнут какие-то вопросы — к вашим услугам огромный faq: http://www.cs.utah.edu/dept/old/texinfo/cvs/FAQ.txt. На этом, разбор полетов с CVS будем считать законченным и займемся готовыми архивами.

Рисунок 5 архив исходных текстов браузера Lynx в различных версиях и форматах

Значит, архивы. Обычно их бывает много, если не больше того! Страничка дистрибьюции Рыся (http://lynx.isc.org/current/index.html) насчитывает с полсотни файлов в трех форматах: pkzip, gzip и bzip. Какой из них брать? Самый расточительный — pkzip, за ним с небольшим отрывом идет gzip (по сути дела представляющий той же самый архиватор, но в другой «инкоронации»), bzip лидирует с 1,5 — 2 кратным разрывом, правда не во всех дистрибутивах он установлен по умолчанию и тогда его приходится качать самостоятельно: http://www.bzip.org/, благо он бесплатен.

4550647 Oct 30 12:54 [26]lynx2.8.6dev.15.tar.Z

2259601 Oct 30 12:54 [27]lynx2.8.6dev.15.tar.bz2

3141568 Oct 30 12:54 [28]lynx2.8.6dev.15.tar.gz

3344962 Oct 30 12:54 [29]lynx2.8.6dev.15.zip

Листинг 2 исходные тексты, упакованные различными архиваторами, имеют сильно неодинаковый размер

Скачав архив, поинтересуйтесь, а не прилагается ли к нему патч с последними исправлениями? Версия патча обязательно должна совпадать с версией архива, иначе образуется каша и программа рухнет еще на стадии компиляции. Впрочем, это не правило, а скорее рекомендация. Это смотря какой патч и что он исправляет. Тем не менее, без необходимости лучше не рисковать.

Патчи бывают разных видов. Например, в случае с Рысем — это обыкновенный архив измененных файлов, который нужно просто взять и распаковать (с перезаписью) в основной каталог программы, и который по своему размеру вплотную приближается к дистрибутиву, что не есть хорошо, зато у пигвистов никаких вопросов не возникает.

Рисунок 6 diff-патч, прилагаемый к архиву исходных текстов

Большинство программистов создают патчи с помощью утилиты diff (см. man diff), получившей свое название в результате сокращения английского difference – разница. Эта штука построчено сравнивает файлы, отображая только реальные изменения. Знак «-», стоящий впереди, означает, что данная строка была удалена, а «+« – добавлена. Имя файла предваряется тройным »—»/«+++» и, как правило, все изменения дистрибутива собраны в одном diff'e. Файлы изменений обычно имеют расширение .diff или .patch, но даже без расширения их легко отождествить визуально (см. листинг 3):

diff -pruN biew-561/biewlib/sysdep/ia32/os2/timer.c biew-562/biewlib/sysdep/ia32/os2/timer.c

— biew-561/biewlib/sysdep/ia32/os2/timer.c2001-11-18 17:05:48.000000000 +0000

+++ biew-562/biewlib/sysdep/ia32/os2/timer.c2004-09-20 19:34:11.000000000 +0000

@@ -29,7 +29,7 @@ static HTIMER timerID = 0;

static TID timerThread = 0;

static timer_callback *user_callback = NULL;

-static VOID NORETURN thread_callback( ULONG threadMsg )

+static VOID NORETURN _Syscall thread_callback( ULONG threadMsg )

{

ULONG recv;

UNUSED(threadMsg);

Листинг 3 так выглядит патч, созданный утилитой diff

Наложить diff-патч можно, в принципе, и вручную. Некоторые так и парятся. Другие — используют утилиту patch (см. man patch), полностью автоматизирующий этот процесс. В общем случае, ее вызов выглядит так:

$patch -p1 < my_patch.patch

Листинг 4 наложение патча утилитой patch

Здесь, «my_patch.patch» – имя diff-файла, а «p1» – уровень вложенности. Номер <1> означает, что мы вызываем patch из основного каталога программы. Зачем это нужно? Откроем diff-файл в любом редакторе и посмотрим каким образом в нем задаются пути к файлам: «biew-561/biewlib/sysdep/ia32/os2/timer.c». Ага, путь начинается с «biew-561» — каталога, в который должна быть распакована подопытная программа. Но можем же мы переименовать его? Не знаю как вас, а вот лично меня цифры «561» очень раздражают и вообще мыщъх предпочитает короткие имена в стиле «bw». Ключ «-p1» заставляет утилиту patch игнорировать первое слева имя в цепочке, и тогда путь начинается с «/biewlib», при этом естественно, каталог «biew-561» (или как мы там его назовем) должен быть текущим. Если же мы накладываем patch извне каталога «biew-561», необходимо указать «-p0». Отсутствие ключа «-p» приводит к полному игнорированию путей и все файлы ищутся в текущем каталоге, где их, естественно, нет!

Установка патча — обратимая операция и при желании его можно удалить, воспользовавшись ключом «-R», возвращающим все измененные строки на место. Так же обратите внимание на ключ «-b», создающий резервные копии измененяемых файлов.

Иногда, к одной версии прилагается сразу несколько патчей, серьезно озадачивающих даже бывалых пользователей. Внимательно прочитайте описание: в каком порядке их следует устанавливать! Если же описание отсутствует — смотрите на изменения и разбирайтесь с порядком наложения самостоятельно или же вовсе откажитесь от установки. (По одной из версий Чернобыльская АС взорвалась в результате небрежно спланированного эксперимента, когда в инструкции, описывающей порядок действия оператора, было исправлено, зачеркнуто, и поверх зачеркнутого написано опять, вот оператор и растерялся…).

В экзотических случаях патч представляет собой скрипт, выполняющий все изменения самостоятельно.

Многие разработчики прилагают к архивам цифровые подписи типа PGP или эталонные контрольные суммы. Теоретически это позволяет предотвратить возможное искажение информации или подделку. Современные архиваторы контролируют целостность данных самостоятельно, а от преднамеренного взлома никакая цифровая подпись не спасет! Так что решайте сами — использовать их или нет, а мы приступаем к главному — к компиляции.

В среде пингвинистов бытует мнение, что если программа не собирается «стандартным» путем (см. листинг 5), это неправильная программа, и работать она будет неправильно, поэтому будет лучше не мучаться, отправить ее в /dev/nul и пересесть на альтернативу. На самом деле, неправильных пингвинистов гораздо больше, чем неправильных программ!

$./configure

$make

$make install

Листинг 5 типовой порядок сборки большинства программ

Начнем с того, что в отличии от мира Windows, где программа устанавливается/собирается путем запуска setup.exe или nmake.exe, в UNIX процесс сборки начинается… с чтения документации! Читать документацию обязательно! Даже если сборка с настройками по умолчанию пройдет без сучка и задоринки, полученная конфигурация навряд ли будет оптимальной.

Обычно к исходным текстам прилагается файл install, readme или что-то типа того. Если же ничего подобного в архиве нет (как в случае в BOCHS) ищите инструкцию по сборке на головном сайте. В клинических случаях инструкция находится внутри файлов configure и makefile.

Файл configure представляет собой достаточно сложный скрипт, анализирующий текущую конфигурацию, распознающий платформу, определяющий наличие всех необходимых библиотек и управляющий опциями сборки (какие фичи включать, а какие не надо). Результатом его работы становится сгенерированный makefile, который и собирает (компилирует, линкует) программу воедино.

Рисунок 7 конфигуратор за работой

Некоторые конфигураторы имеют продвинутый интерфейс и работают в интерактивном режиме, но это не правило, а скорее приятное исключение. Гораздо чаще опции сборки задаются через ключи командой строки или даже путем правки самого конфигурационного файла!!!

Самая важная опция компиляции — это платформа. Под UNIX-системами она в большинстве случаев распознается автоматически и никаких граблей не возникает, но вот при сборке под MacOS, BeOS, QNX, win32 нас могут встретить большие проблемы. И хотя разработчики стремятся обеспечить максимальную переносимость, на практике все происходит совсем не так. Больше всего страдают Windows-пользователи: эта платформа не поддерживает shell-скриптов и конфигуратор там не работает. Даже если разработчик предусмотрел возможность компиляции под win32, управлять опциями проекта приходится вручную, путем правки make-файла, а для этого еще необходимо разобраться какая строка за что отвечает. Положение частично спасает cygwin (если, конечно, он установлен), но проблемы все равно остаются. Windows это вам не UNIX! Инструкцию по сборке читать от начала и до конца! Даже если мы собираем программу с помощью MicrosoftVisualC++, нужная нам информации вполне может оказаться в разделе BorlandBuilder или совсем в другом месте.

Рисунок 8 опции сборки эмулятора BOCHS – по умолчанию большинство из них выключено

Остальные опции уже не столь решающе, но и к второстепенным их не отнесешь. Сборка с настойками по умолчанию гарантирует, что программа соберется правильно и, может быть, даже заработает, однако… поддержки нужных нам режимов там может и не быть. В частности, уже не раз упомянутый BOCHS по умолчанию собирается без эмуляции SoundBlaster'а, без сетевой карты, без see/mxx, без x86-64, без интегрированного отладчика и без оптимизации скорости выполнения виртуального кода (см. рис. 8). Вот такой ущербный эмулятор получается! Можно, конечно, бездумно активировать все опции, но по любому это не лучшая идея. Во-первых, многие опции конфликтуют друг с другом, а во-вторых, дополнительные компоненты не только увеличивают размер откомпилированного файла, но зачастую и замедляют скорость работы программы. Поэтому, составляя «меню», необходимо быть очень внимательным и предусмотрительным. Помните анекдот про того парня, что обнаружил дохлую ворону и кинул в телегу: авось пригодится? Вот так же и тут.

В частности, заставить BOCHS поддерживать x86-64 вместе с интегрированным отладчиком можно так:

$./configure –enable-x86-64 –enable-debugger

Листинг 6 задание опций сборки посредством командной строки

А что делать, если в документации никакого упоминания о сборочных опциях вообще нет (или у нас терзают смутные сомнения, что это описание неполное)? Тогда — открываем configure в своем любимом текстовом редакторе и смотрим опции «прямым текстом». Если нам повезет рядом с ними будут и комментарии (см. листинг 7). Как вариант, можно набрать «$./configure –help» — авось что-то мяукнет в ответ.

–enable-processors select number of processors (1,2,4,8)

–enable-x86-64 compile in support for x86-64 instructions

–enable-cpu-level select cpu level (3,4,5,6)

–enable-apic enable APIC support

–enable-compressed-hd allows compressed zlib hard disk image (not implemented yet)

–enable-ne2000 enable limited ne2000 support

–enable-pci enable limited i440FX PCI support

–enable-pcidev enable PCI host device mapping support (linux host only)

–enable-usb enable limited USB support

–enable-pnic enable PCI pseudo NIC support

Листинг 7 фрагмент файла configure с опциями сборки

Некоторые программы (например, hex-редактор biew) вообще не имеют configure-файла. Это значит, что настраивать программу приходится вручную, путем редактирования makefile. Звучит намного сложнее чем выглядит. Структура makefile довольно проста и фактически представляет собой последовательность команд и переменных. Вот переменными-то мы и будем управлять! Перечень возможных значений обычно содержится тут же, в комментариях.

Рисунок 9 конфигурирование программы посредством правки make-файла

# Please select target platform. Valid values are:

# For 16-bit Intel: i86 i286 ( still is not supported by gcc )

# For 32-bit Intel

# basic : i386 i486

# gcc-2.9x : i586 i686 p3 p4 k6 k6_2 athlon

# pgcc : i586mmx i686mmx p3mmx p4mmx k5 k6mmx k6_2mmx 6×86 6x86mmx

# athlon_mmx

# Other platform : generic

#—————————————————————————–

TARGET_PLATFORM=i386

# Please select target operation system. Valid values are:

# dos, os2, win32, linux, unix, beos, qnx4, qnx6

#———————————————————

TARGET_OS=unix

# Please add any host specific flags here

# (like -fcall-used-R -fcall-saved-R -mrtd -mregparm=3 -mreg-alloc= e.t.c ;-):

#——————————————————————————

# Notes: You can also define -DEXPERIMENTAL_VERSION flag, if you want to # build experimental version with fastcall technology. # * # You can also define: # -DHAVE_MMX mostly common for all cpu since Pentium-MMX and compatible # -DHAVE_MMX2 exists on K7+ and P3+ # -DHAVE_SSE exists only on P3+ # -DHAVE_SSE2 exists only on P4+ # -DHAVE_3DNOW exists only on AMD's K6-2+ # -DHAVE_3DNOWEX exists only on AMD's K7+ # * # -DDISABLE_ASM disables all inline assembly code.

# Try it if you have problems with compilation due to assembler errors.

# Note that it is not the same as specifying TARGET_PLATFORM=generic.

#——————————————————————————

HOST_CFLAGS=

Листинг 8 фрагмент make-файла с опциями и комментариями

Нужно заранее подготовить себя к тому, что часть переменных окажется привязанной к окружению автора (будет содержать абсолютные пути к целевым каталогам, включаемым файлам, библиотекам или т. д.) или же вовсе окажется не инициализирована и в этом случае мы будем должны задать их самостоятельно. Некоторые make-файлы управляются через переменные окружения, которые опять-таки нам необходимо задать перед компиляцией.

PDCURSES_HOME=$(PDCURSES_SRCDIR)

Листинг 9 фрагмент make-файла, управляемого через переменные окружения

И вот торжественный момент! Все пиво выпито, все лошади запряжены, все опции настроены и мы с замираем сердца пишем «$make». Процесс сборки начался! Можно смело сушить траву, дербанить грибы и кайфовать, ибо компиляция длиться очень долгое время. Достаточно часто она прерывается с сообщением об ошибке. Что делать? Главное — не паниковать, а прочитать «ругательное» сообщение, перевести его на русский язык и проанализировать. Чаще всего программе не хватает какой-то библиотеки или заголовочного файла. Вообще-то, это должен быть выявить конфигуратор (если только он есть), но скачать недостающие компоненты при наличии интернета — не проблема. Знать бы только что именно надо скачать! К сожалению, далеко не всегда makefile сообщает «официальное» название библиотеки. Чаще всего нам просто говорят: отсутствует файл super-puper-zip.h или как его там. Не беда! Запускаем поисковик, вводим имя файла и смотрим — какому пакету он принадлежит и откуда его можно download'ть Так же неплохо сходить на форум поддержки или просто «закинуть» сообщение об ошибке в google. Ведь не одни же мы с ней столкнулись! А раз так, этот вопрос должен обсуждаться на различных форумах, которые наверняка дадут нам ответ. Если это не поможет — читаем документацию еще раз, обращая внимания на то, какие библиотеки и системные компоненты должны быть установлены или пробуем проиграться с опциями сборки, отключая все, что только можно отключить.

Хуже, когда сталкиваешься с грубыми ошибками самих разработчиков. Ведь make-файлы тоже люди пишут и далеко не на всех платформах их тестируют. Если так — попробуйте связаться с разработчиками (только хрен они вам ответ) или соберите программу на другой платформе (другим компилятором).

По умолчанию, программы, как правило, собираются с отладочной информацией, что существенно упрощает их отладку, но вместе с тем и увеличивает размер. Поскольку отладка чужих программ не входит в наши планы, отладочную информацию лучше убрать. Это можно сделать либо на стадии конфигурации: «$./configure –disable-debug», либо «вырезать» отладочную информацию из elf-файла «в живую», пропустив его через утилиту strip (входит в большинство UNIX-дистрибутивов). Но прежде, чем это делать, запустим программу file и посмотрим на обстоятельства дел.

Вот, например, BOCHS:

$file bochs

bochs: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.0,

dynamically linked (uses shared libs), not stripped

Листинг 10 BOCHS, собранный с настройками по умолчанию, содержит отладочную информацию

Ага, отладочная информация «notstripped», вот потому bochs занимает целых 9 мегабайт, что просто уродство:

$ls -l bochs

итого 15052

-rw-r–r– 1 root staff 138 2006-03-21 05:24 1

-rw-r–r– 1 root staff 0 2006-03-21 05:25 2

-rwxr-xr-x 1 root staff 9407192 2006-03-20 20:44 bochs

-rwxr-xr-x 1 root staff 36966 2006-03-20 20:44 bxcommit

-rwxr-xr-x 1 root staff 37697 2006-03-20 20:44 bximage

-rwxr-xr-x 1 root staff 5390592 2006-02-19 22:12 elinks

-rwxr-xr-x 1 root staff 488395 2006-02-19 21:58 js

Листинг 11 с отладочной информацией bochs занимает целых 9 мегабайт

Берем в руки скальпель и…

$strip bochs

Листинг 12 утилита strip удаляет отладочную информацию из файла

Файл сразу же худеет до 1 мегабайта, сокращая свой объем в девять (!) раз. Как говориться, почувствуйте разницу!

$file bochs

bochs: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.0,

dynamically linked (uses shared libs), stripped

$ls -l bochs

итого 6844

-rw-r–r– 1 root staff 138 2006-03-21 05:24 1

-rw-r–r– 1 root staff 399 2006-03-21 05:25 2

-rw-r–r– 1 root staff 0 2006-03-21 05:25 3

-rwxr-xr-x 1 root staff 1009368 2006-03-21 05:25 bochs

-rwxr-xr-x 1 root staff 36966 2006-03-20 20:44 bxcommit

-rwxr-xr-x 1 root staff 37697 2006-03-20 20:44 bximage

-rwxr-xr-x 1 root staff 5390592 2006-02-19 22:12 elinks

-rwxr-xr-x 1 root staff 488395 2006-02-19 21:58 js

Листинг 13 после «обрезания» bochs сразу же худеет до 1 мегабайта, причем без какой бы то ни было потери функциональности!

Рисунок 10 криво собранный biew конкретно лажает

Откомпилированная программа, как правило, еще не готова к работе. Нам предстоит еще много работы: удалить промежуточные файлы, созданные в процессе компиляции (библиотеки, объективные файлы), настроить конфигурационные файлы, рассовать файлы данных по своим директориями, а при необходимости — изменить системные настройки.

За это отвечает команда «$make install», однако, далеко не во всех программах она реализована, взять, например, хотя бы тот же biew:

install:

@echo Sorry! This operation should be performed manually for now!

@exit

Листинг 14 фрагмент make-файла из biew'а: автоматическая инсталляция не реализована

С другой стороны, автоматическая инсталляция — это рулетка. Все мы знаем, во что способен превратить систему кривой setup.exe. Поэтому, прежде чем набирать «$make install» неплохо бы заглянуть в makefile (раздел «install:») и посмотреть, что он собирается делать. Вдруг это нас не устраивает?

Попробуйте дать команду «$make uninstall», убирающую программу из системы — вдруг повезет? Однако, в подавляющем большинстве случаев она не реализована.

Существует такая полезная шутка как CheckInstall (http://checkinstall.izto.org/). Это бесплатно распространяемая утилита, трассирующая «$make install» на виртуальной машине и автоматически генерирующая полноценный «дистрибутив» любого типа: Slackware, RPM или Debiancompatiblepackage, устанавливаемый в систему соответствующим менеджером инсталляций, который всегда может сделать корректный uninstall, даже если он не был предусмотрен автором программы. Просто вместо «$make install» мы должны написать «$sudo checkinstall» и немного подождать…

Настоящие хакеры предпочитают устанавливать программу руками, используя готовую бинарную сборку как образец. Это самый надежный способ, однако, требующий времени и квалификации.

Кстати говоря, большинство инсталляторов помещают программы /usr/local/bin/, что не всем нравится. Правильные конфигураторы поддерживают ключ «–prefix», позволяющий устанавливать программы куда угодно (например, «$./configure –prefix=/usr»), неправильные заставляют нас это делать своими руками и хвостом. В общем, без траха никакое хорошее дело не обходится.

Вот, оказывается, какой сборка нетривиальный процесс! Чудес не бывает! Тупая перекомпиляция только вредит и работает намного хуже готовой «официальной» сборки. Ручная компиляция — это дверь в мир практически неограниченных возможностей, однако, попасть в него может только тот, кто не боится сложностей, готов совершать ошибки, умеет работать с документацией и движется вперед даже под проливным дождем.