Ответ находится в руководство GCC: используйте эти -MT
флаг.
-MT target
Изменение цель правила испущена поколением зависимости. По умолчанию CPP берет название основного входного файла, удаляет любые компоненты каталога и любой суффикс файла такой как
.c
, и добавляет обычный объектный суффикс платформы. Результатом является цель.
-MT
опция поставит цель, чтобы быть точно строкой, которую Вы определяете. Если Вы хотите несколько целей, можно определить их как отдельный аргумент к-MT
, или использование приблизительно-MT
опции., Например,
-MT '$(objpfx)foo.o'
мог бы дать$(objpfx)foo.o: foo.c
Хорошо, только для проверки у меня есть право вопроса: я предполагаю, что Вы имеете test.c
, который включает test.h
, и Вы хотите генерировать subdir/test.d
(в то время как не генерация subdir/test.o
), где subdir/test.d
содержит
subdir/test.o: test.c test.h
, а не
test.o: test.c test.h
, который является тем, что Вы получаете прямо сейчас. Это правильно?
я не смог придумать простой способ сделать точно, что Вы просите. Однако смотря Улучшения Поколения Зависимости , если Вы хотите создать .d
файл при генерации.o файла можно использовать:
gcc $(INCLUDES) -MMD $(CFLAGS) $(SRC) -o $(SUBDIR)/$(OBJ)
(Учитывая SRC=test.c
, SUBDIR=subdir
, и OBJ=test.o
.) Это создаст и subdir/test.o и subdir/test.d, где subdir/test.d
содержит желаемый вывод как выше.
Если существует аргумент GCC, чтобы сделать это, я не знаю, каково это. Мы заканчиваем тем, что передали вывод зависимости по каналу до sed для перезаписи всех случаев <blah>.o
как ${OBJDIR}/<blah>.o
.
[GNU] делают, становится сердитым, если Вы не помещаете вывод в текущий каталог. Необходимо действительно работать, делают из каталога сборки и используют VPATH, делают переменную для определения местоположения исходного кода. При лжи о компиляторе рано или поздно он возьмет свою месть.
, Если Вы настаиваете на том, чтобы генерировать свои объекты и зависимости в некотором другом каталоге, необходимо использовать -o
аргумент, как отвеченный Emile.
Я предполагаю, что вы используете GNU Make and GCC. Сначала добавьте переменную для хранения списка файлов зависимостей. Предположим, что у вас уже есть такая переменная, которая перечисляет все наши исходники:
SRCS = \
main.c \
foo.c \
stuff/bar.c
DEPS = $(SRCS:.c=.d)
Затем включите сгенерированные зависимости в makefile:
include $(DEPS)
Затем добавьте это правило шаблона:
# automatically generate dependency rules
%.d : %.c
$(CC) $(CCFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -MT"$(<:.c=.o)" "$<"
# -MF write the generated dependency rule to a file
# -MG assume missing headers will be generated and don't stop with an error
# -MM generate dependency rule for prerequisite, skipping system headers
# -MP add phony target for each header to prevent errors when header is missing
# -MT add a target to the generated dependency
"$@" - цель (вещь с левой стороны : ), "$<" - необходимое условие (вещь с правой стороны : ). Выражение "$(<:.c=.o)" заменяет расширение .c на .o.
Хитрость здесь в том, чтобы сгенерировать правило с двумя целями, дважды добавив -MT; это делает и .o файл, и .d файл зависимыми от исходного файла и его заголовков; таким образом, файл зависимости автоматически регенерируется при изменении любого из соответствующих .c или .h файлов.
Опции -MG и -MP не дают сбиться с толку, если заголовочный файл отсутствует.