Моя структура папок выглядит так:

.
├── app.c
├── inc
│   ├── butil.h
│   └── libs
│       ├── flagutil.h
│       ├── libflagutil.c
│       └── libflagutil.o
└── Makefile

Мой Makefile выглядит так:

CC = gcc
WARN = -Wall -Wconversion -Wextra -Wno-unused-variable -Wno-unused-parameter
DEBUG = -ggdb -O0

app: ./app.c ./inc/libs/flagutil.h ./inc/butil.h ./inc/libs/libflagutil.o
    $(CC) $(WARN) app.c ./inc/libs/libflagutil.o -o ./app

libflagutil.o: ./inc/libs/libflagutil.c ./inc/libs/flagutil.h 
    $(CC) $(WARN) ./inc/libs/libflagutil.c -c -o ./inc/libs/libflagutil.o

app-debug: ./app.c ./inc/libs/flagutil.h ./inc/butil.h ./inc/libs/libflagutil.o
    $(CC) $(WARN) $(DEBUG) app.c ./inc/libs/libflagutil.o -o ./app

Я немного озадачен его поведением. Допустим, я внес критическое изменение в файл ./inc/libs/flagutil.h . И app и libflagutil.o зависят от этого.

Затем я просто запускаю make . Поскольку app основного правила зависит от ./inc/libs/flagutil.h , и оно было изменено, выполняется строка под правилом.

НО, libflagutil.o , который зависит от app (основное правило), также зависит от ./inc/libs/flagutil.h , и его изменение может оказать критическое влияние на libflagutil.o , который, опять же, зависит от app

Однако простое выполнение make не выполняло правило libflagutil.o , что означает, что libflagutil.c не был перекомпилирован, а исполняемый файл app связан со старой версией libflagutil.o .

Это, конечно , может быть исправлено путем явного запуска make libflagutil.o после внесения изменений в /inc/libs/flagutil.h и только затем запустить основное правило, но не вся суть make , чтобы избежать неприятностей , таких как это один?

Я что-то упустил или такое поведение ожидается?

1 ответ1

2

Вам необходимо указать полные пути к файлам в целевых объектах правил, иначе make считает, что они находятся в текущем каталоге.

В вашем случае используйте

./inc/libs/libflagutil.o: ./inc/libs/libflagutil.c ./inc/libs/flagutil.h 

во втором правиле.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .