Написание 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.

Другие вопросы по тегам