Написание make-файла для сборки динамических библиотек - PullRequest
0 голосов
/ 06 апреля 2011

У меня есть 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 ]

2 голосов
/ 06 апреля 2011

Необходимо указать в цели all: предварительные условия.

На языке Makefile% - это шаблон, который можно использовать в автоматических правилах. Тем не менее, цель all: является простой целью без такого подстановочного знака, поэтому ${BIN}${COMPS}%.so неверно в этом контексте.

Обратите внимание, что когда я говорю «подстановочный знак» в этом контексте, этот подстановочный знак сопоставляет цель с предварительными условиями, а не с файловой системой, как * в выражениях glob.


Кроме того, если ваш харт находится в нужном месте, из соображений стиля ваш Makefile может быть лучше:

  • Промежуточные объекты не должны быть предпосылками для цели all, а должны быть только конечными целями, которые вы хотите отправить.
  • Существует набор автоматических и простых правил для определения создания объектов.
  • Обычно не пишут автоматическое правило для %.so, потому что библиотека часто состоит из более чем одного объекта.
  • Зависимости между объектом и заголовочными файлами - сложная проблема. Короче говоря, вам нужно указать, что результирующий объект зависит от *.cpp (или .c), а также от всех заголовков, включенных (прямо и косвенно) в файл *.cpp.
  • По соглашению, это хорошо поддерживается GNU make, вместо использования ${COMPILE}, как вы делаете, следует использовать $(CXX) для вашего компилятора C ++ и $(CXXFLAGS) для стандартных флагов, которые вы хотите передать этому компилятору. .
1 голос
/ 06 апреля 2011

Вам нужно что-то вроде

SOBJECTS = ...

all: ${BIN}main ${SOBJECTS}
     ...

Вам нужен способ собрать все * .so имена в переменной SOBJECTS.Вы можете сделать это вручную или использовать некоторые из внутренних функций make для сканирования исходного каталога.

Также обратите внимание, что я удалил два файла *.o как зависимости от цели all.Они не являются конечными целями сборки (я полагаю), поэтому вам не нужно упоминать их там.

Помимо этого есть другие стилистические моменты, которые я бы сделал по-другому, но на данный момент они не являютсявызывая непосредственные проблемы, поэтому я не буду отступать, но я советую вам взглянуть на некоторые учебные пособия, чтобы увидеть, как все это делается в целом.
Для начала посмотрите Правила создания файлов Пола , и Как не использовать VPATH .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...