Написание make-файла для сборки динамических библиотек
У меня есть make-файл в моем каталоге src. Makefile должен построить структуры данных, которые находятся в DataStructures/, а затем перебрать все файлы cpp в вычислениях / и создать соответствующий файл.so в../bin/calculations.
Я попробовал следующий синтаксис:
DAST = DataStructures/
COMPS = computations/
BIN = ../bin/
OBJECTS = ${DAST}Atom.o ${DAST}Molecule.o
COMPILE = g++ -Wall -g -c -std=c++0x -I/usr/local/include/openbabel-2.0 LINK = g++ -Wall -g -std=c++0x ${OBJECTS} -lopenbabel -I/usr/local/include/openbabel-2.0
all: ${BIN}main ${DAST}Molecule.o ${DAST}Atom.o ${BIN}${COMPS}%.so
${BIN}main: ${OBJECTS} main.cpp
${LINK} main.cpp -o ${BIN}main
${DAST}Molecule.o: ${DAST}Molecule.h ${DAST}Molecule.cpp
${COMPILE} ${DAST}Molecule.cpp -o ${DAST}Molecule.o
${DAST}Atom.o: ${DAST}Atom.h ${DAST}Atom.cpp
${COMPILE} ${DAST}Atom.cpp -o ${DAST}Atom.o
${BIN}${COMPS}%.o: ${COMPS}%.cpp
gcc -Wall -fPIC -c -lopenbabel $< -I/usr/local/include/openbabel-2.0 -std=c++0x
${BIN}${COMPS}%.so: ${COMPS}%.o
gcc -shared -Wl,-soname,libcsmtest.so.1 -o libcsmtest.so $@
clean:
rm -rf ${OBJECTS}
.PHONY: all clean
Но это, очевидно, не работает, так как я получаю следующий вывод:
shai@ubuntu:~/csm/csm2/src$ make all
make: *** No rule to make target `../bin/computations/%.so', needed by 'all'. Stop.
Спасибо
2 ответа
Вам необходимо указать в all:
цель, предпосылки явно.
На языке Makefile% - это шаблон, который можно использовать в автоматических правилах. Тем не менее all:
цель - простая цель без такого подстановочного знака, таким образом ${BIN}${COMPS}%.so
неправильно в этом контексте.
Обратите внимание, что когда я говорю "подстановочный знак" в этом контексте, этот подстановочный знак сопоставляет цель с предварительными условиями, а не с файловой системой, такой как *
сделать в выражениях глобус.
Кроме того, если ваш харт находится в нужном месте, то по стилю ваш Makefile может быть лучше:
- Посреднические объекты, не должны быть предпосылками
all
цель, но только конечные цели, которые вы хотите отправить. - Существует сочетание автоматических и простых правил для указания создания объектов.
- Обычно не пишут автоматическое правило для
%.so
потому что библиотека часто состоит из более чем одного объекта. - Зависимости между объектом и заголовочными файлами - сложная проблема. Короче говоря, вам нужно указать, что результирующий объект зависит от
*.cpp
(или же.c
) а также все заголовки, включенные (прямо и косвенно)*.cpp
файл. - По соглашению, это хорошо поддерживается GNU make вместо использования
${COMPILE}
как вы делаете, следует использовать$(CXX)
для вашего компилятора C++, и$(CXXFLAGS)
для стандартных флагов, которые вы хотите передать этому компилятору.
Вам нужно что-то вроде
СОБЫТИЯ = ... все: ${BIN}main ${SOBJECTS} ...
Вам нужен способ собрать все имена *.so в переменной SOBJECTS
, Вы можете сделать это вручную или использовать некоторые из make
внутренние функции для сканирования исходного каталога.
Также обратите внимание, что я удалил два *.o
файлы как зависимости от all
цель. Они не являются конечными целями сборки (я полагаю), поэтому вам не нужно упоминать их там.
Помимо этого есть и другие стилистические моменты, которые я бы сделал по-другому, но в данный момент они не вызывают непосредственных проблем, поэтому я не буду отступать, но я советую вам взглянуть на некоторые учебные пособия, чтобы увидеть, как все это делается в целом.
Для начала посмотрите правила Paul Makefile'ов и как не использовать VPATH.