Reputation: 102205
According to the GNUmake manual, 5.9 Using Empty Recipes, I can do the following to create an empty recipe:
target: ;
I have an empty recipe that prints system information to help in troubleshooting:
.PHONY: system
system: ;
$(info CXX: $(CXX))
$(info CXXFLAGS: $(CXXFLAGS))
$(info GCC_COMPILER: $(GCC_COMPILER))
$(info CLANG_COMPILER: $(CLANG_COMPILER))
$(info INTEL_COMPILER: $(INTEL_COMPILER))
$(info SUN_COMPILER: $(SUN_COMPILER))
...
However, it ends with:
...
IS_MINGW: 0
IS_CYGWIN: 1
IS_OPENBSD: 0
IS_SUN: 0
make: Nothing to be done for 'system'.
For some reason, I made the leap an empty rule would be silent (obviously wrong). Is there a way to suppress the message "Nothing to be done for 'target'"? If so, how?
Upvotes: 4
Views: 1701
Reputation: 3186
I was in the same situation, and achieved what I wanted by just adding a "no-op" recipe to the rule.
The :
command is exactly that for the Bash/Bourne shell: a null operation.
.PHONY: vars
vars: # print Makefile variables and values
⇥ @:
⇥ @$(foreach V, \
⇥ ⇥ $(sort $(.VARIABLES)), \
⇥ ⇥ $(if $(filter-out environment% default automatic,$(origin $V)), \
⇥ ⇥ ⇥ $(info $V=$($V) ($(value $V))) \
⇥ ⇥ ␣) \
⇥ ␣␣)
Because $(info ...)
produces an side effect to standard out but doesn't actually create any work for the rule itself to do, make
sees it as an empty target, hence the warning message.
Upvotes: 0
Reputation: 80921
You've given the system
target a recipe by putting the $(info)
lines under it. Make doesn't care that they are all make context and not shell context recipe lines though. That's why adding ;
isn't doing anything. Your recipe is already not empty.
That all said you can either not use $(info)
there and use @echo
(or whatever) instead and you'll avoid that message.
Or you can go with just system: ;
and then a make-level conditional on system
being in MAKECMDGOALS
to then use $(info)
to display the information.
ifneq ($(filter system,$(MAKECMDGOALS)),)
$(info CXX: $(CXX))
$(info CXXFLAGS: $(CXXFLAGS))
$(info GCC_COMPILER: $(GCC_COMPILER))
$(info CLANG_COMPILER: $(CLANG_COMPILER))
$(info INTEL_COMPILER: $(INTEL_COMPILER))
$(info SUN_COMPILER: $(SUN_COMPILER))
endif
system: ;
Which would then let you use make target1 target2 system
and get the system output printed before the targets are run.
The above does output
make: `system' is up to date.
at the end though. To avoid that you need to actually give the rule a recipe.
system: ;@:
but that will actually run a shell (the empty recipe does not). So you get to decide on the trade-offs there.
Upvotes: 2