Д. Стефенс - C++. Сборник рецептов
- Название:C++. Сборник рецептов
- Автор:
- Жанр:
- Издательство:КУДИЦ-ПРЕСС
- Год:2007
- Город:Москва
- ISBN:5-91136-030-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Д. Стефенс - C++. Сборник рецептов краткое содержание
Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.
C++. Сборник рецептов - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Пример 1.16. make-файл для сборки исполняемого файла hello с помощью GCC, измененный с помощью переменных
# Указываем целевой файл и директорию установки
OUTPUTFILE=hello
INSTALLDIR=binaries
# Цель по умолчанию
.PHONY all
all: $(OUTPUTFILE)
# Собрать hello из hello.cpp
$(OUTPUTFILE): hello cpp
g++ -o hello hello.cpp
#Скопировать hello в поддиректорию binaries
.PHONY: install
install:
mkdir -p $(INSTALLDIR)
cd -p $(OUTPUTFILE) $(INSTALLDIR)
# Удалить hello
.PHONY: clean
clean:
rm -f $(OUTPUTFILE)
Здесь я ввел две переменные make — OUTPUTFILE
и INSTALLDIR
. Как вы можете видеть, значения переменным make присваиваются с помощью оператора присвоения =, и они вычисляются с помощью заключения их в круглые скобки с префиксом в виде знака доллара.
Также установить значение переменной make можно в командной строке с помощью записи make X=Y . Кроме того, при запуске make все переменные среды используются для инициализации переменных make с такими же именами и значениями. Значения, указанные в командной строке, имеют приоритет перед значениями, унаследованными от переменных среды. Значения, указанные в самом make-файле, имеют приоритет перед значениями, указанными в командной строке.
Также GNU make поддерживает автоматические переменные ( automatic variables ), имеющие специальные значения при выполнении командного сценария. Наиболее важные из них — это переменная $@
, представляющая имя файла цели, переменная $<
, представляющая имя файла первого пререквизита, и переменная $^
,представляющая последовательность пререквизитов, разделенных пробелами. Используя эти переменные, мы можем еще сильнее упростить make-файл из примера 1.16, как показано в примере 1.17.
Пример 1.17. make-файл для сборки исполняемого файла hello с помощью GCC, измененный с помощью автоматических переменных
# Указываем целевой файл и директорию установки
OUTPUTFILE=hellо
INSTALLDIR=binaries
# Цель по умолчанию
.PHONY all
all: $(OUTPUTFILE)
# Собрать hello из hello.cpp
$(OUTPUTFILE) hello.cpp
g++ -o $@ $<
# Цели Install и clean как в примере 1 16
В командном сценарии g++ -o $@ $<
переменная $@
раскрывается как hello
, а переменная $<
раскрывается как hello.cpp
. Следовательно, make-файл из примера 1.17 эквивалентен файлу из примера 1.16, но содержит меньше дублирующегося кода.
make-файл в примере 1.17 может быть еще проще. На самом деле командный сценарий, связанный с целью hello
, избыточен, что демонстрируется выполнением make-файла из примера 1.18.
Пример 1.18. make-файл для сборки исполняемого файла hello с помощью GCC, измененный с помощью неявных правил
# Указываем целевой файл и директорию установки
OUTPUTFILE=hello
INSTALLDIR=binaries
# Цель по умолчанию
.PHONY: all
all: $(OUTPUTFILE)
# Говорим make пересобрать hello тогда, когда изменяется hello.cpp
$(OUTPUTFILE): hello.cpp
# Цели Install и clean как в примере 1.16
Откуда make знает, как собирать исполняемый файл hello из исходного файла hello.cpp , без явного указания? Ответ состоит в том, что make содержит внутреннюю базу данных неявных правил, представляющих операции, часто выполняемые при сборке приложений, написанных на С и С++. Например, неявное правило для генерации исполняемого файла из файла .cpp выглядит так, как в примере 1.19.
Пример 1.19. Шаблон правила из внутренней базы данных make
%: %.cpp
# исполняемые команды (встроенные):
$(LINK.cpp) $(LOADLIBS) $(LDLIBS) -о $@
Правила, первые строки которых имеют вид % xxx :% yyy
, известны как шаблонные правила (pattern rules) , а символ %
действует как подстановочный знак (wildcard) . Когда устаревшему пререквизиту не соответствует ни одно из обычных правил, make ищет доступные шаблонные правила. Для каждого шаблонного правила make пытается найти строку, которая при подстановке подстановочного знака в целевую часть правила даст искомый устаревший пререквизит. Если make находит такую строку, make заменяет подстановочные знаки для цели и пререквизитов шаблонного правила и создает новое правило. Затем make пытается собрать устаревший пререквизит с помощью этого нового правила.
Чтобы напечатать базу данных неявных правил GNU make , используйте make -p .
Например, при первом выполнении make-файла из примера 1.18 пререквизит hello
цели по умолчанию all
является устаревшим. Хотя hello
фигурирует как цель правила $(OUTPUTFILE): hello.cpp
, это правило не содержит командного сценария, и, таким образом, оно бесполезно для сборки файла hello. Следовательно, make выполняет поиск в своей внутренней базе данных и находит правило, показанное в примере 1.19. Подставляя в правило из примера 1.19 вместо подстановочного знака строку hello
, make генерирует следующее правило с hello
в качестве цели.
hello: hello.cpp
$(LINK.cpp) $(LOADLIBS) $(LDLIBS) -o $@
Пока все хорошо, но есть еще кое-что. Повторный взгляд на внутреннюю базу данных make показывает, что переменная LINK.cpp
по умолчанию раскрывается как $(LINK.cc)
. В свою очередь LINK.cc
по умолчанию раскрывается как
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
Наконец, переменная CXX
по умолчанию раскрывается как g++
, а четыре другие переменные — $(CXXFLAGS)
, $(CPPFLAGS)
, $(LDFLAGS)
и $(TARGET_ARCH)
— раскрываются как пустые строки. После выполнения всех этих подстановок получается следующее правило, которое теперь выглядит более знакомо.
hello: hello.cpp
g++ $^ -o $@
Запутались? Это не страшно. Если вы изучите приведенное объяснение и потратите некоторое время на изучение внутренней базы данных make , неявные правила приобретут смысл.
Теперь, когда вы увидели, как шаблонное правило из примера 1.19 приводит к тому, что make собирает исполняемый файл hello из исходного файла hello.cpp , вы можете спросить, почему было необходимо использовать столько промежуточных шагов. Почему вместо сложного правила из примера 1.19 во внутреннюю базу данных make просто не добавить правило
%: %.cpp
g++ $^ -о $@
Ответ состоит в том, что промежуточные переменные, такие как $(CXX)
, $(CXXFLAGS)
, $(CPPFLAGS)
и $(LDFLAGS)
, служат как точки настройки (customization points). Например, указав значение LDFLAGS
в командной строке, в make-файле или установив значение переменной среды, можно указать дополнительные флаги, передаваемые компоновщику. Переменные CPPFLAGS
и CXXFLAGS
играют схожую роль для опций препроцессора и компилятора C++ соответственно. А установив значение переменной CXX
, можно указать компилятор, отличный от GCC. Например, чтобы собрать hello с помощью Intel для Linux и используя make-файл из примера 1.18, вы должны в командной строке ввести make CXX=icpc
, предполагая, что переменные среды, необходимые для компилятора Intel, уже установлены.
Интервал:
Закладка: