GNU Autotools: ошибки свои и чужие::Журнал СА 12.2007
www.samag.ru
     
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Наука и технологии
Подписка
Где купить
Авторам
Рекламодателям
Магазин
Архив номеров
Вакансии
Контакты
   

  Опросы

Какие курсы вы бы выбрали для себя?  

Очные
Онлайновые
Платные
Бесплатные
Я и так все знаю

 Читать далее...

1001 и 1 книга  
20.12.2019г.
Просмотров: 5101
Комментарии: 0
Dr.Web: всё под контролем

 Читать далее...

04.12.2019г.
Просмотров: 6343
Комментарии: 0
Особенности сертификаций по этичному хакингу

 Читать далее...

28.05.2019г.
Просмотров: 7599
Комментарии: 2
Анализ вредоносных программ

 Читать далее...

28.05.2019г.
Просмотров: 7922
Комментарии: 1
Микросервисы и контейнеры Docker

 Читать далее...

28.05.2019г.
Просмотров: 6978
Комментарии: 0
Django 2 в примерах

 Читать далее...

Друзья сайта  

Форум системных администраторов  

sysadmins.ru

 GNU Autotools: ошибки свои и чужие

Архив номеров / 2007 / Выпуск №12 (61) / GNU Autotools: ошибки свои и чужие

Рубрика: Администрирование /  Продукты и решения

Рашид Ачилов

GNU Autotools: ошибки свои и чужие

GNU Autotools, комплект скриптов, предназначенный для облегчения процесса построения сложных программных проектов, является чрезвычайно удобной и мощной системой. Есть тут только одно «но» – эта система очень плохо документирована. Поэтому если при сборке чужого проекта неожиданно возникает ошибка, то чувство растерянности – и что тут делать дальше? – вполне уместно. Прочитав эту статью, вы узнаете о том, как программы Autotools связаны между собой и как можно исправить чужие ошибки, не наделав своих.

Анатомия

Сейчас уже трудно себе представить, что когда-то для сборки любого программного проекта сначала необходимо было тщательно читать различные README, INSTALL и другую документацию – большую часть работы по выполнению нужных проверок и созданию файла Makefile берет на себя скрипт configure. Но ведь и сам скрипт configure должен создаваться каким-то образом? В этом и состоит роль GNU Autotools – в упрощении работы по сопровождению программных проектов.

Каждый программист знает, что сопровождение программных проектов, в которые входят хотя бы два файла и одна внешняя библиотека, – это достаточно сложное и муторное дело – необходимо позаботиться о том, чтобы в системе оказались все нужные функции и вспомогательные программы, чтобы были установлены подходящие библиотеки требуемых версий. Также надо найти места, где дополнительные программы установлены, занести в Makefile перечень всех файлов с исходным текстом и предусмотреть обработку специальных файлов, если они есть. При этом, конечно же, не забыть создать все каталоги и перечислить нужные библиотеки при компиляции и сборке. Приходится делать множество вещей, которые повторяются раз от раза для каждого из разрабатываемых программных проектов.

Все это хорошо знал и Дэвид Мак-Кензи (David MacKenzie), разработавший в 1992 году первый компонент GNU Autotools – программу Autoconf. В 1994 году им же была написана первая версия программы Automake, позже полностью переписанная Томом Троми (Tom Tromey). В 1996 году в состав GNU Autotools вошел третий важный компонент – Libtool, написанный Гордоном Матцигкейтом (Gordon Matzigkeit). В 1998 году GNU Autotools были портированы под Windows Яном Лэнсом Тейлором (Ian Lance Taylor).

Почему же эти скрипты так важны, чем они так облегчают жизнь программисту?

Autoconf предназначен для создания скрипта configure, который выполняет первую важную задачу – проверяет наличие в системе тех или иных функций (в библиотеках) и наличие тех или иных библиотек необходимых версий, проверяет наличие вспомогательных программ, запоминает все сделанные настройки и формирует файл Makefile (а также другие файлы, формирование которых задано) на основе Makefile.in (и других файлов с расширением .in). В качестве дополнительного источника макросов, используемых при проверке, испольузется файл acinclude.m4, если он есть в текущем каталоге. К числу обычно формируемых дополнительных файлов, как правило, относится файл config.h, который содержит определения типа

#undef HAVE_LIBJPEG

#define HAVE_LIBICONV   1

Исходным файлом для создания скрипта configure является файл configure.in (еще он может называться configure.ac).

Сразу же возникает вопрос – а откуда берутся исходные версии файлов, то есть Makefile.in, configure.in, config.h.in? Можно создавать их вручную, в текстовом редакторе, а можно использоватьAutomake.

Automake – это второй скрипт из пакета GNU Autotools. В цепочке преобразований вспомогательных файлов он стоит впереди. Automake создает файлы, которые затем используются как входные файлы для Аutoconf. Для более полного понимания механизма работы GNU Autotools вся цепочка преобразований основных файлов изображена на схеме.

Диаграмма зависимостей для GNU Autotools

Диаграмма зависимостей для GNU Autotools

Основной задачей Automake является создание файла Makefile.in, то есть генерация некоторого набора стандартных мишеней, с учетом списка исходных файлов и некоторых специальных действий. Ну в самом деле, в каждом программном проекте есть мишени all, install, clean, distclean и т. д. Почему бы не написать некий скрипт, который из предъявленного списка файлов исходных текстов будет формировать Makefile.in? Этим и занимается automake. Он обрабатывает специальный входной файл под названием Makefile.am. Он содержит так называемые «примитивы» (Primaries), которые используются для формирования мишеней, а также правила и переменные, которые просто копируются в Makefile.in, при этом заменяя собой подобное стандартное правило или переменную, если таковые имеются.

Кроме того, в зависимости от режимов работы, Automake может создать набор вспомогательных файлов, которые требуются во всех проектах, соответствующих файловой структуре GNU, – COPYING, INSTALL, NEWS, TODO, README.

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

В отличие от первых двух, Libtool не имеет исходного конфигурационного файла. Поддержка Libtool может быть встроена в исходные файлы configure.in и Makefile.am:

  • в configure.in вписывается одна строка – макрос AC_PROG_LIBTOOL;
  • в Makefile.am используются другие примитивы (например, LTLIBRARIES вместо LIBRARIES).

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

Кроме того, в GNU Autotools входят некоторые вспомогательные программы:

  • Autoscan – предназначена для первоначального создания файла configure.in. Сканирует все файлы проекта и создает файл configure.ac, в который заносит макросы по поиску использованных в файлах функций и некоторых программ.
  • Autoheader – предназначена для создания файла config.h.in. Точно так же сканирует все файлы проекта и создает файл config.h.in на основе использованных заголовочных файлов. Может использовать файл aclocal.m4, если он существует в текущем каталоге.
  • Aclocal – предназначена для создания файла aclocal.m4, который содержит локальные макросы для Automake. Эти макросы могут быть заданы в командной строке или присутствовать в файле configure.ac.

Более полное описание GNU Autotools, правда, на английском языке, можно получить, установив порт devel/autobook, а также из info autoconf-2.61, info automake-1.9.

Физиология

Ну хорошо, нам известны компоненты пакета GNU Autotools и примерная взаимосвязь между ними: сначала запускается aclocal, потом Automake, потом Autoconf. Как все это возможно применить для сборки чужой программы, загруженной, допустим с Sourceforge.net?

Прежде всего отмечу, что autotools hell (буквально «ад autotools», ситуация, когда из-за установки большого количества разных версий autotools, использующих одинаковые имена файлов, возникала очень большая путаница), связанный с необходимостью иметь на машине разработчика Autoconf всех версий от 2.13 до 2.61 включительно, кончился относительно недавно, с появлением в портах autoconf-wrapper и automake-wrapper. Нет, иметь на компьютере все эти версии по-прежнему необходимо. Но теперь для их поиска можно пользоваться врапперами, которые поддерживают стандарт наименования, принятый в Linux, например, autoconf-1.7, вместо принятого в FreeBSD наименования autoconf17. Кроме того, нужные версии программ можно задать через переменные окружения – можно в стартовом скрипте:

setenv  AUTOTOOLS_DEBUG         "yes"

setenv  AUTOCONF_VERSION        "261"

setenv  AUTOMAKE_VERSION        "19"

Таким образом мы устанавливаем в любом случае использование Autoconf 2.61 и Automake 1.9. А можно через команду env:

# env AUTOCONF_VERSION="259" autoconf

Таким образом мы используем Autoconf 2.59, но только для этой команды!

Итак, в общих чертах цепочка выстраивается следующая: aclocal -> autoheader -> automake -> autoconf (см. схему).

Теперь от теории переходим к практике и пробуем собрать программу, которая отсутствует в портах. Вручную, с использованием GNU autotools. В качестве примера возьмем программу kgtk версии 0.9. (Я намеренно указываю номер версии, потому что последняя версия kgtk – 0.9.2, и она уже собирается с помощью Cmake.) Скачать ее можно по адресу [1]. Что мы обнаруживаем в дистрибутиве?

Обнаруживаем уже готовые файлы config.h.in, Makefile.in, configure.in, и если первые два были созданы Automake 1.9, то последний явно писался вручную, потому что не похож ни на что. Кроме того, здесь мы обнаруживаем исходник для Automake – Makefile.am и несколько служебных файлов Automake – depcomp, install-sh, missing, config.guess, ltmain.sh и config.sub. Иногда эти файлы помещаются в подкаталог admin или cfgaux.

Запускаем configure:

# ./configure --prefix=/usr/local/kde3 --with-qt-dir=/usr/X11R6/qt33 /

    --with-extra-includes=/usr/local/include --with-extra-libs=/usr/local/lib --disable-debug

Пока все стандартно, без ошибок, без особенностей. Запускаем gmake... и удивляемся:

# /bin/sh ../libtool --silent --tag=CXX --mode=link g++  -g -O2  -L/usr/local/lib /

    -L/usr/X11R6/lib -o kdialogd3  kdialogd.o -lkio -lkdecore -lqt-mt

/usr/bin/ld: cannot find -lkio

gmake[2]: *** [kdialogd3] Error 1

А удивляемся мы от того, что здесь совершенно отсутствуют указания на то, где искать библиотеки KDE. А это значит, что configure не выполняет своих функций. Посмотрев файл config.log, который создается после каждого выполнения configure и содержит вывод всех тестов и диагностические сообщения, убеждаемся – да, в configure просто-напросто отсутствует блок тестирования наличия KDE, вот такие могут быть неаккуратно написанные скрипты. А может быть, у автора KDE стоял в /usr/local, а о том, что он может находиться в другом месте, он и не подумал.

Добавляем в configure.in одну строчку – макрос поиска KDE AC_PATH_KDE. На самом деле мы этим добавляем целую огромную цепочку макросов (которая уже присутствует в acinclude.m4), которая выполнит поиск QT, KDE, набор необходимых тестов и установит соответствующие переменные. Грамотный разработчик, конечно же, спросит, не читая дальше: «А почему именно AC_PATH_KDE? А где полный список макросов?». Честно скажу, что не знаю. Файл acinclude.m4 со списком макросов, относящихся к KDE, при создании через Kdevelop нового проекта, относящегося к KDE, появляется в каталоге admin. Или же его можно взять из любого другого проекта. Выбираем AC_PATH_KDE потому, что этот макрос служит для поиска пути, куда установлен KDE, и по мере выполнения будет вызывать другие необходимые макросы.

Но это будет потом. Сейчас же нужно пересоздать сам configure:

# env AUTOCONF_VERSION=259 autoconf

