VPATH = <���путь-к-файлам-cpp>
Чтобы сказать make , что выполнять поиск определенных типов файлов требуется в определенном месте, используйте директиву vpath.
# искать файлы .exp в ../lib
vpath %. exp../lib
Смотри также
Рецепты 1.2 и 1.7.
1.16. Сборка статической библиотеки с помощью GNU Make
Проблема
Вы хотите использовать GNU make для сборки статической библиотеки из набора исходных файлов C++, таких как перечисленные в примере 1.1.
Решение
Вначале в директории, где должна быть создана статическая библиотека, создайте make-файл и объявите фиктивную цель all, единственным пререквизитом которой будет статическая библиотека. Затем объявите цель статической библиотеки. Ее пререквизитами должны быть объектные файлы, входящие в состав библиотеки, а ее командный сценарий должен представлять собой командную строку для сборки библиотеки из набора объектных файлов, аналогично показанному в рецепте 1.3. При использовании GCC или компилятора с похожим синтаксисом командной строки настройте, если требуется, неявные правила шаблонов, изменив одну или более переменных CXX, CXXFLAGSи т.п., используемых в базе данных неявных правил make , как показано в рецепте 1.15. В противном случае, используя синтаксис шаблонных правил, описанный в рецепте 1.16, напишите шаблонное правило, говорящее make , как с помощью командной строки из табл. 1.8 компилировать .cpp -файлы в объектные. Далее явно или неявно объявите цели, указывающие, как каждый из исходных файлов библиотеки зависит от включаемых в него заголовков. Эти зависимости можно описать вручную или сгенерировать их автоматически. Наконец, добавьте цели installи clean, как показано в рецепте 1.15.
Например, чтобы с помощью GCC в Unix собрать из исходных файлов, перечисленных в примере 1.2, статическую библиотеку, создайте в директории johnpaul make-файл, показанный в примере 1.20.
Пример 1 20. make-файл для создания libjohnpaul.a с помощью GCC в Unix
# Укажите расширения файлов, удаляемых при очистке
CLEANEXTS - о а
# Укажите целевой файл и директорию установки
OUTPUTFILE = libjohnpaul.a
INSTALLDIR = ../binaries
# Цель по умолчанию
.PHONY: all
all: $(OUTPUTFILE)
# Соберите libjohnpaul.a из john.o. paul.o и johnpaul.с
$(OUTPUTFILE): john.o paul.o johnpaul.о
ar ru $@ $^
ranlib $@
# Для сборки john.o, paul.o и johnpaul.о из файлов .cpp
# правила не требуются; этот процесс обрабатывается базой данных
# неявных правил make
.PHONY: install
install:
mkdir -p $(INSTALLDIR)
cp -p $(OUTPUTFILE) $(INSTALLDIR)
.PHONY: clean
clean:
for file in $(CLEANEXTS); do rm -f *.$$file; done
# Укажите зависимости файлов cpp от файлов .hpp
john.o: john.hpp
paul.o: paul.hpp
johnpaul.o: john.hpp paul.hpp johnpaul.hpp
Аналогично, чтобы собрать статическую библиотеку с помощью Visual С++, ваш make-файл должен выглядеть, как показано в примере 1.21.
Пример 1.21. make-файл для создания libjohnpaul.lib с помощью Visual C++
# Укажите расширения файлов, удаляемых при очистке
CLEANEXTS = obj lib
# Specify the target file and the install directory
OUTPUTFILE = libjohnpaul.lib
INSTALLDIR = ./binaries
# Шаблонное правило для сборки объектного файла из файла .cpp
%.obj: %.cpp
"$(MSVCDIR)/bin/cl" -с -nologo -EHsc -GP -Zc:forScope -Zc:wchar_t \
$(CXXFLAGS) S(CPPFLAGS) -Fo"$@" $<
# Фиктивная цель
.PHONY: all
all: $(OUTPUTFILE)
# Соберите libjohnpaul.lib из john.obj, paul.obj и johnpaul.obj
$(OUTPUTFILE): john.obj paul.obj johnpaul.obj
"$(MSVCDIR)/bin/link" -lib -nologo -out:"$@" $^
.PHONY: install
install:
mkdir -p $(INSTALLDIR)
cp -p $(OUTPUTFILE) $(INSTALLDIR)
.PHONY: clean
clean:
for file in $(CLEANEXTS); do rm -f *.$$file; done
# Укажите зависимости файлов .cpp от файлов .hpp
john.obj: john.hpp
paul.obj: paul.hpp
johnpaul.obj: john.hpp paul.hpp johnpaul.hpp
В примере 1.21 я с помощью переменной среды MSVCDIR, устанавливаемой в vcvars32.bat , показал команду Visual C++ link.exe как "$(MSVCDIR)/bin/link". Это позволяет избежать путаницы между компоновщиком Visual C++ и командой Unix link , поддерживаемой Cygwin и MSYS. Для полноты картины я также использовал MSVCDIR для команды компиляции Visual С++.
Обсуждение
Давайте подробно рассмотрим пример 1.20. Вначале я определяю переменные, представляющие выходной файл, директорию установки и расширения файлов, которые должны удаляться при сборке цели clean. Затем я объявляю цель по умолчанию all, как в примере 1.14.
Читать дальше