2017-01-05 2 views
0

Я пытаюсь сделать миры простейшими (относительно общие) Makefile. Я могу использовать для проведения небольшой серии тестов, чтобы узнать C. По какой-то причине Makefile отказывается понимать мое неявное правило для создания объектных файлов c: %.o: %.c, я получаю no rule to make target %.o, необходимый test1.exe. Ниже мой Makefile в целом:Makefile не видит мое неявное правило

INC  = sglib 
CC  = gcc 
LD  = gcc 
LDFLAGS = 
# On MS-Windows, say "make os=win" to set proper extensions 
os = 
SO = 
EXE = 

ifeq ($(os), win) 
SO = dll 
EXE = .exe 
# -fPIC is a no-op on Windows, but causes a compiler warning 
CFLAGS = -std=gnu99 -ggdb3 -Wall 
else 
SO = so 
CFLAGS = -std=gnu99 -ggdb3 -Wall -fPIC 
endif 


all: test1$(EXE) 

test1$(EXE): %.o 
    $(LD) $< -o [email protected] 

lib-test.$(SO): %.o 
    $(LD) -shared $(LDFLAGS) -o [email protected] $< 

%.o: %.c 
    $(CC) $(CFLAGS) -I$(INC) -c $< -o [email protected] 

check: 
    echo Nothing yet! 

.PHONY: all clean 

clean: 
    rm -f *.o *.$(SO) test1$(EXE) 

Я использую msys на окнах 20 с gnu make 4.2.1 и gcc 6.2.0. Я озадачен тем, что там не так. это, наверное, что-то простое, но в настоящий момент я кажусь слепым.

+0

'% .o:% .c' сообщает, что он может скомпилировать' anything.c', чтобы получить 'anything.o'. Однако 'test1 $ (EXE):% .o' сообщает make, что он может связывать'% .o' (который получен путем компиляции '% .c' с использованием этого правила), чтобы получить' test1 $ (EXE) '. У вас есть файл с именем '% .c'? – immibis

+0

Whauh! Честно говоря, я не понимаю, что вы здесь делаете. «Пожалуйста, используйте ссылку редактирования на свой вопрос, чтобы добавить дополнительную информацию Кнопку Создать ответ следует использовать только для полных ответов на вопрос -.. Из обзора - Morten Jensen 6 часов назад» я не хочу чтобы добавить дополнительную информацию, я хотел поблагодарить тех, кто ответил на мой пост, и подтвердил, что они были полезными, и указал мне на правильное место. И теперь мне даже запрещено публиковать анонсов :-). Я очень смущен, но в любом случае, спасибо за помощь, наслаждайтесь и хорошо поработайте. – user1648090

+1

@ user1648090 То, как вы благодарите тех, кто отвечает, - это их ответы и/или принятие наиболее полезного. См. [Что делать, когда кто-то отвечает] (http://stackoverflow.com/help/someone-answers). Кроме того, посмотрите [тур]. – Barry

ответ

0

Вы, кажется, думают, что в правилах, как это:

test1$(EXE): %.o 

знака% является символом шаблона, который вызывает расширение имени файла - это не так. Если вы хотите создать список файлов .o, вы должны использовать встроенную функцию wildcard.

У меня есть пара статей в блогах об общих файлах makefile, начиная с https://latedev.wordpress.com/2014/11/08/generic-makefiles-with-gcc-and-gnu-make/, которые могут (или не могут) быть полезными.

3

Это:

test1$(EXE): %.o 

определяет правило, которое гласит, что предпосылкой цели test1 является файл %.o. Не какой-то подстановочный список объектных файлов. В частности файл с именем %.o. У вас нет другого правила в вашем файле makefile для создания этого файла, и он в настоящее время не существует, следовательно, ошибка, которую вы получаете.

% действует только в качестве заполнителя в Pattern Rules (и аналогичные функции, такие как patsubst), которые являются правилами, где % появляется в мишени. Так что ваши:

%.o : %.cpp 
    $(CC) $(CFLAGS) -I$(INC) -c $< -o [email protected] 

это шаблонное правило, из-за % в %.o. Это не создает правило построения цели %.o, а скорее любой файл с суффиксом .o. Это применимо при попытке создать цель foo.o - мы создадим неявное правило с preqrequiste foo.cpp, со стеблем %, соответствующими foo.

Что вы на самом деле хотите, чтобы подстановочные файлы ваших объектных файлов. Для этого есть функция:

test1$(EXE) : $(wildcard *.o) 

Но это на самом деле не работает. Когда вы пытаетесь построить первый раз, пока еще нет объектных файлов. Ясно. Итак, $(wildcard *.o) вернет пустую строку, и вы получите бессмысленность. Поэтому вы не можете их подставить.Вам необходимо явно предоставить эту строку:

test1$(EXE) : $(object_files) 
    $(LD) $< -o [email protected] 

Теперь мы просто должны придумать этот список:

source_files := $(wildcard *.c) 
object_files := $(source_files:.c=.o) 

Теперь, если у вас есть исходные файлы, такие как foo.c, bar.c и baz.c, функция $(wildcard) найдет их и установит source_files на номер foo.c bar.c baz.c. Подстановка на следующей строке установит object_files в foo.o bar.o baz.o. Таким образом, мы получаем test в зависимости от этих трех объектных файлов, и у вас уже есть правило шаблона для создания этих объектных файлов.

Смежные вопросы