Отправляет email-рассылки с помощью сервиса Sendsay

Программирование и др.

  Все выпуски  

Программирование в Linux с нуля - Выпуск 4


Информационный Канал Subscribe.Ru

Программирование в Linux с нуля. Выпуск 4.

1. Предисловие

Здравствуйте, уважаемые подписчики. Этот выпуск будет посвящен работе с GNU-утилитой make. Убедитесь, что она у вас установлена.

2. Программа

2.1. Описание

Воспользуемся программой из прошлого выпуска. Программа состоит из двух файлов, написанных на C++ (main.cpp, pswgen.cpp) и одного заголовочного файла pswgen.h. Компиляцию и сборку проекта мы осуществляли посредством выполнения трех команд:


$ g++ -c main.cpp
$ g++ -c pswgen.cpp
$ g++ -o pswgen main.o pswgen.o

А если бы проект состоял из 20-ти или из 30-ти исходных файлов?! Возникает вопрос об автоматизации компиляции и сборки проекта. Можно, конечно, "запихнуть" все эти команды в bash-скрипт, но в этом случае изменение одного исходного файла потребует перекомпиляции всех остальных (нетронутых!) исходников. Учитывая то, что компиляция - процесс длительный, подход с использованием обыкновенного bash-скрипта недопустим. Вот здесь мы и воспользуемся утилитой make. Чтобы утилита make могла работать, для нее следует написать файл-сценарий, который помещается в репозиторий проекта и называется Makefile. Обратите внимание, что в файловой системе Linux (будь то ext2, ext3 или reiserfs) имена файлов чувствительны к регистру символов. Проще говоря, заглавные и прописные символы распознаются как разные. По сему Makefile и makefile - это разные имена, и для нормальной работы утилиты make нужно именовать файл-сценарий именно с заглавной буквы.

2.2. Makefile

Вот таким будет наш Makefile. Обратите внимание, что [tab] следует заменить на табуляции. Используйте для написания Makefile текстовый редактор, который не заменяет табуляции пробелами.


pswgen: main.o pswgen.o
[tab] g++ -o pswgen main.o pswgen.o

main.o: main.cpp pswgen.h
[tab] g++ -c main.cpp

pswgen.o: pswgen.cpp pswgen.h
[tab] g++ -c pswgen.cpp

clean:
[tab] rm -f *.o pswgen

2.5. Компиляция и сборка

Теперь чтобы откомпилировать и собрать проект достаточно зайти в репозиторий, где уже лежит Makefile и набрать одну команду.


$ make
g++ -c main.cpp
g++ -c pswgen.cpp
g++ -o pswgen main.o pswgen.o
$

Как видим, утилита make вывела на экран три строчки. Это выполняемые действия. Теперь внесем в файл main.cpp незначительные изменения. Заменим имя переменной p:


#include "pswgen.h"

int main ()
{
 pswgen pas (3, 2, 0);
 pas.outp ();

 return 0;
}

Теперь заново запустим утилиту make:
$ make
g++ -c main.cpp
g++ -o pswgen main.o pswgen.o
$

Утилита make снова вывела на экран список команд, которые она выполнила. На этот раз файл pswgen.cpp не компилировался, поскольку изменения в файле main.cpp никак не отражаются на файле pswgen.o.

Предположим, теперь, что вы написали программу и хотите отправить ее другу. Нет большого смысла отправлять объектные и исполняемые файлы. Достаточно отправить исходники и Makefile. Чтобы очистить проект от лишнего мусора, выполним следующую команду:


$ make clean
rm -f *.o pswgen
$

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

3. Теория

3.1. Цели. Зависимости. Правила

Любая программа, состоящая из нескольких исходных файлов, требует разбиения процесса компиляции и сборки на цели, зависимости и правила. Рассмотрим нашу программу. Конечная цель компиляции и сборки нашего проекта - это получение рабочего исполняемого файла pswgen. Для реализации этой цели мы используем объектные файлы main.o и pswgen.o, от которых зависит наша цель и правило, по которому файлы main.o и pswgen.o будут превращаться в pswgen. В данном случае это сборка. Объектных файлов main.o и pswgen.o изначально не существует, по сему ставим цели их получения. Файл main.o зависит от файла main.cpp. Аналогично файл pswgen.o не может получиться без файла pswgen.cpp. В каждый из этих файлов (main.cpp, pswgen.cpp) включается интерфейс pswgen.h, значит от него тоже кое-что зависит. Получаем следующее:

1. Есть цель: получение исполняемого файла pswgen. Назовем эту цель pswgen.
Цель pswgen зависит от двух объектных файлов main.o и pswgen.o.
Для реализации этой цели используется правило сборки.

2. Есть цель: получение объектного файла main.o. Назовем эту цель main.o.
Цель main.o зависит от двух файлов main.cpp и pswgen.h.
Для реализации этой цели используется правило компиляции

3. Есть цель: получение объектного файла pswgen.o. Назовем эту цель pswgen.o.
Цель pswgen.o зависит от двух файлов pswgen.cpp и pswgen.h.
Для реализации этой цели используется правило компиляции

4. Есть цель: удаление мусора. Назовем эту цель clean.
Цель clean ни от чего не зависит.
Для реализации этой цели используется правило удаления

3.2. Синтаксис Makefile

Рассмотрим наш Makefile. Где здесь цели, где зависимости, а где правила, уже понятно.

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

Вообще говоря Makefile может состоять из следующих блоков:

1. Объявления констант (будет рассмотрено в последующих выпусках рассылки).
2. Комментарии. Комментарии в Makefile начинаются с символа # и заканчиваются символом конца строки.
3. Триады цель-зависимости-правила.

Нас пока интересуют эти самые триады. Синтаксис их формирования такой:

1. Пишиется название цели, заканчивающееся двоеточием.

2. После двоеточия через пробел указываются зависимости. Если список зависимостей не умещается на одной строке, то для переноса строки используется символ backslash (\). После списка зависимостей следует символ переноса строки.

3. Теперь пишем список правил для реализации цели. Перед каждым правилом ставится табуляция. Если правило не умещается на одной строке - не беда: используйте для переноса тот же символ backslash.

Заключение

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

Учитывая то, что аудитория рассылки - люди с разным уровнем знаний по программированию, у меня зародилась идея создания параллельной рассылки, посвященной программированию на C и С++ с нуля. Идея новой рассылки состоит в комбинации экспресс-курса по языкам C и C++ плюс фундаментальные алгоритмы. Новая рассылка должна быть тесно связана с существующей. Если есть предложения, пишите на nnivanov@mail.ru.

Те, кто участвует в создании сайта, откликнитесь! До завершения первой версии осталось совсем немного, но одному мне не справиться.

Все вопросы относительно рассылки направляйте на nnivanov@mail.ru.

Всегда ваш. Николай.
Рассылки Subscribe.Ru
*nix project - новости из мира unix-систем! (ежедневная)

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.linuxp
Отписаться

В избранное