I have a makefile with a valgrind target that looks like this:
# expects a file `test.keys` to exist; it can contain any numbers.
valgrind: $(PROG) test.keys
valgrind ./$(PROG) < test.keys
If I wanted to include valgrind flags such as --leak-check=full --show-leak-kinds=all, where would I put them? Do I put them right after valgrind:, or only on the second line before ./$(PROG) but after valgrind?
Thanks in advance!
The name "valgrind" appears twice in your rule because you are using it to mean two different things: it is the name of the analysis tool that you want to execute, and it is the name of your makefile rule, which is arbitrary. You could just as well have named your rule "pumpernickel":
pumpernickel: $(PROG) test.keys
valgrind ./$(PROG) < test.keys
The flags are to be passed to valgrind (the analysis tool) as if you were invoking it on the command line. That's what the second line is; that line is passed to the shell as a command. So that's where the flags belong.
P.S. Whatever name you choose for this rule, be aware that by default Make expects a rule with a given name to build a file with that name. This rule builds nothing, so you should use .PHONY to warn Make not to expect this rule to behave in the default way.
Related
In ffmpeg Makefile,
https://github.com/FFmpeg/FFmpeg/blob/master/Makefile#L37
https://github.com/FFmpeg/FFmpeg/blob/master/Makefile#L189
It defined phony targets "all" and "all-yes", but I can't find prerequisites and command of "all-yes" by searching whole ffmpeg directory. So can anyone help to explain what "all-yes" exactly means?
There is another "all" target in the "include $(SRC_PATH)/fftools/Makefile": https://github.com/FFmpeg/FFmpeg/blob/master/fftools/Makefile#L30
$(foreach P,$(AVPROGS-yes),$(eval $(call DOFFTOOL,$(P))))
all: $(AVPROGS)
fftools/ffprobe.o fftools/cmdutils.o: libavutil/ffversion.h | fftools
OUTDIRS += fftools
4.11 Multiple Rules for One Target
There can only be one recipe to be executed for a file. If more than one rule gives a recipe for the same file, make uses the last one given and prints an error message. (As a special case, if the file’s name begins with a dot, no error message is printed. This odd behavior is only for compatibility with other implementations of make… you should avoid using it). Occasionally it is useful to have the same target invoke multiple recipes which are defined in different parts of your makefile; you can use double-colon rules (see Double-Colon) for this.
There are two targets and make only uses the last one, so you could delete the "all-yes" or delete "all:all-yes" then use "make all" command, and it has no effect on the compilation. the command line "all:all-yes" is just ensure the "all" is the default target.
I encountered such pattern in makefile
CXXOBJ = f1.o f2.o f3.o
$(CXXOBJ): %.o: %.cpp
g++ -c $< -o $#
f1.o: f1.cpp f1.hpp f2.hpp
f2.o: f2.cpp f2.hpp f3.hpp macros.h
f3.o: f3.cpp f3.hpp
It works (at least with GNU make 4.0).
It uses generic recipe from 4th line,
but in addition uses dependencies defined at the bottom.
Questions
Is it standard make behavior? (or is it specific to GNU-make?)
Is it standard way to write make file? (i.e. are people usualy doing it this way or is it something 'exotic'?)
How exactly does it work?
How does make combine 2 distinct rules for same file? (just append dependency list or something more?)
(I was browsing through GNU-make manual, but could not find relevant part)
This is called static pattern rules (https://www.gnu.org/software/make/manual/html_node/Static-Usage.html). It is specific to GNU make. It might be useful when different targets require different recipes to build, but match the same pattern.
As for third question, there are no distinct rules for the same file. Everything is quite well defined, each target have corresponding .cpp file.
GNU Make manual:
One file can be the target of several rules. All the dependencies
mentioned in all the rules are merged into one list of dependencies
for the target....
There can only be one set of commands to be executed for a file. If
more than one rule gives commands for the same file, make uses the
last set given and prints an error message...
Although both names will do the job, what is the correct name for makefiles?
GNU `make' homepage uses Makefile, and I guess it is the good way to name it. Any reasons for typing the front M in upper case ?
What Name to Give Your Makefile chapter of GNU Make manual clarifies it:
By default, when make looks for the makefile, it tries the following names, in order: GNUmakefile, makefile and Makefile. Normally you should call your makefile either makefile or Makefile. (We recommend Makefile because it appears prominently near the beginning of a directory listing, right near other important files such as README.) The first name checked, GNUmakefile, is not recommended for most makefiles. You should use this name if you have a makefile that is specific to GNU make, and will not be understood by other versions of make. Other make programs look for makefile and Makefile, but not GNUmakefile.
I think that Makefile is displayed at the almost top of the list rather than makefile when using the ls command.
it is not only the reason that it appears prominently near the beginning of a directory listing, but also that it would cause a compile error when you using “makefile” to replace “Makefile”。 you could try to test in the helloworld case of Linux device driver..
I understand that # suppresses printing of a command in a Makefile...
http://www.gnu.org/software/make/manual/make.html#Echoing
... and I understand that $# is the target name...
http://www.gnu.org/software/make/manual/make.html#Automatic-Variables
... but I can't find any information on what a line like this might mean:
variable=#value#
I'm not trying to fix anything here, just trying to better understand Makefiles.
Update: The "Makefile Subsitutions" section of the GNU autoconf manual explains that it's a value that is substituted by autoconf.
Typically you find this in Makefile.in files, which are processed by configure (which are in turn generated by autoconf) scripts.
In that case #X# will be replaced by the value of a shell variable $X, if configure is told so. If it's not, no occurrence in the input file will be touched by configure, hence leaving the replaceable string as it is. If you ask me these instances indicate slips in the build system.
How to pass the entire command line (including goals, link lines, make options etc) from top level make to recursive make:
targets : prerequisites
$(MAKE) $(this should expand to top level command line) additional_args
Thanks.
I think the closest you can get is using a combination of $(MAKE), which contains the exact filename make was invoked with, $(MAKECMDGOALS), which contains the goals you specified on the command line, and $(MAKEFLAGS), which contains any variable definitions and (a subset of) the switches specified on the command line.
The $(MAKE) macro is special and expands to include some relevant options. See the section How the MAKE variable works in the Make documentation for more details. However, this doesn't include the complete line including goals etc, and I'm not sure that is possible.
Usually I try to avoid using Make recursively, there's a good article about that here: Recursive Make Considered Harmful.