Почему переопределенная цель вызвана makefile - PullRequest
0 голосов
/ 31 января 2020

Мне нужно вызвать make следующим образом:

bin ?= bar                                                                      

all: ${bin}                                                                     

objects := 1.o 2.o                                                              

$(objects): %.o: ./%.cpp                                                        
▸   g++ -c  $< -o $@                                                            

foo: FORCE                                                                      
▸   bin=foo\                                                                    
▸   ▸   $(MAKE)·                                                                

${bin}: ${objects}                                                              
▸   g++  ${objects} -o ${bin}                                                  

FORCE:

т.е. целью по умолчанию является bar, но вызов foo target выполняется снова с переменной bin = foo. Проблема в том, что когда целевой foo переопределяется (во время второго вызова make), он всегда запускается (связывание) Этого можно избежать, если я использую другое имя цели:

foo_bla_bla: FORCE                                                                      
▸   bin=foo\                                                                    
▸   ▸   $(MAKE)

, в этом случае файл foo будет связан только тогда, когда объектные файлы изменились (правильно, что мне нужно). Но мне нужно использовать одно и то же имя для этой цели, чтобы вызвать make foo и получить таким образом foo bin. Так почему переопределение цели foo влечет за собой принудительное связывание?

1 Ответ

1 голос
/ 31 января 2020

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

Предварительные условия для цели foo все еще сохраняются, поэтому предварительное условие FORCE из Первая foo цель все еще там. Таким образом, цель foo всегда перестраивается.

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

ifneq ($(bin),foo)
foo: FORCE
▸   $(MAKE) bin=foo
endif

Но даже лучше, чем просто не использовать рекурсию вообще. Почему вам это нужно? Почему бы просто не сказать:

bar foo: ${objects}
▸   g++  ${objects} -o ${bin}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...