This document describes fundamentals of Cheops Makefiles. A natural follow-up to this file is the Howdy, World Primer, which describes the step-by-step process of writing and compiling the standard "Howdy, world" program.
We use the GNU/960 cross compiler and associated tools for compiling programs for Cheops. These tools are supported on Sun SPARC, IBM AIX/R6000, and DEC Ultrix/DECStation 5000 machines. Unfortunately, they aren't supported on either the HP700 or the DEC Alpha architectures at this time.
Cheops Makefiles require that your shell have all Cheops environment variables specified to describe the compile-time system configuration. To insure that your shell's path, environment variables and aliases are set up properly, refer to Host environment.
The proper way to set up your Makefile is to copy one of the following files from the path /mas/garden/cheops/doc to a Makefile in the directory in which you will write your source code.
Once you have copied a fresh template to your own directory (and named it Makefile, not Makefile.something ) you will need to modify it to suit your needs. Be careful to avoid altering those lines that say they should not be changed.
The ultimate target is either BINFILE for binary executable or LIBFILE for an archived set of object files. Which ever is appropriate, set the target to the name of the binary or the name of the library without the .a suffix.
The OBJS variable is a list of .o files that need to be linked or archived together to create the ultimate target. If the list gets long, put a backspace at the end of the line and put in a carriage return to get to the next line. For each file in the OBJS list, make will search for a corresponding .c or .s file in that directory and try to compile or assemble it to make a .o file.
This section lets you add command line options to the compiler and linker
Make, by default, creates a new target .o file if the corresponding .c or .s dependancy file is younger. To specify other useful dependancies the last section of your Makefile should list these.
Here's an example of how to define dependancies. Let's say we want to compile howdy.c and doody.c both of which include stuff.h and only doody.c includes cheops.h. howdy.o and doody.o are linked with libcheops.a to make the binary executable file, howdy. The additional dependancies should look like this:
${BINFILE} : $(CHEOPS_LOCAL_LIB)/libcheops.a ${OBJS} : ./stuff.h doody.o : ${CHEOPS_LOCAL_INC}/cheops.h
In developing assembly code, it is not unusual to make errors. The default set of rules for a local application aren't very helpful in this situation, as they pass a copy of the code through the C preprocessor, then pipe it into the assembler (which then refers to a line number in the piped stream). You can specify a separate set of compilation instructions in your Makefile which will override the defaults and produce a file which you can examine to localize the errors.
To do this for a file, file.s, use the following :
file.o: ; ${CP} $*.s $*_s.c ${CCP} $*_s.c -o $*_s.s ${AS} $*_s.s -o $@ ${RM} -f $*_s.c $*_s.s
The template Makefiles support several useful make targets that you should know about:
The template Makefiles keep track of the last system configuration that your code was last compiled under. The reason for this is that .o files compiled by different platforms are not compatible during the link or archive stage. To keep things straight, your Makefile automatically makes a .oldenv file in that directory which stores the values of environment variables that defines the current configuration. Each time make is invoked in your directory, the last compiled environment is compared to the current environment. If they don't match exactly, make clean all is automatically done to ensure that all .o files will be compatible.
While this is necessary to guarantee that .o are compatible, it can be bothersome to have to recompile all .o files each time you make for a different platform. Only the .c or .s files that have been altered should need to be recompiled. To solve this problem when developing code on different platforms alternately, the two make targets pre and post are useful in eliminating redundant compilation:
Thus if you always invoke make pre all post, then you will never need to recompile all .o files just because you are now on a new platform. Note: this procedure is primarily recommended only when the number of files in OBJS is large.
This implementation of template Makefiles supports having only a single ultimate target. If you require having multiple BINFILEs or LIBFILEs in a single directory, then do the following: