Looking at the Catalogue of Implicit Rules several statements make me wonder:
The default suffix list is: .out, .a, .ln, .o, .c, .cc, .C, .cpp, .p, .f, .F, .m, .r, .y, .l, .ym, .lm, .s, .S, .mod, .sym, .def, .h, .info, .dvi, .tex, .texinfo, .texi, .txinfo, .w, .ch .web, .sh, .elc, .el. All of the implicit rules described below whose prerequisites have one of these suffixes are actually suffix rules.
Hm, not really?
$ make -p -f/dev/null | grep '%.o: %\.c$' -A2
%.o: %.c
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
Suffix .c
is in the list but it is defined as pattern rule?
Ok, it is also defines a suffix rule:
make -p -f/dev/null | grep '^.c.o:' -A5
.c.o:
# Implicit rule search has not been done.
# Modification time never checked.
# File has not been updated.
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
But why?
The suffix rule is defined after the pattern rule. The pattern rule should take precedence then, right?
But since the actions are equal what is the point?
Implicit rules tell make how to use customary techniques so that you do not have to specify them in detail when you want to use them. For example, there is an implicit rule for C compilation. File names determine which implicit rules are run.
Suffix rules are the old-fashioned way of defining implicit rules for make . Suffix rules are obsolete because pattern rules are more general and clearer. They are supported in GNU make for compatibility with old makefiles. They come in two kinds: double-suffix and single-suffix.
In computer system file names, a suffix is a convention for having one or more characters appended to a file name (usually separated from the file name with a dot) so that it can be distinguished from other files or grouped together with similar types of files.
A rule appears in the makefile and says when and how to remake certain files, called the rule's targets (most often only one per rule). It lists the other files that are the prerequisites of the target, and the recipe to use to create or update the target.
The listed pattern rules are applied. The suffix rules are only listed but not used.
When you dump Make's internal database using make -p -f /dev/null
it prints predefined rules and variables. The output is structured into different sections. For example my Make (v3.81) returns the following:
# GNU Make 3.81
# Copyright (C) 2006 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions.
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# This program built for i686-pc-linux-gnu make: *** No targets. Stop.
# Make data base, printed on Fri May 31 12:48:50 2013
# Variables
...
# Directories
...
# Implicit Rules
...
# Pattern-specific variable values
...
# Files
...
# VPATH Search Paths
....
Managing Projects with GNU Make and the GNU Make manual explains the different sections as follows:
The Variables section lists each variable along with a descriptive comment. Automatic variables aren't listed, though.
The Directories section is more useful to Make developers than to Make users. It lists the directories being examined by Make, including SCCS and RCS subdirectories that might exist, but usually do not. For each directory, Make displays implementation details, such as the device number, inode, and statistics on file pattern matches.
The Implicit Rules section follows. This contains all the built-in and user-defined pattern rules in make’s database.
The next section catalogs the pattern-specific variables defined in the makefile. Recall that pattern-specific variables are variable definitions whose scope is precisely the execution time of their associated pattern rule.
The Files section follows and lists all the explicit and suffix rules that relate to specific file. [A file in this context means a target]
The last section is labeled VPATH. It contains search paths and lists the value of VPATH and all the vpath patterns.
So the applied rules are listed in the 'Implicit Rules' section. The suffix rules are listed as part of the 'Files' section.
Everybody knows that the source is the only true documentation ;) So, true to the GNU spirit, I ventured into Make's sources trying to figure out what it's going on. Disclaimer: I've only poked around for about two hours - just long enough to get a general overview of Make's architecture.
Initialization phase: main.c : line 1600 (I merely removed a couple of #ifdefs that deal with different platforms):
/* Define the initial list of suffixes for old-style rules. */
set_default_suffixes ();
/* Define the file rules for the built-in suffix rules. These will later
be converted into pattern rules. We used to do this in
install_default_implicit_rules, but since that happens after reading
makefiles, it results in the built-in pattern rules taking precedence
over makefile-specified suffix rules, which is wrong. */
install_default_suffix_rules ();
/* Define some internal and special variables. */
define_automatic_variables ();
/* Set up the MAKEFLAGS and MFLAGS variables
so makefiles can look at them. */
define_makeflags (0, 0);
/* Define the default variables. */
define_default_variables ();
default_file = enter_file (strcache_add (".DEFAULT"));
default_goal_var = define_variable_cname (".DEFAULT_GOAL", "", o_file, 0);
// I removed the block that evalutes user input entered
// through the `--eval` switch for brevity
[...]
/* Read all the makefiles. */
read_makefiles = read_all_makefiles (makefiles == 0 ? 0 : makefiles->list);
/* Set up MAKEFLAGS and MFLAGS again, so they will be right. */
define_makeflags (1, 0);
/* Make each `struct dep' point at the `struct file' for the file
depended on. Also do magic for special targets. */
snap_deps ();
/* Convert old-style suffix rules to pattern rules. It is important to
do this before installing the built-in pattern rules below, so that
makefile-specified suffix rules take precedence over built-in pattern
rules. */
convert_to_pattern ();
/* Install the default implicit pattern rules.
This used to be done before reading the makefiles.
But in that case, built-in pattern rules were in the chain
before user-defined ones, so they matched first. */
install_default_implicit_rules ();
/* Compute implicit rule limits. */
count_implicit_rule_limits ();
/* Construct the listings of directories in VPATH lists. */
build_vpath_lists ();
-f /dev/null
.Build phase:
Later, when Make tries to build a target, it searches the rules database only. Rule searching is implemented in implicit.c .
Lastly I looked at the logic behind the --print-database
switch.
main.c : line 3078:
/* Print a bunch of information about this and that. */
static void
print_data_base ()
{
time_t when;
when = time ((time_t *) 0);
printf (_("\n# Make data base, printed on %s"), ctime (&when));
print_variable_data_base ();
print_dir_data_base ();
print_rule_data_base ();
print_file_data_base ();
print_vpath_data_base ();
strcache_print_stats ("#");
when = time ((time_t *) 0);
printf (_("\n# Finished Make data base on %s\n"), ctime (&when));
}
The print_rule_data_base() function is simply pretty printing all "active" rules. All existing suffix rules have previously been converted to pattern rules as well.
The print_file_data_base() function is listing all targets. The suffix rules are still in there. Actually, there doesn't seem to be a function to remove targets from the database. However, from what I've gleaned the suffix-targets are otherwise unused.
The very short answer is: the suffix rules are defined because POSIX make
requires them to be built-in. See the section named "Default Rules". The pattern rules are (non-POSIX) GNU value-add.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With