Д. Стефенс - C++. Сборник рецептов
- Название:C++. Сборник рецептов
- Автор:
- Жанр:
- Издательство:КУДИЦ-ПРЕСС
- Год:2007
- Город:Москва
- ISBN:5-91136-030-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Д. Стефенс - C++. Сборник рецептов краткое содержание
Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.
C++. Сборник рецептов - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Это решение удобно только для очень небольших проектов, так как очень сложно постоянно отслеживать зависимости целей, представляющих собой исходные файлы, входящие в большую базу кода. К счастью, имеется несколько способов автоматической генерации этих зависимостей. Например, три последних правила примера 1.20 можно заменить на следующие.
# Генерируем зависимости .cpp-файлов от .hpp-файлов
include john.o paul.o johnpaul.о
%.d: %.cpp
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's.\($*\)\.o[ :]*.\1.o $@ : ,g' < $@.$$$$ > $@, \
rm -f $@.$$$$
Этот фрагмент кода основан на опции компилятора -M , которая заставляет GCC вывести в make-файл информацию о зависимостях. За подробным описанием того, как это работает, и почему иногда не подходит, обратитесь к книге Managing Projects with GNU make , Third Edition, написанной Робертом Мекленбургом (Robert Mecklenburg) (O'Reilly).
Код для генерации зависимостей помещайте в конец make-файла.
Так как большинство компиляторов имеет опцию, аналогичную опции -М GCC, этот метод может быть адаптирован для работы с большинством инструментов. На самом деле обычно эта опция называется -М или -m . Однако Visual C++ не имеет опции для генерации зависимостей в make-файле. При использовании Visual C++ есть две возможности. Можно использовать опцию -Gm совместно с опциями -Zi или -ZI , обсуждаемыми в рецепте 1.21. Опция -Gm говорит компилятору создать базу данных, сохраняемую в файле с расширением idb , содержащую информацию о зависимостях между исходными файлами. Файл . idb создается при первоначальной компиляции файла или набора файлов .cpp . При последующих компиляциях перекомпилируются только те исходные файлы, которые были изменены или зависят от изменившихся заголовочных файлов.
Кроме того, можно использовать опцию -showIncludes совместно с опцией -E . Опция -showIncludes приводит к тому, что компилятор при каждом обнаружении директивы include выводит в стандартный поток ошибок сообщение. Опция -E говорит компилятору запустить препроцессор и выйти, не создавая никаких двоичных файлов. С помощью небольшого сценария оболочки можно использовать вывод, сгенерированный -showIncludes ; для создания зависимостей в make-файле.
include john.d paul.d johnpaul.d
%d: %.cpp
"$(MSVCDIR)/bin/cl" -E -showIncludes $< 2> $@.$$$$ > /dev/null; \
sed -n 's/^Note: including file: *\(.*\)/$*.obj•$*.d:\1/gp' \
< $@.$$$$ | sed "s:\\:/:g:s: :\\ :gp" > $@; \
rm -f $@.$$$$
В этом примере символ • обозначает Tab.
Давайте сделаем еще одно последнее усовершенствование примера 1.20. В настоящий момент последовательность john paul johnpaul
содержится в двух местах — в пререквизитах правила для сборки статической библиотеки и в директиве include
, используемой для генерации зависимостей. Если список исходных файлов изменится, вам придется вносить изменения в двух местах make-файла. Гораздо лучше определить переменную SOURCES
и заменить оба использования последовательности john paul johnpaul
на выражения, использующие SOURCES
.
SOURCES = john.cpp paul.cpp johnpaul.cpp
...
# Собираем libjohnpaul.a из john.о, paul.o и johnpaul.о
$(OUTPUTFILE): $(subst .cpp, .o,$(SOURCES))
ar ru $@ $^
ranlib $@
...
# Генерируем зависимости .cpp-файлов от .hpp-файлов
include $(subst .cpp,.d,$(SOURCES))
%d: %.cpp
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*.\1.o $@ : .g' < $@ $$$$ > $@; \
rm -f $@.$$$$
Здесь я использую функцию make $(subst x , y , str )
, которая заменяет в строке str
все вхождения x
на y
.
GNU make поддерживает большое количество функций обработки строк и имен файлов, а также много других. Также она поддерживает определение пользовательских функций. Как обычно, за подробным описанием обратитесь к Managing Projects with GNU make , Third Edition Роберта Мекленбурга (O'Reilly).
Рецепты 1.2 и 1.7.
1.17. Сборка динамической библиотеки с помощью GNU Make
Вы хотите использовать GNU make для сборки динамической библиотеки из набора исходных файлов С++, таких как перечисленные в примере 1.2.
Вначале в директории, где должна быть создана динамическая библиотека, создайте make-файл и объявите фиктивную цель
all, единственным пререквизитом которой будет эта динамическая библиотека. Затем объявите цель динамической библиотеки. Ее пререквизитами должны быть объектные файлы, из которых она собирается, а ее командный сценарий должен представлять собой командную строку для сборки библиотеки из набора объектных файлов, аналогично показанному в рецепте 1.4. При использовании GCC или компилятора с похожим синтаксисом командной строки настройте, если требуется, неявные правила шаблонов, изменив одну или более переменных CXX
, CXXFLAGS
и т.п., используемых в базе данных неявных правил make , как показано в рецепте 1.15. В противном случае, используя синтаксис шаблонных правил, описанный в рецепте 1.16, напишите шаблонное правило, говорящее make , как с помощью командной строки из табл. 1.8 скомпилировать .cpp -файлы в объектные. Наконец добавьте цели install
и clean
, как показано в рецепте 1.15, и механизм для автоматической генерации зависимостей исходных файлов, как показано в рецепте 1.16.
Например, чтобы из исходных файлов, перечисленных в примере 1.2, собрать динамическую библиотеку с помощью GCC в Unix, в директории georgeringo создайте make-файл, показанный в примере 1.22.
Пример 1.22. make-файл для libgeorgeringo.so с использованием GCC
# Укажите расширения файлов, удаляемых при очистке
CLEANEXTS = o so
# Укажите исходные файлы, целевой файл и директорию установки
SOURCES = george.cpp ringo.cpp georgeringo.cpp
OUTPUTFILE = libgeorgeringo.so
INSTALLDIR = ../binaries
.PHONY: all
all: $(OUTPUTFILE)
# Соберите libgeorgeringo.so из george.o, ringo.о
# и georgeringo.o; subst - это функция поиска и замены.
# показанная в рецепте 1.16
$(OUTPUTFILE): $(subst .cpp,.o,$(SOURCES))
$(CXX) -shared -fPIC $(LDFLAGS) -о
.PHONY: install
install:
mkdir -p $(INSTALLDIR)
cp -p $(OUTPUTFILE) $(INSTALLDIR)
.PHONY: clean
clean:
for file in $(CLEANEXTS); do rm -f *.$$file; done
# Сгенерируйте зависимости файлов .cpp от файлов .hpp
include $(subst .cpp,.d,$(SOURCES))
%.d: %.cpp
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's. \($*\)\.o[ :]*.\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
make-файл из примера 1.22 — это прямое применение идей из рецептов 1.4, 1.15 и 1.16. Главным отличием между примерами 1.22 и 1.20 является правило для сборки libgeorgeringo.so из объектных файлов george.o , ringo.o и georgeringo.о .
Читать дальшеИнтервал:
Закладка: