Я делю все коды .C
на две группы, одна A1_SRC
, а другая A2_SRC
. Обе группы имеют одинаковые коды заголовков const.h
и var.h
. Я прикрепляю свой Makefile ниже:
SHELL=/bin/bash
EXEC=../bin
OBJ=../obj
CC=mpicc
CFLAGS=-O3 -Wall -traceback
LFLAGS=-lm -lfftw3 -lstdc++ -lmpi
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
$(CC) $(CFLAGS) -MM $*.c > $(OBJ)/$*.d
A1_OBJ = $(A1_SRC:%.c=%.o)
A2_OBJ = $(A2_SRC:%.c=%.o)
A1_SRC = \
test.c \
alloc.c \
func.c
A2_SRC = \
test1.c \
test2.c
A1: $(A1_OBJ) const.h var.h
$(CC) $(LFLAGS) $(A1_OBJ) -o $(EXEC)/test_A1
A2: $(A2_OBJ)
$(CC) $(LFLAGS) $(A2_OBJ) -o $(EXEC)/test_A2
all: A1 A2
.PHONY: clean
clean:
rm -f $(OBJ)/*.o $(OBJ)/*.d $(EXEC)/*
install: clean all
-include $(A1_OBJ:.o=.d)
-include $(A2_OBJ:.o=.d)
Вот мои вопросы:
Я знаю, что $(CC) $(CFLAGS) -MM $*.c > $(OBJ)/$*.d
используется для создания файлов зависимостей. Но можно ли запустить под %.o: %.c
? Это правильное использование?
Я бы хотел, чтобы файлы .o
также хранились в каталоге $(OBJ)
(то же самое для файлов .d
). Как я могу добавить эту команду в Makefile?
По сравнению с A1: $(A1_OBJ) const.h var.h
, почему за A2: $(A2_OBJ)
нет const.h var.h
?
Можно ли с помощью некоторых хитростей объединить последние 2 строки -include $(A1_OBJ:.o=.d)
и -include $(A2_OBJ:.o=.d)
в 1 строку?
@Beta Полностью понимаю вашу точку зрения. Поскольку все эти вопросы относятся к одному Makefile с некоторым расширенным использованием, они будут очень полезны читателям, если люди ищут объектные файлы или зависимые файлы, или хотели бы имитировать пример Makefile для своих целей. Не могли бы вы ответить на мои вопросы, если знаете как? Большое спасибо.
Я рекомендую вам прочитать make.mad-scientist.net/papers/… и посмотреть, есть ли в нем какие-либо полезные идеи.
- Я знаю, что
$(CC) $(CFLAGS) -MM $*.c > $(OBJ)/$*.d
используется для создания файлов зависимостей. Но можно ли запустить под%.o: %.c
? Это правильное использование?
Да. На самом деле, он лучше всего подходит для этого контекста. Руководство GNU make
рекомендует не использовать $*
вне неявного правила (ярким примером которого являются шаблонные правила).
- Я бы хотел, чтобы файлы
.o
также хранились в каталоге$(OBJ)
(то же самое для файлов.d
). Как я могу добавить эту команду в Makefile?
Во-первых, вы не должны. Если вам нужна сборка вне исходного кода, используйте VPATH. В противном случае, зачем тратить время и усилия на усложнение make-файла и усложнение его обслуживания?
Но если вам нужно, то поймите, что make
не имеет разделения между файлом и каталогом, в котором он содержится. Вы не можете изменить каталог, в котором создается файл — вместо этого вы должны создать другой файл. В частности, если вы хотите, чтобы ваши файлы .o
были созданы в каталоге $(OBJ)
, то сначала измените правило %.o: %.c
на правило $(OBJ)/%.o: %.c
. И во-вторых, измените определения ваших правил A1_OBJS
и A2_OBJS
, чтобы они распространялись на списки файлов в $(OBJ)
.
- По сравнению с
A1: $(A1_OBJ) const.h var.h
, почему заA2: $(A2_OBJ)
нетconst.h var.h
?
Вы сказали, что это ваш make-файл. Кому ты рассказываешь.
Возможно, это ошибка. Возможно, источники A2 не зависят от этих заголовков. Возможно, второе правило полагается на ваше автоматическое создание зависимостей, но первое еще не получило сообщения.
- Можно ли с помощью некоторых хитростей объединить последние 2 строки
-include $(A1_OBJ:.o=.d)
и-include $(A2_OBJ:.o=.d)
в 1 строку?
Я не знаю. Вы считаете это...
-include $(A1_OBJ:.o=.d) $(A2_OBJ:.o=.d)
... задействовать трюки?
Директива include
ожидает список имен файлов для обработки. Неважно, какой механизм вы используете для их указания.
Спасибо за отличный ответ. Если я хочу указать путь к файлам .o
и .d
, могу ли я написать последнюю строку как -include $(A1_OBJ:$(OBJ)/.o=$(OBJ)/.d) $(A2_OBJ:$(OBJ)/.o=$(OBJ)/.d)
@John Bollinger
Ты пробовал это, @ThomasD? Даже если бы это сработало, почему вы предпочитаете это альтернативе, представленной в этом ответе?
1) Да. 2) Это можно сделать, приложив немного усилий. 3) Это похоже на оплошность. 4) Да. Пожалуйста, задавайте только один вопрос на вопрос.