Сделать предупреждение файла, переопределяя команды для цели
Как часть make файла, я хотел бы создать либо отладочную, либо выпускную версию цели.
Функционально все работает, однако я получаю предупреждения при запуске make
12 SRC := $(shell echo src/*.cpp)
13 SRC += $(shell echo $(TEST_ROOT)/*.cpp)
14
15 D_OBJECTS = $(SRC:.cpp=.o) # same objects will need to be built differently
16 R_OBJECTS = $(SRC:.cpp=.o) # same objects will need to be built differently
22 all: $(TARGET)
23
25 $(TARGET): $(D_OBJECTS)
26 $(CC) $(D_OBJECTS) -o $(TARGET)
27
28 $(D_OBJECTS) : %.o: %.cpp # ----- run with debug flags
29 $(CC) $(COMMON_FLAGS) $(DEBUG_FLAGS) -c $< -o [email protected]
30
31 release: $(R_OBJECTS)
32 $(CC) $(R_OBJECTS) -o $(TARGET)
33
34 $(R_OBJECTS) : %.o: %.cpp # ----- run with release flags
35 $(CC) $(COMMON_FLAGS) $(RELEASE_FLAGS) -c $< -o [email protected]
Когда я make
я получаю отладочную версию, когда я make release
я получаю версию выпуска.
Но я также получаю предупреждения:
Makefile:35: warning: overriding commands for target `src/Timer.o'
Makefile:29: warning: ignoring old commands for target `src/Timer.o'
Makefile:35: warning: overriding commands for target `test/TimerTest.o'
Makefile:29: warning: ignoring old commands for target `test/TimerTest.o'
С этими двумя вопросами:
- Любой способ игнорировать предупреждения
- Я делаю все правильно? Какие изменения необходимы?
Ответы
Ответ 1
Один из наиболее распространенных способов сделать это - поместить объекты выпуска и объекты отладки в отдельные подкаталоги. Таким образом, вы не получите переопределения правил для объекта, так как они будут иметь разные имена. Что-то вроде этого:
D_OBJECTS=$(SRC:%.cpp=debug/%.o)
R_OBJECTS=$(SRC:%.cpp=release/%.o)
RTARGET = a.out
DTARGET = a.out.debug
all : dirs $(RTARGET)
debug : dirs $(DTARGET)
dirs :
@mkdir -p debug release
debug/%.o : %.c
$(CC) $(DEBUG_CFLAGS) -o [email protected] -c $<
release/%.o : %.c
$(CC) $(RELEASE_CFLAGS) -o [email protected] -c $<
$(DTARGET) : $(D_OBJECTS)
$(CC) $(DEBUG_CFLAGS) -o [email protected] $(D_OBJECTS)
$(RTARGET) : $(R_OBJECTS)
$(CC) $(RELEASE_CFLAGS) -o [email protected] $(R_OBJECTS)
Ответ 2
Как и OP (Джеймс Леонард), я хотел бы подавлять или избегать предупреждений о переопределении целей Makefile
. Тем не менее, моя ситуация и цели разные.
Я хочу, чтобы Makefile
include base.mk
, и я хочу, чтобы Makefile
мог переопределять цели из base.mk
без каких-либо предупреждений. Я использую GNU Make.
Документация GNU Make описывает один из способов сделать это:
Создайте Makefile
следующим образом:
foo:
echo 'bar' > foo
%: force
@$(MAKE) -f base.mk [email protected]
force: ;
Источник: https://www.gnu.org/software/make/manual/html_node/Overriding-Makefiles.html
Вышеприведенный метод имеет (потенциально серьезный) недостаток, заключающийся в том, что он будет вызывать отдельный экземпляр $(MAKE)
, что означает, что (некоторые или все?) Переменные могут (не будут?) Не использоваться совместно родительскими и дочерними вызовами make.
К счастью, я нашел лучшее решение, как указано ниже:
Создайте base.mk
следующим образом:
foo-default:
echo 'foo-default'
bar-default:
echo 'bar-default'
%: %-default
@ true
Создайте Makefile
следующим образом:
include base.mk
foo:
echo 'foo Makefile'
Пример вывода:
$ make foo
echo 'foo Makefile'
foo Makefile
$ make bar
echo 'bar-default'
bar-default
Обратите внимание, что вам нужно иметь возможность контролировать имена целей в base.mk
чтобы вы могли называть их <target>-default
. Другими словами, вы не можете использовать этот подход для расширения произвольных базовых make файлов. Однако, если вы управляете и base.mk
и Makefile
, этот подход позволит вам создать один base.mk
а затем множество его настроек.
Ответ 3
Я выполнил свой собственный раздел о марках и комментариях, где напечатаны эти предупреждения. Работает как шарм. сделайте v4.2, read.c, вокруг строки 2114