* .c не восстанавливается при изменении зависимости xh, используя автоматически сгенерированный файл * .d - PullRequest
0 голосов
/ 03 января 2019

Я столкнулся с одной проблемой при обработке файлов зависимостей во время компиляции. Я просто даю вам сценарий, с которым я столкнулся в своем проекте.

У меня есть два исходных файла на языке C, которые называются a.c, b.c, в которые входит один заголовочный файл с именем c.h. Я запустил makefile, в котором есть инструкции для компиляции обоих файлов. Я могу успешно скомпилировать файл a.c, но я обнаружил некоторые ошибки при компиляции b.c, которые требуют внесения некоторых изменений в c.h, чтобы исправить эту проблему. После того, как я внес изменения в c.h и запустил сборку (инкрементная сборка), файл a.c тоже должен скомпилироваться, верно? Потому что a.c также зависит от файла c.h.

Я следовал всему механизму зависимости (создавая файлы автозависимости, включая .d файлы и т. Д.)

DEPSALL := $(wildcard $(patsubst %,%.d,$(basename $(TGTFILES)/*.c)))
-include $(DEPSALL)
$(TGTFILES)/%.o: $(TGTFILES)/%.c
        mkdir -p $(@D)
        $(CC64) -MT $@ -MMD -MP -MF $(patsubst %,%.d,$(basename $@)) -o $(@) -c $(CFLAGS64) $<
  ...
  ...

Я что-то здесь упускаю? Я хочу перестроить все файлы .c, включая определенный заголовочный файл, который я изменил.

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Ваш вопрос не завершен: вы на самом деле не описываете проблему, с которой сталкиваетесь (но мы, вероятно, можем догадаться, что объектные файлы не восстанавливаются, хотя они должны это делать), а часть показанного вами файла Makefile недостаточна для понимания ваших целей есть.

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

DEPSALL := $(wildcard $(patsubst %,%.d,$(basename $(TGTFILES)/*.c)))

бесполезно сложен. Это эквивалентно гораздо более простому и понятному:

DEPSALL := $(wildcard $(TGTFILES)/*.d))

Аналогично, в вашем рецепте компиляции вы можете заменить:

$(patsubst %,%.d,$(basename $@))

по:

$(TGTFILES)/$*.d

Но давайте вернемся к вашей основной проблеме (по крайней мере, я думаю, это ваша основная проблема): при изменении вашего заголовочного файла некоторые объектные файлы не перестраиваются, пока они должны.

Я думаю, вы думаете:

DEPSALL := $(wildcard $(patsubst %,%.d,$(basename $(TGTFILES)/*.c)))

назначит DEPSALL список файлов зависимостей, по одному на исходный файл, как это сделала бы другая форма:

DEPSALL := $(patsubst %.c,%.d,$(wildcard $(TGTFILES)/*.c))

Если это то, что вы думаете, тогда вы ошибаетесь. Ваша версия назначит DEPSALL список файлов зависимостей, которые существуют в $(TGTFILES), когда вы вызываете make. Если некоторые (или все) отсутствуют, некоторые объектные файлы не будут восстановлены ...

Предлагаю вам внимательно прочитать этот отличный пост об автозависимости Generation . Если вы адаптируете его к вашей настройке, вы должны получить что-то вроде:

TGTFILES := tgtfiles
SRCS     := $(wildcard $(TGTFILES)/*.c)
OBJS     := $(patsubst %.c,%.o,$(SRCS))
DEPS     := $(patsubst %.c,%.d,$(SRCS))
INCLUDES := include
CFLAGS   += -I$(INCLUDES)

.PHONY: objs clean

objs: $(OBJS)

%.o: %.c
%.o: %.c %.d
    $(CC) -MT $@ -MMD -MP -MF $*.Td $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
    @mv -f $*.Td $*.d && touch $@

%.d: ;
.PRECIOUS: %.d

clean:
    rm -f $(OBJS) $(DEPS)

include $(DEPS)

Некоторые аспекты могут выглядеть странно, бесполезно или даже совершенно неправильно. Но если вы внимательно прочитаете вышеупомянутый пост, то увидите, что в нем есть смысл. Демонстрация:

$ tree
.
├── Makefile
├── include
│   └── c.h
└── tgtfiles
    ├── a.c
    └── b.c

2 directories, 4 files
$ make
cc -MT tgtfiles/b.o -MMD -MP -MF tgtfiles/b.Td -Iinclude  -c -o tgtfiles/b.o tgtfiles/b.c
cc -MT tgtfiles/a.o -MMD -MP -MF tgtfiles/a.Td -Iinclude  -c -o tgtfiles/a.o tgtfiles/a.c
$ tree
.
├── Makefile
├── include
│   └── c.h
└── tgtfiles
    ├── a.c
    ├── a.d
    ├── a.o
    ├── b.c
    ├── b.d
    └── b.o

2 directories, 8 files
$ cat tgtfiles/a.d
tgtfiles/a.o: tgtfiles/a.c include/c.h

include/c.h:
$ make
make: Nothing to be done for 'objs'.
$ touch include/c.h 
$ make
cc -MT tgtfiles/b.o -MMD -MP -MF tgtfiles/b.Td -Iinclude  -c -o tgtfiles/b.o tgtfiles/b.c
cc -MT tgtfiles/a.o -MMD -MP -MF tgtfiles/a.Td -Iinclude  -c -o tgtfiles/a.o tgtfiles/a.c
0 голосов
/ 03 января 2019

wildcard приложение функции выглядит неправильно. Вероятно, должно быть:

DEPSALL := $(patsubst %,%.d,$(basename $(wildcard $(TGTFILES)/*.c)))
...