C++. Сборник рецептов - Д. Стефенс
Шрифт:
Интервал:
Закладка:
В других случаях скачайте самую свежую версию GNU make с сайта ftp://ftp.gnu.org/pub/gnu/make, распакуйте ее и следуйте инструкциям по установке.
ОбсуждениеУтилита make имеет множество разновидностей. Большая часть инструментариев содержит собственные варианты make. Например, Visual C++ поставляется с утилитой, которая называется nmake.exe. Обычно эти специфичные версии make содержат встроенные функции, которые облегчают их использование с конкретным инструментарием. В результате обсуждение make, которое охватывает множество инструментариев, должно будет описать несколько версий make или иметь дело с ситуациями, когда между какой-то отдельной версией make и конкретным инструментарием не будет соответствия.
Вместо того чтобы описывать несколько утилит make, я решил сконцентрировать внимание на GNU make, которая является наиболее мощным и переносимым вариантом make. GNU make в первую очередь предназначена для работы с GCC. В результате использование GNU make с другим инструментарием, в частности для Windows, иногда может оказаться нетривиальным. Тем не менее, так как GNU make обладает достаточной гибкостью, гораздо проще использовать GNU make с нe-GNU-инструментам и, чем большую часть других make, типа nmake.exe, с инструментарием, отличным от того, для которого они были разработаны.
Основные преимущества GNU make происходят от ее способности исполнять сложные сценарии оболочки. Если вы работаете одновременно и в Unix, и в Windows, вы знаете, что оболочка Windows cmd.exe оставляет желать много большего; в ней отсутствуют многие полезные команды, она имеет ограниченную способность по выполнению сценариев и накладывает жесткие ограничения на длину командной строки. Следовательно, если заставить GNU make использовать cmd.exe, то ее возможности будут сильно ограничены. К счастью, Cygwin и MSYS предоставляют прекрасные среды для использования GNU make в Windows.
MSYS предоставляет минимальную среду, необходимую для запуска в Windows make-файлов и сценариев configure в стиле Unix. Среди прочих полезных инструментов она предоставляет awk, cat, cp, grep, ls, mkdir, mv, rm, rmdir и sed. MSYS была предназначена для работы с GCC и прекрасно с этим справляется. Однако с другими инструментариями для Windows, в частности теми, которые предоставляют .bat-файлы для установки переменных среды и используют для опций командной строки слеши (/) вместо тире (-), она работает несколько менее гладко.
Так, где MSYS минимальна, Cygwin максимальна. Cygwin make может делать все, что может MSYS make, и даже много больше. Однако переносимые make-файлы ограничены узким диапазоном утилит GNU, и они все поддерживаются в MSYS.
Смотри такжеРецепт 1.1.
1.15. Сборка простого приложения «Hello, World» с помощью GNU make
ПроблемаВы хотите с помощью GNU make собрать простую программу «Hello, World», подобную приведенной в примере 1.4.
РешениеПрежде чем вы напишете свой первый make-файл, вы должны познакомиться с терминологией, make-файл состоит из набора правил, имеющих вид
цели: пререквизиты
команда-сценарий
Здесь цели и пререквизиты — это строки, разделенные пробелами, а команда-сценарий состоит из нуля или более строк текста, каждая из которых начинается с символа табуляции (Tab). Цели и пререквизиты обычно являются именами файлов, но иногда они представляют собой просто формальные имена действий, выполняемых make. Командный сценарий состоит из последовательности команд, передаваемых в оболочку. Грубо говоря, правило говорит make сгенерировать набор целей из набора пререквизитов, выполнив для этого командный сценарий.
Пробелы в make-файлах значимы. Строки, содержащие командные сценарии, должны начинаться с Tab, а не с пробелов — это источник некоторых наиболее распространенных ошибок новичков. В следующих примерах строки, которые начинаются с Tab, указаны с помощью отступа на четыре символа.
Теперь вы готовы начать. В директории, содержащей исходные файлы, создайте текстовый файл с именем makefile. В этом файле объявите четыре цели. Первую цель назовите all и в качестве ее пререквизита укажите имя собираемого исполняемого файла. Она не должна содержать командного сценария. Второй цели присвойте имя исполняемого файла. В качестве ее пререквизитов укажите имена исходных файлов, а в качестве командного сценария укажите команды, которые требуется выполнить для сборки исполняемого файла из исходных файлов. Третья цель должна называться install. У нее не должно быть пререквизитов и должен быть командный сценарий, копирующий исполняемый файл из директории, содержащей make-файл, в директорию, где он должен быть установлен. Последняя цель должна называться clean. Как и install, она не должна иметь пререквизитов. Ее командный сценарий должен удалять из текущей директории исполняемый файл и промежуточные объектные файлы. Цели clean и install должны быть помечены как phony targets (фиктивные цели), для чего используется атрибут PHONY.
Например, чтобы с помощью GCC собрать исполняемый файл из исходного кода из примера 1.4, make-файл может иметь вид, показанный в примере 1.14.
Пример 1.14. make-файл для сборки исполняемого файла с помощью GCC
# Это цель по умолчанию, которая будет собрана при
# вызове make
.PHONY: all
all: hello
# Это правило говорит make, как собрать hello из hello.cpp
hello: hello.cpp
g++ -o hello hello.cpp
# Это правило говорит make скопировать hello в поддиректорию binaries,
# создав ее, если требуется
.PHONY: install
install:
mkdir -p binaries
cp -p hello binaries
# Это правило говорит make удалить hello и hello.о
.PHONY: clean
clean:
rm -f hello
Чтобы собрать исполняемый файл из исходного кода из примера 1.4 с помощью Visual С++, используйте make-файл, показанный в примере 1.15.
Пример 1.15. make-файл для сборки исполняемого файла с помощью Visual С++.
#цель по умолчанию
.PHONY: all
all: hello.exe
#правило для сборки hello.exe
hello.exe: hello.cpp
cl -nologo -EHsc -GR -Zc:forScope -Zc:wchar_t
-Fehello hello.cpp
.PHONY: install
install:
mkdir -о binaries
cp -p hello.exe binaries
.PHONY: clean
clean:
rm -f hello.exe
Команды и списки целей или пререквизитов могут занимать несколько строк текста make-файла, для чего используется символ продолжения строки , как и в исходных файлах С++.
Чтобы собрать исполняемый файл, установите переменные среды, необходимые для инструментов командной строки, перейдите в директорию, содержащую makefile, и введите make. Чтобы скопировать исполняемый файл в поддиректорию binaries, введите make install. Чтобы удалить из директории make-файла исполняемый файл и промежуточный объектный файл, введите make clean.
Если вы установили среду Cygwin, описанную в рецепте 1.1, можете выполнить make-файл из примера 1.15 непосредственно из оболочки Windows cmd.exe.
Также этот make-файл можно выполнить из оболочки Cygwin, как описано далее. В cmd.exe запустите vcvars32.bat, устанавливающий переменные среды Visual С++. Затем запустите cygwin.bat, запускающий оболочку Cygwin. Если директория установки Cygwin добавлена в PATH, то оболочку Cygwin можно запустить из cmd.exe, просто введя cygwin. Наконец, перейдите в директорию, содержащую make-файл, и введите make.
Аналогично можно выполнить make-файл из оболочки MSYS: в cmd.exe запустите vcvars32.bat, затем запустите msys.bat, запускающий оболочку MSYS.
Если ваш инструментарий предоставляет сценарий для установки переменных среды, запуск make-файла из Cygwin или MSYS несколько более трудоемок, чем его запуск из cmd.exe. Однако для некоторых make-файлов это обязательное условие, так как они не будут работать из-под cmd.exe.
ОбсуждениеВ нескольких последующих рецептах вы увидите, что GNU make является достаточно мощным инструментом для сборки сложных проектов. Но что же она делает? Вот как она работает. При вызове make без аргументов она просматривает текущую директорию в поисках файла с именем GNUmakefile, makefile или Makefile и пытается собрать первую содержащуюся в нем цель, которая называется целью по умолчанию (default target). Если цель по умолчанию не устарела, что означает, что она существует, все ее пререквизиты существуют и ни один из них не был изменен с момента ее сборки, то работа make закончена. В противном случае она пытается сгенерировать цель по умолчанию из ее пререквизитов, выполнив соответствующий командный сценарий. Аналогично определению устаревания этот процесс рекурсивен: для каждого устаревшего пререквизита make ищет правило, содержащее этот пререквизит в качестве цели, и начинает весь процесс заново. Так продолжается до тех пор, пока цель по умолчанию не будет обновлена или пока не возникнет ошибка.