$ patch -p1 < patch_file
16.6. Устранение проблем при компиляции и установке
Если вы усвоили различия между ошибками и предупреждениями компилятора, ошибками компоновщика и проблемами, связанными с совместно используемыми библиотеками, как рассказано в главе 15, у вас не должно возникнуть много сложностей при исправлении большинства глюков, которые возникают при сборке программ. Этот раздел описывает некоторые распространенные проблемы. Хотя маловероятно, что при использовании утилиты Autoconf вам встретится что-либо подобное, никогда не повредит узнать о том, как выглядят такие проблемы.
Прежде чем переходить к деталям, убедитесь в том, что вы понимаете некоторые типы сообщений утилиты make. Важно знать различия между ошибкой и проигнорированной ошибкой. Вот реальная ошибка, с которой вам необходимо разобраться:
make: *** [target] Error 1
Однако некоторые файлы Makefiles подозревают, что может возникнуть условие для какой-либо ошибки, но они знают, что такие ошибки безвредны. Обычно можно не обращать внимания на такие сообщения:
make: *** [target] Error 1 (ignored)
Команда GNU make часто вызывает себя многократно для больших пакетов, и каждый ее экземпляр отмечен в сообщениях об ошибках с помощью символов [N], где N является числом. Зачастую можно быстро отыскать ошибку, посмотрев на то сообщение об ошибке команды make, которое идет сразу после ошибки компилятора. Например:
[compiler error message involving file.c]
make[3]: *** [file.o] Error 1
make[3]: Leaving directory '/home/src/package-5.0/src'
make[2]: *** [all] Error 2
make[2]: Leaving directory '/home/src/package-5.0/src'
make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory '/home/src/package-5.0/'
make: *** [all] Error 2
Первые три строки практически выдают ее: проблема связана с файлом file.c, который расположен в каталоге /home/src/package-5.0/src. К сожалению, дополнительной информации так много, что бывает сложно найти важные детали. Выяснение того, как отфильтровать более поздние ошибки утилиты make, позволит отыскать настоящую причину.
Особые ошибки. Вот несколько распространенных ошибок сборки, которые могут вам встретиться.
Ошибка
Сообщение об ошибке компилятора:
src.c:22: conflicting types for 'item'
/usr/include/file.h:47: previous declaration of 'item'
Объяснение и устранение
Программист выполнил ошибочное повторное объявление элемента item в строке 22 файла src.c. Обычно это можно исправить, удалив ошибочную строку (с помощью комментария, директивы #ifdef или чего-либо подобного).
Ошибка
Сообщение об ошибке компилятора:
src.c:37: 'time_t' undeclared (first use this function)
—snip—
src.c:37: parse error before '...'
Объяснение и устранение
Программист забыл важный заголовочный файл. Страницы руководства лучше всего помогут в отыскании упущенного файла. Сначала посмотрите на ошибочную строку (в данном случае это строка 37 в файле src.c). Вероятно, она содержит объявление переменной вроде следующего:
time_t v1;
Отыщите в программе строку, в которой переменная v1 использует вызов какой-либо функции. Например, так:
v1 = time(NULL);
Теперь запустите команды man 2 time или man 3 time, чтобы отыскать системные и библиотечные вызовы с именем time(). В данном случае подходит второй раздел страницы руководства:
SYNOPSIS
#include <time.h>
time_t time(time_t *t);
Это означает, что вызову time() необходим файл time.h. Поместите строку #include <time.h> в начало файла src.c и попробуйте еще раз.
Ошибка
Сообщение об ошибке компилятора (препроцессора):
src.c:4: pkg.h: No such file or directory
(long list of errors follows)
Объяснение и устранение
Компилятор запустил препроцессор C для файла src.c, но не смог найти включаемый файл pkg.h. Исходный код, вероятно, зависит от библиотеки, которую необходимо установить, или же необходимо указать для компилятора нестандартный путь с включаемыми файлами. Как правило, вам понадобится лишь добавить параметр -I к флагам препроцессора C (CPPFLAGS), чтобы добавить этот путь. Помните о том, что может также понадобиться флаг компоновщика -L, чтобы использовать эти включаемые файлы.
Если ситуация не похожа на отсутствие библиотеки, есть незначительная вероятность того, что вы пытаетесь скомпилировать файл для операционной системы, которая не поддерживается данным исходным кодом. Ознакомьтесь с файлами Makefile и README, чтобы узнать подробности о платформах.
Если вы работаете с версией ОС на основе Debian, попробуйте применить команду apt-file к имени заголовочного файла:
$ apt-file search pkg.h
Это может выявить необходимый пакет разработки. Для версий, которые содержат утилиту yum, попробуйте такой вариант:
$ yum provides */pkg.h
Ошибка
Сообщение утилиты make:
make: prog: Command not found
Объяснение и устранение
Чтобы собрать пакет, в вашей системе должна быть программа prog. Если таковой является что-либо вроде cc, gcc или ld, то в системе не установлены утилиты для разработки. С другой стороны, если вы полагаете, что команда prog уже установлена в системе, попробуйте изменить файл Makefile, чтобы выяснить полный путь к команде prog.
В редких случаях команда make собирает программу prog, а затем немедленно ее использует, считая, что текущий каталог (.) расположен в командном пути. Если переменная $PATH не содержит текущий каталог, можно отредактировать файл Makefile и изменить prog на ./prog. Как вариант, можно было бы на время добавить точку к имени пути.
16.7. Заглядывая вперед
Мы только затронули основы сборки программного обеспечения. Вот несколько дополнительных направлений, которые вы можете исследовать, когда займетесь собственными разработками.
• Понимание того, как использовать другие системы компоновки, кроме утилиты Autoconf (например, CMake и SCons).
• Настройка сборок для вашего ПО. Если вы разрабатываете собственные программы, вам необходимо выбрать систему сборки и научиться применять ее. При создании пакетов с помощью утилиты GNU Autoconf вам может пригодиться книга Джона Кэлкоута (John Calcote) Autotools («Утилиты Autotools») (No Starch Press, 2010).
• Компиляция ядра системы Linux. Система сборки ядра полностью отличается от других инструментов. У нее есть собственная система конфигурирования, предназначенная для точной подгонки под ваше ядро и модули. Однако сама процедура проста. Если вы понимаете, как работает загрузчик системы, у вас не возникнет никаких затруднений. Тем не менее следует с осторожностью заниматься этим: всегда проверяйте, что у вас под рукой есть старое ядро на тот случай, когда вы не сможете загрузиться с помощью нового.
• Специализированные пакеты исходного кода. Дистрибутивы Linux поддерживают собственные версии исходного программного кода в качестве специальных пакетов исходного кода. Иногда могут оказаться полезными исправления, которые расширяют функциональность или исправляют ошибки, недоступные для исправления как-либо иначе. Системы для управления пакетами исходного кода содержат инструменты для автоматической сборки, например debuild в Debian и mock для систем на основе RPM.
Сборка программного обеспечения — это зачастую стартовая площадка для изучения языков программирования и методов разработки ПО. Инструменты, которые вы видели в последних двух главах, снимают завесу тайны с того, откуда берутся ваши системные программы. Совсем несложно выполнить дальнейшие шаги: заглянуть в исходный код, внести изменения и создать собственную программу.