C++. Сборник рецептов - [37]
Например, чтобы из исходных файлов из примера 1.3 собрать исполняемый файл с помощью GCC в Unix, создайте такой make-файл, как показанный в примере 1.23.
Пример 1.23. make файл для hellobeatles.exe с использованием GCC
# Укажите исходные файлы, целевой файл, директории сборки
># и директорию установки
>SOURCES = hellobeatles.cpp
>OUTPUTFILE = hellobeatles
>LIBJOHNPAUL = libjohnpaul.a
>LIBGEORGERINGO = libgeorgeringo.so
>JOHNPAULDIR = ../johnpaul
>GEORGERINGODIR = ../georgeringo
>INSTALLDIR = ../binaries
>#
># Добавьте в путь поиска заголовочных файлов родительскую директорию
>#
>CPPFLAGS += -I..
>#
># Цель по умолчанию
>#
>.PHONY: all
>all: $(HELLOBEATLES)
>#
># Цель для сборки исполняемого файла.
>#
>$(OUTPUTFILE): $(subst .cpp,.о,$(SOURCES)) \
> $(JOHNPAULDIR)/$(LIBJOHNPAUL) \
> $(GEORGERINGODIR)/$(LIBGEORGERINGO)
> $(CXX) $(LDFLAGS) -o $@ $^
>.PHONY: install
>install:
> mkdir -p $(INSTALLDIR)
> cp -p $(OUTPUTFILE) $(INSTALLDIR)
>.PHONY: clean
>clean:
> rm -f *.o
> rm -f $(OUTPUTFILE)
>#Сгенерируйте зависимости .cpp-файлов от .hpp-файлов
>include $(subst .cpp,.d,$(SOURCES))
>%.d: %.cpp
> $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
> sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@..$$$$ > $@; \
> rm -f $@.$$$$
Далее в директории, содержащей johnpaul, georgeringo, hellobeatles и binaries, создайте главный make-файл, как показано в примере 1.24.
Пример 1.24. Главный make-файл для исходного кода из примеров 1.1, 1.2 и 1.3
># Все цели в этом make-файле — фиктивные
>PHONY: all johnpaul georgeringo hellobeatles
># Цель по умолчанию
>all: hellobeatles
># Цели johnpaul, georgeringo и hellobeatles представляют
># директории, командный сценарий вызывает make в каждой из них
>johnpaul georgeringo hellobeatles
>$(MAKE) --directory=$@ $(TARGET)
># Это правило указывает что цель по умолчанию make-файла
># в директории hellobeatles зависит от целей по умолчанию
># make-файлов из директорий johnpaul и georgeringo
>.PHONY: hellobeatles
>hellobeatles: johnpaul georgeringo
Чтобы собрать hellobeatles, перейдите в директорию, содержащую главный make-файл, и введите >make
. Чтобы скопировать файлы libjohnpaul.a, libgeorgeringo.so и hellobeatles в директорию binaries, введите >make TARGET=install
. Чтобы очистить проект, введите >make TARGET=clean
.
Подход к управлению сложными проектами, продемонстрированный в этом рецепте, известен как рекурсивный make (recursive make). Он позволяет организовать проект в виде набора модулей, каждый со своим собственным make-файлом, и указать зависимости между этими модулями. Он не ограничен одним главным make-файлом с набором дочерних make-файлов: эта методика может применяться для обработки многоуровневых древовидных структур. В то время, пока рекурсивный make был стандартной методикой управления большими проектами с помощью make, появились другие методы, которые теперь рассматриваются как более качественные. За подробностями снова обратитесь к Managing Projects with GNU make, Third Edition Роберта Мекленбурга (O'Reilly).
Пример 1.23 — это прямое применение методик, продемонстрированных в рецептах 1.15, 1,16 и 1.17. В нем есть один очень интересный момент. Как показано в рецепте 1.15, при компиляции hellobeatles.cpp из командной строки необходимо использовать опцию -I.., говорящую компилятору, где искать заголовочные файлы johnpaul.hpp и georgeringo.hpp. Одним из возможных решений является написание явного правила сборки hellobeatles.o с помощью командного сценария, содержащего опцию -I.. подобно этому.
>hellobeatles.o: hellobeatles.cpp
>g++ -с -I.. -о hellobeatles.o hellobeatles.cpp
Вместо этого я использовал точку настройки >CPPFLAGS
, описанную в рецепте 1.15, и указал, что всегда, когда происходит компиляция объектного файла из файла .cpp, в командную строку должна быть добавлена опция -I..:
>CPPFLAGS += -I..
Вместо оператора присвоения >=
я использовал >+=
, так что новое значение будет добавляться к тому значению >CPPFLAGS
, которое могло быть указано в командной строке или в переменной среды.
Теперь давайте посмотрим на то, как работает пример 1.24. Наиболее важным правилом является то, которое заставляет make вызываться для каждой из директорий johnpaul, georgeringo и hellobeatles.
>johnpaul georgeringo hellobeatles:
>$(MAKE) --directory=$@ $(TARGET)
Чтобы понять это правило, вы должны знать три вещи. Во-первых, переменная >MAKE
раскрывается как имя запущенного в данный момент экземпляра make. Обычно это будет >make
, но на некоторых системах это может быть >gmake
. Во-вторых, опция командной строки --directory=><path>
в качестве текущей директории. В-третьих, правило с несколькими целями эквивалентно набору правил, каждое из которых имеет по одной цели и которые содержат одинаковые командные сценарии. Так что приведенное выше правило эквивалентно следующим.
>johnpaul:
> $(MAKE) --directory=$@ $(TARGET)
>georgeringo:
> $(MAKE) --directory=$@ $(TARGET)
>hellobeatles:
> $(MAKE) --directory=$@ $(TARGET)
В свою очередь это эквивалентно:
>johnpaul:
> $(MAKE) --directory=johnpaul $(TARGET)
>georgeringo:
> $(MAKE) --directory=georgeringo $(TARGET)
>hellobeatles:
> $(MAKE) -directory=hellobeatles $(TARGET)
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.