Если попытаться запустить Autoconf, не указывая версии, то можно получить нечто невразумительное типа:

configure.in:6: error: Autoconf version 2.58 or higher is required

aclocal.m4:538: AM_INIT_AUTOMAKE is expanded from...

configure.in:6: the top level

Но вот Autoconf завершен успешно, запускаем снова configure, убеждаемся, что да, в новом Makefile появились нужные пути, запускаем gmake... и снова удивляемся, потому что сталкиваемся с той особенностью проектов, которые собираются с помощью GNU Autotools – при изменении любого из исходных файлов выполняется полный комплекс задач по перестройке всех вспомогательных файлов, то есть aclocal, затем autoheader, затем automake, затем autoconf. Причем, если запустить gmake без явного указания версий autotools, можем опять получить то же самое:

# gmake

cd . && /bin/sh /usr/home/shelton/program/kgtk-0.9/missing --run aclocal-1.9

autom4te253: unknown language: Autoconf-without-aclocal-m4

aclocal-1.9: autom4te failed with exit status: 1

gmake: *** [aclocal.m4] Error 1

Теперь запускаем, как упоминалось выше, с указанием версий:

# env AUTOCONF_VERSION=261 AUTOMAKE_VERSION=19 gmake

Теперь Autotools благополучно перестраивает свои файлы, но configure все равно отработать не в состоянии. Мы забыли про одну вещь, которая изначально не входила в autotools, но в последнее время играет все большую роль в процессе сборки программ. Эта вещь называется pkg-config. Pkg-config – это своего рода информационная база по установленным программам. Она содержит информацию, отличную от той, что содержит /var/db/pkg. Это информация о том, в какие каталоги была установлена программа, с какими флагами она компилировалась, с какими библиотеками собиралась, какой номер версии сейчас установлен, с какими пакетами может конфликтовать... Хранится все это в текстовых файлах с расширением .pc, которые как правило располагаются в /usr/local/libdata/pkgconfig, хотя могут располагаться и в других каталогах – это просто текстовые файлы, в них нет ничего мистического. Но если pkg-config не указать эти дополнительные каталоги, то он и искать информацию будет только в /usr/local/libdata/pkgconfig. Каталоги задаются в переменной окружения PKG_CONFIG_PATH через двоеточие. Так вот, в процессе работы configure пытается обнаружить некоторые программы через pkg-config, ничего не находит и аварийно завершается.

Запускаем вот таким образом:

# env AUTOCONF_VERSION=261 AUTOMAKE_VERSION=19 /

    PKG_CONFIG_PATH=/usr/X11R6/libdata/pkgconfig:/usr/X11R6/qt33/libdata/pkgconfig:/usr/local/kde3/libdata/pkgconfig gmake

Ну вот, кое с чем справились – Autotools перестроили свои файлы, configure завершился успешно. Зато получили чрезвычайно странную ошибку:

# /bin/sh ../libtool --silent --tag=CXX --mode=link g++  -g -O2  -L/usr/local/lib /

    -L/usr/X11R6/lib -o kdialogd3 -L/usr/X11R6/lib -L/usr/X11R6/qt33/ lib /

    -L/usr/local/kde3/lib  -L/usr/local/lib kdialogd.o -lkio -lkdecore -lqt-mt

libtool: link: cannot find the library `'

gmake[2]: *** [kdialogd3] Error 1

На первый взгляд в командной строке все нормально – все перечисленные библиотеки могут быть найдены в одном из перечисленных путей, других ключей нет... Какой же библиотеки не хватает для завершения сборки и библиотеки ли?

Путей решения этой проблемы есть два – лобовой и нормальный. В лобовом методе решения исключается Libtool. В Makefile.am добавляется собственная переменная CXXLINK:

CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@

Почему именно CXXLINK и что вообще мы такое натворили? Опять же где можно получить полный список переменных?

На этот вопрос ответить проще. Полный список переменных, которые можно задавать в Makefile.am, приведен в документации по automake, например в info automake-1.9. Там сказано, что CXXLINK – это переменная, содержащая команду, которая используется для сборки программы на языке C++. Там же описаны и прочие переменные, использованные здесь. Кратко на «человеческий» язык это можно перевести так – «используя программу, заданную в переменной CXXLD, флаги компилятора, заданные переменными AM_CXXFLAGS и CXXFLAGS, и флаги компоновщика, заданные переменными AM_LDFLAGS и LDFLAGS, скомпоновать программу и поместить ее файл с именем, заданным в ключе -o компоновщика»

При этом, поскольку собственные переменные замещают переменные по умолчанию, вызова Libtool вообще не произойдет. Но при этом всю его работу нам придется выполнить самим, то есть проверить, что переменные AM_LDFLAGS и LDFLAGS содержат имена всех нужных библиотек и пути к ним.

При выборе нормального метода нужно-таки доискаться до корней причины возникновения такой непонятной ошибки. Для этого необходимо знать, как работает Libtool. Libtool был написан для того, чтобы решать за программиста вопрос «не забыл ли программист указать какую-нибудь нужную библиотеку в строке команды для компилятора или сборщика». Делается это просто – Libtool получает в качестве параметра строку вызова компилятора или сборщика и последовательно проверяет все ключи этой строки. Допустим, при вызове Libtool в режиме сборщика (mode=link) если ключ является указанием пути к библиотекам (-L, -R) или именем статической библиотеки (filename.la), то он переписывается в командную строку, с которой Libtool потом запустит сборщик. Если это известная ему опция командной строки, она игнорируется, возможно, при этом выставляются некоторые флаги работы Libtool. Если же это ссылка на библиотеку (-l), то libtool пытается найти файл с именем, соответствующим имени библиотеки, и расширением .la и извлечь из него информацию о том, как собиралась данная библиотека. Если файл найден, то информация извлекается и присоединяется к исходной строке запуска сборщика. Эта операция выполняется для всех библиотек, которые были найдены в строке параметров Libtool. Но что будет, если Libtool обнаружит незнакомую опцию командной строки?

esac # case $deplib

if test "$found" = yes || test -f "$lib"; then :

else

  $echo "$modename: cannot find the library \`$lib'" 1>&2

  exit 1

fi

Ответ мы видим непосредственно в коде самого Libtool. Если это из вышеперечисленных (а также многих других предусмотренных) вариантов – предполагается, что это файл, и он должен существовать. Но, судя по тексту сообщения об ошибке, переменная $lib не установлена, оттого и сообщение об ошибке выглядит так странно. Что же это за загадочный ключ командной строки?

Пристальней вглядевшись в перечисленные в Libtool ключи, можно обнаружить, что среди них отсутствует -pthread. Так? Делаем небольшой патч:

--- admin/ltmain.sh.bak 2007-10-11 23:07:36.000000000 +0700

+++ admin/ltmain.sh     2007-10-11 23:07:36.000000000 +0700

@@ -1923,6 +1923,10 @@

         continue

         ;;

       *.la) lib="$deplib" ;;

+        -pthread)

+          deplibs="$deplib $deplibs"

+          continue

+            ;;

       *.$libext)

         if test "$pass" = conv; then

           deplibs="$deplib $deplibs"

Не забываем добавить в Makefile.am, в строку kdialog3_LDFLAGS упоминание библиотеки libpthread, коль уж она заявлена при сборке библиотек KDE:

kdialogd3_LDFLAGS  = $(all_libraries) $(LIBPTHREAD)

и запускаем сборку заново. Все в порядке – Libtool отрабатывает нормально. Но это пока еще не «корень зла», а всего лишь то, что называется quick hack (так обычно называют правку на скорую руку, сделанную только для того, чтобы проверить истинность или ложность некоторых посылок. Буквальный перевод этого выражения – «быстрый взлом»). Чтобы доискаться-таки до причины, нужно вспомнить, что сам скрипт Libtool создается из файла ltmain.sh, который, как правило, распространяется вместе с дистрибутивом или в корневом каталоге, или в каталоге для вспомогательных файлов. ltmain.sh – это тот же Libtool, только в нем не выполнены некоторые макроподстановки. Если наложить на него патч, приведенный выше, на всякий случай удалить Libtool и заново запустить configure (через env с указанием всех необходимых переменных), то должен быть создан работоспособный Libtool.

Но как же так получилось? Автор программы распространяет со своим дистрибутивом ltmain.sh, содержащий ошибки?

Нет. Просто ltmain.sh, который поставляется в дистрибутиве, – очень старый. Достаточно заглянуть внутрь, чтобы убедиться, что это так и есть:

PROGRAM=ltmain.sh

PACKAGE=libtool

VERSION=1.4e

TIMESTAMP=" (1.1090 2002/02/07 19:54:36)"

В 2002 году не было ключа командной строки -pthread. Для решения этой проблемы без применения упомянутого выше патча достаточно переписать в каталог сборки (или каталог вспомогательных файлов – в зависимости от того, где находился ltmain.sh) новую версию, которую можно взять из каталога libtool, установленного в системе – /usr/local/share/libtool.

Сборка снова завершается аварийно, но уже в другом каталоге и по другой причине – сборщик не смог найти библиотеку libdl. Неудивительно – во FreeBSD вообще нет такой библиотеки (вы не забыли, что программа изначально написана под Linux?). Вот тут нам и пригодится возможность редактирования configure.in и пересоздания configure. Достаточно вставить проверку на операционную систему и, если это FreeBSD, игнорировать тестирование на libdl:

@@ -156,19 +158,25 @@

 fi

 AC_CHECK_FUNCS(getpeereid)

 +# FreeBSD has not dlvsym, so we check this occassion

+HOST=`uname`

 -# Check if we have dlvsym...

-AC_CHECK_LIB(dl, dlvsym,

+if test "$HOST" != "FreeBSD"; then

+  # Check if we have dlvsym...

+  AC_CHECK_LIB(dl, dlvsym,

              AC_DEFINE(HAVE_DLVSYM, 1, [dlvsym in libdl]),

              AC_MSG_WARN([You're libdl does not contain dlvsym - SWT apps will not be supported]))

 -# Determine version of dlsym...

-for d in `libtool --config | grep sys_lib_search_path_spec | awk -F= '{print $2}' | sed s:\"::g ` ; do

