2016-10-18 3 views
0

У меня есть основной Makefile для компиляции C файлы, необходимые для составления общей библиотеки, у меня есть ошибка, поскольку Makefile не признается:Правило не распознается в make-файле?

SOURCES=/home/test/project/sources 
OBJECTS=/home/test/project/objects 

$(OBJECTS)/%.o:$(SOURCES)/%.c 
$(CC) -fPIC -c $^ -o [email protected] 

sharedlib: $(OBJECTS)/%.o 
$(CC) -shared -o libsharedlib.so $< 

Когда я бегу сделать Я понимаю, что нет правила для цели: $(OBJECTS)/%.o необходимо sharedlib. Хотя правило написано прямо до sharedlib.

+0

Но подстановочные означало бы, что я скомпилировать все файлы сразу? – Bionix1441

+0

Я изменил его, но все тот же вопрос. – Bionix1441

+0

Вы пытаетесь скомпилировать libsharedlib.so со всеми объектами сразу? – 2501

ответ

4

Основная проблема заключается в том, что вы нигде не находитесь сообщают, что ваши исходные файлы. Начните делать это:

SOURCEDIR=/home/test/project/sources 
SOURCES=$(wildcard $(SOURCEDIR)/*.c) 

Затем вывести имена объектных файлов из имен исходных файлов путем замены .c для .o:

OBJECTDIR=/home/test/project/objects 
OBJECTS=$(patsubst $(SOURCEDIR)/%.c,$(OBJECTDIR)/%.o,$(SOURCES)) 

Вы все еще можете сохранить общие правила для создания объектных файлов:

$(OBJECTDIR)/%.o: $(SOURCEDIR)/%.c 
     $(CC) -fPIC -c $^ -o [email protected] 

Но вы даете явный список объектных файлов в правила, чтобы сделать sharedlib:

libsharedlib.so: $(OBJECTS) 
     $(CC) -shared -o [email protected] $< 

Обратите внимание, что я сделал имя правила таким же, как и файл, который создается. Это важно, потому что вызов, сделанный дважды подряд, затем пропустит создание библиотеки во второй раз. Вы всегда можете добавить псевдоним, если вы хотите:

sharedlib: libsharedlib.so 

В этом случае, это также хорошо, чтобы сказать, сделать что sharedlib не реальный файл:

.PHONY sharedlib 

Это предотвращает странные вещи случиться если вы в каталоге всегда был файл sharedlib.

+0

Еще одна проблема, и это когда я вызываю make на цель '$ (OBJECTDIR) /%. o': Я не получаю никакого правила, чтобы сделать цель' $ (OBJECTDIR) /%. o '? Не могли бы вы рассказать мне, почему? в основном makefile не выполняет правило '$ (OBJECTDIR) /%. o: $ (SOURCEDIR) /%. c', когда make вызывается в target sharedlib. – Bionix1441

+1

@ Bionix1441: потому что нет правила, которое буквально '$ (OBJECTDIR) /%. O'. Это всего лишь * шаблон *, и вы должны предоставить make с реальным именем файла, которое соответствует шаблону, прежде чем оно использует это правило. –

+0

Вы правы. наконец, я могу скомпилировать без проблем – Bionix1441

1

Правило библиотека

sharedlib: $(OBJECTS)/%.o 

не достаточно, чтобы сказать, сделать которые OBJS необходимы для библиотеки.

Это должно работать, и дает явный контроль, на которых источники/OBJS пары, которые вы хотите в библиотеке:

SOURCESDIR=/home/test/project/sources 
OBJECTDIR=/home/test/project/objects 

OBJLIST = \ 
    $(OBJECTS)/file1.o \ 
    $(OBJECTS)/file2.o 

$(OBJECTDIR)/%.o: $(SOURCESDIR)/%.c 
    $(CC) -fPIC -c $^ -o [email protected] 

sharedlib: $(OBJLIST) 
    $(CC) -shared -o libsharedlib.so $< 
+0

Я только заметил, что предложения относительно правила библиотеки в ответе выше G Sliepen очень подходят – AdRiX

+0

Спасибо за разъяснение. – Bionix1441