Makepp may be able to figure out how to compile and link
your program even if you specify no rules at all (or if you don't
even have a makefile). After every makefile is loaded,
makepp also loads a set of default rules. (These rules are
special in that they do not override any other rules in the
makefile.) The default rule database is stored in the file
makepp_builtin_rules.mk
in the makepp
distribution or library directory, so you can always look at that to
see exactly what the default rules are.
Makepp's builtin rules are almost the same as the rules in GNU make, except that it has no rules for some of the rare languages that GNU make supports. (This is deliberate; I often ran into trouble with GNU make on several projects that accidently reused some of the suffixes that GNU make assigned to those rare languages.) The rules use the same variables as GNU make, with some possibly useful additions. Makepp is smarter than GNU make about inferring which compiler to use, and which other objects and libraries to link in.
Makepp supplies default values for a number of variables. The most important of these variables are:
CC |
The C compiler. Makepp looks for gcc, cc, or some other variants on your system and tries to pick an appropriate compiler. |
CFLAGS |
-g unless you're using the GNU compiler, in
which case it's -g -Wall . |
CXX |
The C++ compiler. Makepp looks for g++, c++, cxx, or CC (and a few other variants) and tries to pick an appropriate value. |
CXXFLAGS |
-g unless you're using the GNU compiler, in
which case it's -g -Wall . |
F77 or FC |
The Fortran compiler. Makepp looks for f77, g77, or fort77. |
YACC |
yacc or bison -y , depending
on what you have on your system. |
LEX |
lex or flex , depending on what you
have on your system. |
Makepp defines a number of other variables. These are mostly for compatibility with other makefiles which depend on GNU make's defaults; your makefile should ordinarily not depend on builtin variables since that is often obscure to other readers of a makefile. If you have any questions about what any variable evaluates to, you can always put a line in your makefile like this:
dummy := $(print $(CC))
which simply prints the value of the $(CC)
variable
when the makefile is loaded.
In simplified form, here is approximately what the compilation rules look like. If you change the values of any of the indicated variables, the compilation command is changed as expected.
# # For C programs: # %.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ -c $(input) -o $(output) # # For C++ programs: # %.o: %.cxx # and also %.cc, %.cpp, %.c++, and %.C $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ -c $(input) -o $(output) # # For fortran programs: # %.o: %.f $(FC) $(FFLAGS) $(TARGET_ARCH) -c $(input) -o $(output) # # Yacc and lex: # %.c: %.y $(YACC) $(YFLAGS) $(input) mv -f y.tab.c $(output) %.c: %.l $(LEX) $(LFLAGS) -t $(input) > $(output)
Makepp also knows how to link programs, too.
Makepp attempts to be more clever than the standard Unix make
when it comes to figuring out a link command. Suppose you are
trying to build the target program xyz
. Makepp
will try to build this from xyz.o
, and (unlike the
standard unix make) it will also attempt to infer whether any other
objects or libraries need to be linked in.
The link rule looks something like this:
xyz: $(infer_objects xyz.o, *.o) $(inferred linker) $(inputs) $(inferred libraries) $(LOADLIBES) $(LDLIBS) $(LIBS) -o $(output)
infer_objects
attempts to infer what other
.o
files need to be linked in based on what .h
files are
included.
The "inferred linker" is a special bit of magic that turns into
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
if the sources are all straight C code, or
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
if some of the sources are C++, or
$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)
if some of the sources are Fortran.
The "inferred libraries" is another bit of magic that turns into
a list of libraries that makepp thinks you probably need to
link in based on what .h
files were included in the
sources. E.g., if you include jpeglib.h
, makepp
infers -ljpeg
; if you include png.h
, it
infers that you need -lpng
. This is currently
experimental, and I would not be surprised if it often misses
libraries. You can always supply additional libraries by setting
the values of LOADLIBES
or LDLIBS
or
LIBS
.
If you don't like the default rules, you can always turn them off. This can be done by adding a line like this to your makefile:
makepp_no_builtin = 1
For backward compatibility, makepp also turns off its default rules if you include this line somewhere in your makefile:
.SUFFIXES:
If you have suggestions for better default rules or other ideas on how makepp could more intelligently infer the build rules, please let me know.