+  # Determine version of dlsym...

+  for d in `libtool --config | grep sys_lib_search_path_spec | awk -F= '{print $2}' | sed s:\"::g ` ; do

     if test -z $KGTK_DLSYM_VERSION  && test -f $d/libdl.so ; then

         KGTK_DLSYM_VERSION=`objdump --dynamic-syms $d/libdl.so  | grep dlsym | awk '{print $6}'`

         AC_DEFINE_UNQUOTED(KGTK_DLSYM_VERSION, "$KGTK_DLSYM_VERSION", [Version of dlsym])

     fi

-done

+  done

+fi

Сборка завершена. Ура. Вот мы и побывали в роли человека, портирующего приложения Linux на FreeBSD, осталось только порт создать.

Гигиена

Вообще использование обычных команд оболочки внутри файла configure.in имеет некоторые особенности.

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

Во-вторых, нельзя использовать оператор set по тем же причинам, что и перенаправление, – скрипт уже задействовал эту возможность. Можно только использовать независимые команды, причем такие, которые не могут отсутствовать в системе либо наличие которых уже проверено. Например, вот как можно проверить, что команда mkdir поддерживает ключ -p:

mkkey=`mkdir 2>&1 | tail -c +15 | head -c 2`

А вот так можно проверить версию программы kavdaemon – демон антивирусной защиты старого образца (версии 4.х):

KAVD=`whereis -b -B $kavbin -f kavdaemon | awk '{print $2}'`

KAVER=`$KAVD -v | awk '{print $6}' | head -c 7`

Если используется некоторый набор одних и тех же тестов, то лучше всего их поместить в отдельный каталог и подключать его в самом начале при вызове aclocal:

# aclocal -I m4

если собственные макросы размещены в подкаталоге m4 текущего каталога.

Какие же ошибки допускают разработчики программ:

Первая и, пожалуй, наиболее частая ошибка – это жестко прописаные пути (hadrcoded path). Многие разработчики, особенно начинающие, всерьез полагают, что если у него программа А и библиотека В установлены в /usr/local, то точно так же поступают и все остальные и, нимало не сомневаясь, прописывают вызов программы без указания пути или библиотеки без указания каталога поиска. В этом случае нужно внести изменения в файл Makefile.am, если он есть. Если файла Makefile.am не существует, тогда можно вносить изменения в файл Makefile.in, но если существует, – в Makefile.in вносить изменения бессмысленно, он все равно будет перестроен из Makefile.am. Для добавления пути поиска для файлов заголовков или библиотек следует перенести в Makefile.am следующие определения переменных: CXXFLAGS – если необходимо добавить путь поиска заголовков 
(-I/some/path/to),  LDFLAGS – если необходимо добавить путь поиска библиотек (-L/some/path/to) и дополнить их своими значениями. Как уже упоминалось выше, automake, обнаружив в Makefile.am задание стандартной переменной, переносит ее в Makefile.in в неизменном виде.

Вторая наиболее частая ошибка – это то самое сообщение «Cannot find the library», причину появления которого мы уже разобрали. Возникает она оттого, что разработчики используют неведомо где добытые файлы ltmain.sh от давным-давно устаревших версий Libtool, которые уже не понимают всего набора ключей, что может ими использоваться. Я много раз натыкался на это сообщение, но только сейчас у меня хватило терпения разобраться, откуда же оно берется. Решается этот вопрос либо заменой ltmain.sh на файл из последней версии Libtool, либо (если замена невозможна, например в порту) созданием патча, который будет обрабатывать нужный ключ нужным образом. Хотя, конечно, можно и порт заставить скопировать новую версию файла ltmain.sh.

Третья распространенная ошибка – это предположение, что какая-то версия программы или библиотеки независимо ни от чего присутствует в системе. Во FreeBSD нет и никогда не было некоторых библиотек, но если следовать логике configure, если они не обнаруживаются, значит, есть, но старые. Варианта «таких библиотек нет», как правило, в таких случаях не предусматривается. Здесь вполне уместно заметить следующую вещь: configure – не догма, в особенности в тех программах, которые писались «только под Linux». Авторы этих программ могут и не подозревать и о том, что их программа может работать в другой системе, и о том, что для сборки в другой системе вовсе не нужны некоторые библиотеки, поэтому в configure могут встречаться проверки на наличие библиотек, изначально отсутствующих в данной операционной системе (как, например, libdl в патче, приведенном выше). Если убрать имя такой библиотеки из строки параметров сборки программы, то ничего не произойдет – все равно Linux-специфичные библиотеки во FreeBSD не используются.

Последние две известные мне (но далеко не последние вообще) ошибки – это использование Autotools не той версии, чем у автора, и отсутствие в configure.in нужного макроса, самостоятельная разработка макроса (при наличии уже готовых точно таких же). Первая проявляется обычно тем, что при запуске make появляется множество замечаний от Automake, от Autoconf. Как правило, в таком случае autotools не отрабатывает успешно, хотя бывают и исключения. Второй случай наиболее распространен с KDE, и проявляется он, как правило, отсутствием правила для преобразования файлов .ui в файлы .moc или другой такой же ошибкой, которая в нормальных условиях возникнуть не может.

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

Заключение

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

  1. http://home.freeuk.com/cpdrummond/kgtk-0.9.tar.bz2.

Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-41
Fax: (499) 277-12-45
E-mail: sa@samag.ru