Рейтинговые книги
Читем онлайн Командная строка Linux - Шоттс Уильям

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 79 80 81 82 83 84 85 86 87 ... 113

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

./configure

make

Программа configure — это сценарий командной оболочки, поставляемый вместе с деревом исходных текстов. Его задача — проанализировать окружение сборки. Большинство исходного кода поддерживает переносимость. То есть такой исходный код спроектирован так, что допускает сборку в разных Unix-подобных системах. Но для этого во время сборки в исходный код может потребоваться внести небольшие изменения, учитывающие различия между системами. Программа configure также проверяет наличие необходимых внешних инструментов и компонентов.

Давайте запустим configure. Так как эта программа находится не там, где командная оболочка обычно ищет выполняемые файлы, нужно явно сообщить ей местоположение программы, добавив в команду префикс./. Он указывает, что программа находится в текущем рабочем каталоге:

[[email protected] diction-1.11]$ ./configure

В процессе проверки и настройки сборки configure выведет множество сообщений. Последние строки ее вывода должны выглядеть примерно так:

checking libintl.h presence... yes

checking for libintl.h... yes

checking for library containing gettext... none required

configure: creating ./config.status

config.status: creating Makefile

config.status: creating diction.1

config.status: creating diction.texi

config.status: creating diction.spec

config.status: creating style.1

config.status: creating test/rundiction

config.status: creating config.h

[[email protected] diction-1.11]$

Самое важное здесь — отсутствие сообщений об ошибках. Их появление означало бы неудачу настройки и невозможность сборки программы до их устранения.

Как мы видим, configure создала в каталоге с исходным кодом несколько файлов. Самым важным является Makefile. Файл Makefile — это конфигурационный файл с инструкциями для программы make, описывающими, как собрать программу. Без такого файла утилита make работать не будет. Makefile — обычный текстовый файл, то есть мы можем заглянуть в него:

[[email protected] diction-1.11]$ less Makefile

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

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

CC= gcc

определяющую, что роль компилятора C будет играть gcc. Далее в файле можно посмотреть, как используется это определение:

diction:        diction.o sentence.o misc.o getopt.o getopt1.o

                $(CC) -o [email protected] $(LDFLAGS) diction.o sentence.o misc.o

                getopt.o getopt1.o $(LIBS)

Здесь выполняется подстановка: во время выполнения конструкция $(CC) замещается командой gcc.

Большую часть файла сборки занимают строки, определяющие целевой файл (target) — в данном случае выполняемый файл diction — и файлы, от которых она зависит. Остальные строки описывают команды, которые необходимо выполнить для создания целевого файла из его компонентов. Мы видим, что выполняемый файл diction (одна из конечных программ) зависит от присутствия файлов diction.o, sentence.o, misc.o, getopt.o и getopt1.o. Далее в файле сборки присутствуют определения, в которых каждый из этих файлов играет роль целевого.

diction.o:      diction.c config.h getopt.h misc.h sentence.h

getopt.o:       getopt.c getopt.h getopt_int.h

getopt1.o:      getopt1.c getopt.h getopt_int.h

misc.o:         misc.c config.h misc.h

sentence.o:     sentence.c config.h misc.h sentence.h

style.o:        style.c config.h getopt.h misc.h sentence.h

Однако в этих определениях не видно ни одной команды. Обработка этих строк осуществляется определением общей цели, что находится выше в файле, где описывается команда компиляции всех файлов с расширением .c в файлы с расширением .o:

.c.o:

                $(CC) -c $(CPPFLAGS) $(CFLAGS) $<

На первый взгляд все это кажется очень сложным. Почему бы просто не перечислить все этапы компиляции? Ответ на этот вопрос станет очевиден чуть позже. А пока давайте запустим make и соберем наши программы:

[[email protected] diction-1.11]$ make

Программа make запустится и выполнит все инструкции в файле Makefile. В процессе работы она выведет множество сообщений. А по завершении мы увидим, что в каталоге появились все целевые файлы:

[[email protected] diction-1.11]$ ls

config.guess   de.po            en            install-sh   sentence.c

config.h       diction          en_GB         Makefile     sentence.h

config.h.in    diction.1        en_GB.mo      Makefile.in  sentence.o

config.log     diction.1.in     en_GB.po      misc.c       style

config.status  diction.c        getopt1.c     misc.h       style.1

config.sub     diction.o        getopt1.o     misc.o       style.1.in

configure      diction.pot      getopt.c      NEWS         style.c

configure.in   diction.spec     getopt.h      nl           style.o

COPYING        diction.spec.in  getopt_int.h  nl.mo        test

de             diction.texi     getopt.o      nl.po

de.mo          diction.texi.in  INSTALL       README

Среди них diction и style, программы, которые мы намеревались собрать. Примите заслуженные поздравления! Мы только что скомпилировали первые программы из исходного кода!

Но, исключительно ради любопытства, запустим make еще раз:

[[email protected] diction-1.11]$ make

make: Nothing to be done for `all'13.

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

[[email protected] diction-1.11]$ rm getopt.o

[[email protected] diction-1.11]$ make

Вы увидите, что make повторно собирает getopt.o и заново компонует программы diction и style, потому что они зависят от отсутствующего модуля. Такое поведение указывает на еще одну важную особенность make: она старается обеспечить актуальность целевых файлов. make гарантирует, что целевые файлы будут более новыми, чем их зависимости. В этом есть определенный смысл, потому что программист часто сначала изменяет исходный код, а затем запускает make, чтобы собрать новую версию программы. make гарантирует сборку всех целевых файлов, опирающихся на изменившийся код. Воспользуемся программой touch, чтобы «обновить» один из файлов с исходным кодом, и посмотрим, к чему это приведет:

[[email protected] diction-1.11]$ ls -l diction getopt.c

-rwxr-xr-x 1 me      me      37164 2009-03-05 06:14 diction

-rw-r--r-- 1 me      me      33125 2007-03-30 17:45 getopt.c

[[email protected] diction-1.11]$ touch getopt.c

[[email protected] diction-1.11]$ ls -l diction getopt.c

-rwxr-xr-x 1 me      me      37164 2009-03-05 06:14 diction

-rw-r--r-- 1 me      me      33125 2009-03-05 06:23 getopt.c

[[email protected] diction-1.11]$ make

Когда make завершится, мы увидим, что целевой файл стал «свежее» зависимости:

[[email protected] diction-1.11]$ ls -l diction getopt.c

-rwxr-xr-x 1 me      me      37164 2009-03-05 06:24 diction

-rw-r--r-- 1 me      me      33125 2009-03-05 06:23 getopt.c

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

1 ... 79 80 81 82 83 84 85 86 87 ... 113
На этой странице вы можете бесплатно читать книгу Командная строка Linux - Шоттс Уильям бесплатно.

Оставить комментарий