2014-10-23 2 views
1

Это мой первый пост в этом форуме. Извините за беспокойство, но я искал нечто похожее и странно, я не мог его найти. Вот проблема. У меня есть три (основных) файла без заголовков, и я хочу их скомпилировать сразу (если я просто набираю «make») или один за другим (если я укажу имя файла без расширения). Поэтому я построил свой Makefile, но что-то не так в командеmakefile компиляция кратных целей

$(TARGETS): $(BUILDS_DIR)% : $(SRCS_DIR)%.c 

, где я получил эту ошибку

марка: *** Никакое правило сделать цель ....

вот полный файл

.SUFFIXES: .c 
ROOT = $(addprefix $(PWD), /) 
BUILDS_DIR = $(addprefix $(ROOT), builds/) 
SRCS_DIR = $(addprefix $(ROOT), src/) 

SRCS = $(wildcard $(SRCS_DIR)*.c) 

TARGETS = ${SRCS:$(SRCS_DIR)%.c=%} 
EXES = ${addprefix $(BUILDS_DIR), $(TARGETS)} 

CC  = gcc 
CFLAGS = -Wall -O3 

RM = rm -f 

.PHONY: all $(TARGETS) clean 

all: $(TARGETS) 

$(TARGETS): $(BUILDS_DIR)% : $(SRCS_DIR)%.c 
    $(CC) $(CFLAGS) \ 
     $< \ 
     -o [email protected] 
    @echo -e "\n\n\t\t*** Compile successfully! ***\n" ; 

clean: 
    $(RM) $(EXES) \ 
     $(SRCS_DIR)*~ 
    @echo -e "\n\n\t\t*** Cleanup complete! ***\n" 

Где я ошибаюсь? Я думаю, что ответ очень глупый и, вероятно, основан на основной ошибке.

заранее спасибо

+1

'Нет правила, чтобы сделать цель' ... что? Какова полная ошибка? –

+1

Запустите 'make -d ...', это покажет вам, что делает 'make'. –

+0

Какой или кто 'make' вы используете? Это [GNU Make] (https://www.gnu.org/software/make/), найденный на большинстве/всех системах GNU/Linux, или 'make' из одного из проектов [BSD] (https: // www.freebsd.org/doc/en/books/developers-handbook/tools-make.html) или сторонний порт? GNU make иногда называется 'gmake'. NetBSD make иногда упоминается или доступен как пакет, известный как [bmake] (http://www.crufty.net/help/sjg/bmake.htm). Примечание. Cmake - это другая система сборки. Я _believe_ 'addprefix' и' wildcard' являются GNU Уточняю, тогда как '.SUFFIXES' довольно старый стиль и не должен быть лишним. – mctylr

ответ

0

Предполагая, что GNU Make (так как вы используете его синтаксис).

:, или первый, проблема в том, что вы пытаетесь переписать цель static pattern неправильно, пытаясь сцепить целевой каталог на шаблон, а не просто использовать имя файла цели.

Вы были:

$(TARGETS): $(BUILDS_DIR)% : $(SRCS_DIR)%.c 
    $(CC) $(CFLAGS) $< -o [email protected] 

Решение заключается в использовании добавить путь к каталогу, в командной строке

$(TARGETS): % : $(SRCS_DIR)%.c 
    $(CC) $(CFLAGS) $< -o $(BUILDS_DIR)[email protected] 
+0

Спасибо большое! на самом деле с этой коррекцией он отлично работает! – Stefano

0

Давайте предположим, что ваши три исходные файлы file1.c, file2.c и file3.c. Я бы создал Makefile, чтобы выглядеть следующим образом (предполагается, что GNU сделать)

CC = gcc 
CFLAGS = -ansi -Wall -pedantic 

RM = rm -f 

OBJS = file1.o file2.o file3.o 

PROG=my_program 

$(PROG) : $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o $(PROG) 

all : clean $(PROG) 

file1 : file1.c 
    $(CC) $(CFLAGS) -c file1.c -o file1.o 

file2 : file2.c 
    $(CC) $(CFLAGS) -c file2.c -o file2.o 

file3 : file3.c 
    $(CC) $(CFLAGS) -c file3.c -o file3.o 

clean : 
    $(RM) *.o $(PROG) *.*~ 

Пробу с помощью этого сделать файл (я использовать -n, чтобы показать, какие правила будут работать, но на самом деле не запускать их, потому что мой источник файлы пустые файлы для тестирования)

[******@broadsword junk]$ make -n 
    gcc -ansi -Wall -pedantic -c -o file1.o file1.c 
    gcc -ansi -Wall -pedantic -c -o file2.o file2.c 
    gcc -ansi -Wall -pedantic -c -o file3.o file3.c 
    gcc -ansi -Wall -pedantic file1.o file2.o file3.o -o my_program 
    [******@broadsword junk]$ make -n file1 
    gcc -ansi -Wall -pedantic -c file1.c -o file1.o 

Мы можем сократить выше делают подам использование решений диких-карт.

CC = GCC CFLAGS = -ansi -Wall -pedantic

RM = RM -f

OBJS = file1.o file2.o file3.o

PROG = my_program

$ (PROG): $ (OBJS) $ (CC) $ (CFLAGS) $ (OBJS) -o $ (PROG)

все: чистый $ (PROG)

%:% .c $ (CC) $ (CFLAGS) -c $ < -o $ @ о

чист. $ (RM) * .o $ (PROG) . ~

Нам нужно добавить '.o' к имени выходного файла, чтобы мы создавали файлы в формате, определенном переменной первого правила сборки, корректно работающим. Делать это дает следующий пример работает:

[******@broadsword junk]$ make -n 
    gcc -ansi -Wall -pedantic -c -o file1.o file1.c 
    gcc -ansi -Wall -pedantic -c -o file2.o file2.c 
    gcc -ansi -Wall -pedantic -c -o file3.o file3.c 
    gcc -ansi -Wall -pedantic file1.o file2.o file3.o -o my_program 
    [******@broadsword junk]$ make -n file2 
    gcc -ansi -Wall -pedantic -c file2.c -o file2.o 

Кстати, я лично не против вводить дополнительные два символа, и я люблю, когда моя цель матч вывод набора правил, которые задавят, поэтому я хотел бы написать правила или как

 file1.o : file1.c 
     $(CC) $(CFLAGS) -c file1.c -o file1.o 

или

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

Наконец, я сильно подозреваю, что, когда мы выполняем make или make all, мы не работают тыс е-файлов в нижней части make-файла, скорее мы запускаем встроенное правило, описанное в руководстве GNU, как: «n.o производится автоматически из n.c с рецептом формы $(CC) $(CPPFLAGS) $(CFLAGS) -c».

+0

Спасибо, это тоже работает, но моя идея состояла в том, чтобы пропустить объектные файлы, так как мне не нужно было связывать что-нибудь позже. но было бы более понятно и просто применить классический подход. Большое спасибо! – Stefano

+0

** Нет ** Пример вашего файла Makefile не рекомендуется. Кроме того, что он излишне сложный, он _less_ мощный, чем стандарт, встроенный в [неявные правила] (https://www.gnu.org/software/make/manual/html_node/Implicit-Rules.html). Наконец, не обязательно нормально «зависеть» от «чистой» цели. Это побеждает цель 'make' только перекомпилировать то, что изменилось. – mctylr

+0

Предлагаемая альтернатива: http://pastebin.com/EXR0ag9b – mctylr

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