• Условные операторы. Можно пометить отдельные фрагменты кода с помощью слов #ifdef, #if и #endif. Директива #ifdef
Приведу далее пример условной директивы. Когда препроцессор встречает такой код, он проверяет, есть ли макроопределение DEBUG, и если оно определено, передает компилятору строку, содержащую команду fprintf. В противном случае препроцессор пропускает эту строку и продолжает обработку файла после директивы #endif:
#ifdef DEBUG
fprintf(stderr, "This is a debugging message.\n");
#endif
примечание
Препроцессор C ничего не знает о синтаксисе языка C, переменных, функциях и других элементах. Он понимает только свои собственные макроопределения и директивы.
В Unix препроцессор C называется cpp, но можно также запускать его с помощью команды gcc -E. Однако вам нечасто понадобится запускать препроцессор как таковой.
15.1.3. Связывание с библиотеками
Компилятор C знает о вашей системе недостаточно для того, чтобы самостоятельно создать пригодную программу. Для построения завершенных программ вам необходимы
Библиотеки вступают в игру главным образом во время компоновки, когда программа-компоновщик создает исполняемый файл из объектных файлов. Например, если у вас есть программа, которая использует библиотеку gobject, но вы забыли указать компилятору о связывании с этой библиотекой, то появятся ошибки компоновщика, подобные этой:
badobject.o(.text+0x28): undefined reference to 'g_object_new'
Наиболее важные части этого сообщения выделены жирным шрифтом. Когда компоновщик проверял объектный файл badobject.o, ему не удалось найти функцию, которая выделена жирным шрифтом, и, как следствие, не удалось создать исполняемый файл. В данном частном случае можно предположить, что вы забыли о библиотеке gobject, поскольку отсутствующая функция называется g_object_new.
примечание
Неопределенные ссылки не всегда означают, что вы упустили библиотеку. Один из объектных файлов команды может отсутствовать в команде компоновки. Но обычно достаточно легко понять, что отсутствует — библиотечные функции или объектные файлы.
Чтобы исправить эту ошибку, сначала вы должны отыскать библиотеку gobject, а затем использовать параметр компилятора -l, чтобы установить связь с библиотекой. Так же как и включаемые файлы, библиотеки разбросаны по всей системе (по умолчанию используется каталог /usr/lib), хотя большинство из них расположено в подкаталоге lib. В предыдущем примере основным файлом библиотеки gobject является libgobject.a, поэтому имя библиотеки — gobject. Объединяя все это, можно выполнить компоновку команды следующим образом:
$ cc -o badobject badobject.o -lgobject
Вы должны сообщать компоновщику о нестандартном расположении библиотеки; для этого применяется параметр -L. Допустим, что команде badobject необходим файл libcrud.a в каталоге /usr/junk/lib. Чтобы выполнить компиляцию и создать исполняемый файл, используйте команду, подобную этой:
$ cc -o badobject badobject.o -lgobject -L/usr/junk/lib -lcrud
примечание
Если вам необходимо отыскать в библиотеке некоторую функцию, применяйте команду nm. Будьте готовы к обширному отчету. Попробуйте, например, такую команду: nm libgobject.a. Вам может понадобиться команда locate, чтобы отыскать файл libgobject.a; многие версии системы теперь помещают библиотеки в подкаталоги, зависящие от архитектуры, внутри каталога /usr/lib.
15.1.4. Совместно используемые библиотеки
Библиотека, имя файла которой оканчивается на .a (например, libgobject.a), называется