mrjbom
@mrjbom

Как создать правило make для компиляции списка .c в список .out?

У меня имеется список исходных файлов и список файлов в которые они должны быть скомпилированы.
Как мне создать такое правило?

Я пробовал так:
.PHONY: all

SRCS = ./a/prog1.c ./a/b/prog2.c ./a/b/c/prog3.c
OUTS = ./outs/prog1.out ./outs/prog2.out ./outs/prog3.out

all: $(OUTS)

$(OUTS): $(SRCS)
	@echo compile $< to $@
	gcc $< -o $@

Но $(OUTS): $(SRCS) приводит такому выводу:
compile a/prog1.c to outs/prog1.out
compile a/prog1.c to outs/prog2.out
compile a/prog1.c to outs/prog3.out
  • Вопрос задан
  • 234 просмотра
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
У меня имеется список исходных файлов и список файлов в которые они должны быть скомпилированы.

SRCS = ./a/prog1.c ./a/b/prog2.c ./a/b/c/prog3.c
OUTS = ./outs/prog1.out ./outs/prog2.out ./outs/prog3.out

Это не очень удачная конфигурация, в том смысле, что немного изменив условия можно сильно упростить Makefile, но если очень хочется именно такого, то можно сделать так:

.PHONY: all

SRCS = ./a/prog1.c ./a/b/prog2.c ./a/b/c/prog3.c
OUTS = ./outs/prog1.out ./outs/prog2.out ./outs/prog3.out

all: $(OUTS)

define make_rule =
$(firstword $(1)): $(firstword $(2))
        @echo compile $$< to $$@
        gcc $$< -o $$@
$(if $(wordlist 2,$(words $(1)),$(1)),
     $(eval $(call make_rule,
                   $(wordlist 2,$(words $(1)),$(1)),
                   $(wordlist 2,$(words $(2)),$(2)))))
endef

$(eval $(call make_rule,$(OUTS),$(SRCS)))


Здесь происходит вот что: макрос make_rule принимает на вход два списка, создаёт правило, что первое слово из первого списка зависит от первого слова из второго списка, а потом вызывает сам себя со списками из которых удалены первые слова, если эти списки не пустые.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
includedlibrary
@includedlibrary
Например, так:
CC=gcc
CFLAGS=-std=c11 -Wall -O3
LDFLAGS=
OBJ=$(patsubst %.c, %.o, $(wildcard *.c))
TARGET=main
.PHONY: all clean
all: $(TARGET)
$(TARGET): $(OBJ)
	$(CC) $(LDFLAGS) $(OBJ) -o $(TARGET)
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@
clean:
	rm -f $(OBJ) $(TARGET)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы