Using Make.Common
Make.Common is a file meant to be used with
GNU make (see also: info pages
and man page). To use it, simply
include it twice in your regular Makefile, once at the
beginning and once at the end. (Using the include directive... see
Make.Common itself for examples.)
Restrictions (Read: Keep It Simple Stupid)
You must only have one executable or library generated
per director leaf and the executable or library must
be named the same as the directory it is in. You can, however,
create a directory structure as deep as is needed to keep the
right things grouped together. Just remember to create a symlink
to Make.Common in the level above when you make a directory tree
deeper. (See how /cfht/src/pegasus/cli/ is set up
for some good examples too.)
Shell scripts (can be more than one) must all be named *.sh and
appear in a subdirectory somewhere in your tree called ./scripts/.
When these are installed in the bin directory, the .sh is stripped off
so you invoke as their "basename".
Configuration files (par files, bitmap files, etc.) must be kept
together in a directory called ./confs/ and will get copied
to /cfht/conf/ during a "make install" if needed.
Some wording you'll find below:
/cfht/src/medusa/project-"head"-directory/
.../project-"head"-directory/"leaves"
Standard Targets Provided by Make.Common
make world
- If you have a project that is divided into other subdirectories
and you run "make world" in the head directory, all subdirectories
will be built with "make all install". If you run "make world" in
one of the leaves, it will change to the head directory and run
"make all install" from there. So you can use "make world" from
anywhere within a sub-project to build the whole thing.
make all
- In a head directory for a subproject, runs "make all" in all the
subdirectories. In a leaf, builds either the library or the
executable for that subdirectory. Note that "make all" from
a subproject head directory may cause some targets to be
installed also (i.e., libraries that are required by one of
the other targets.)
make preinstall
- This exists to make complete releases build properly. It is used mainly
to install header files. For example, if library A and library B both
need each other's header files in order to compile, this is the
way to deal with this chicken-and-egg problem.
make install
- In a head directory for a subproject, runs "make install" in all
the subdirectories. In a leaf, installs (and builds, if it is
out of date) the library or executable in .../lib/ or .../bin/,
respectively.
make clean
- Removes emacs backup files and all object files in the "/cfht/obs/project/"
directory.
make depend
- Your Makefile should not be checked in to RCS when you do this.
Running "make depend" will append the list of C source file
dependencies (generated by "gcc -MM") to your Makefile.
make execlist
- Prints a list of all the programs with their runnable names (shell
scripts will have the .sh removed) from this directory level down.
This is the list of things that gets versioned and installed in
.../bin/ when you do "make install".
make titles
- Generates emacs parsable output of the results of a search of
your code for "===" and "%%%" markers. Files in each subdirectory
are expected to be summarized in a file called "Index". (See
/cfht/src/pegasus/libCFHT++/Index, for an example.)
Copyright headers are automatically inserted into known file types,
and DOS newlines (if found) are changed back to unix newlines.
The modification time-stamp on the file is not altered.
make tar
- Makes a tar file of the current directory tree, excluding RCS
subdirectories and emacs backup files.
Ways to turn on other options from the command line:
make TARGET=VXSPARC
- Cross compilation! Assuming there's a block already in Make.Common
for TARGET=VXSPARC, this will select a different compiler, linker,
and obj.CROSSCC/ directory to place the binaries. No modifications
needed to your Makefile. Add new cross-configurations to Make.Common.
make obj/program-pure
- Assuming you have "$(EXECNAME) $(EXECNAME)-pure: $(OBJS)..."
instead of just "$(EXECNAME): $(OBJS)" in your Makefile, this will
produce a purified copy of the program which you can then copy or
rename if needed.
make EXTRA_CFLAGS="-pg"
- If you have already used EXTRA_CFLAGS in the Makefile, this will
override. The example above causes the program to be compiled
with gprof profiling support. You must do a "make clean" if this
is the first time you are compiling for gprof.
make EXTRA_CFLAGS="-DDEBUG -DDEBUGDEBUG"
- Use this notation to include any arbitrary defines that you want
your code to see, for this invocation of make only. Don't worry
about the fact that these extra flags get passed even at link time;
gcc will simply ignore them where-ever they do not apply.
make EXTRA_CFLAGS="-g" ?????
- Don't do this, and don't try to remove the `-g' from the default
options either. GCC can handle doing optimizations while also putting in
debugging symbols. The installed versions are always stripped,
however, so run the one in the project's ./bin/ directory if you
want one with debugging symbols. It is even possible to analyze
cores dumped by one of the stripped versions if you rebuild the
exact same executable with symbols again (or if you still have the
unstripped version in the ./bin/ directory. Here's an example of
how gdb could be invoked on one of these cores:
gdb --symbols=/cfht/obs/dumper/dumper --exec=/cfht/bin/dumper --core=.../core
Variables You May Want to Override or Add to
VERSION
- Normally this is the date, in the form YYMMDD, but you can override
this with something like "1.1" if you prefer.
CONFS
- Contains *.def *.par *.bm *.xbm *.rdb *.xrdb, any of which may or
may not exists, but they must all be a subdirectory called "conf".
During "make install" they are all copied to "dev/conf". If you
override, do not include the "conf/" part of the the filenames.
SCRIPTS
- Contains *.sh. To limit the list to only specific .sh files within
your scripts/ directory, list only the names of those files, but
the MUST all still be .sh files. (See restrictions at top of
document.)
SUBDIRS
- If you define this, only SCRIPTS and CONFS are installed at this
level, and then each of the directories named in SUBDIRS are recursed
into. Do not list "scripts" and "conf" in this list. They are
handled automatically. Also, all built programs must live at
the "leaves" of the directory tree, so there cannot be a program
at a directory level that defines SUBDIRS.
SRCS
- Contains *.c and *.cc by default. OBJS is generated from SRCS
.cc and .c with .o. If you override SRCS, OBJS will be adjusted
accordingly.
HDRS
- Contains *.h and *.hh by default. If you have internal-only
header files, then you can either place those in a subdirectory
called "internal" and #include them with "internal/foo.h", OR
explicitly override HDRS in your Makefile.
EXTRA_CFLAGS
- This variable is normally empty. Anything you put in it will
be passed as extra options during the compile and link stages.
If you have things that don't belong in CCDEFS or CCINCS (below)
just stick 'em in here.
CCWARN
- The defaults for CCWARN are "-Wall -Wstrict-prototypes", but you might
want to override (with "CCWARN=...") or add to (with "CCWARN+=...") in
the Makefile. If a project compiles cleanly without any warnings, one
way to keep it that way is to add
CCWARN += $(WERROR)
so that any warnings will prevent compilation (as if they were errors.)
[Note: this assumes that there is a file Make.Local in the toplevel
src/ directory which defines "WERROR = -Werror". We have this at
CFHT in our copy of the source trees.]
CCDEFS
- This will contain defines to be passed to the C source code. You can
add your own with "CCDEFS+=..." in the Makefile. Be sure to use +=
because any -Dxxxx from Make.Common itself are important to the build
process. At most one of the following will be defined, if a known
system type was detected:
-DSUNOS - SunOS 4.1.x
-DSOLARIS - SunOS 5.x
-DHPUX - HP-UX 9 or 10
-DLINUX - Linux 1.x or 2.x
-DCYGWIN32 - Cygnus win32 on Windows NT
So you can do things like this in the C code:
#include <sys/socket.h>
#ifdef SUNOS
/* Old Suns lack prototypes for these... */
int socket(int domain, int type, int protocol);
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
int listen(int s, int backlog);
#endif
. . .
In addition, the following -D's may come from Make.Common under the
following conditions:
-DNO_CFHTLOG - If /tmp/pipes/syslog.np was not found at compile-time.
-DUSE_EPICS - If this machine is one on which we want EPICS channel access.
-DHACK_SELECT - If target OS (HP-UX 9) has messed up select() prototype,
requiring use of SELECT() macro in place of select().
(In other cases, missing_protos.h defines SELECT to select,
so always use SELECT() in your code. Only missing_protos.h
needs to worry about HACK_SELECT.)
-DHACK_XLIBS - Another obscure work-around, only for un-patched HP-UX 9
systems that have buggy X-libraries in /usr/lib. Only
"hform" uses this.
-D__USE_FIXED_PROTOTYPES__ - Enables some extra prototypes in the gcc-fixed
include files on our SUNOS machines. Not of
interest to user code.
-DEXIT_FAILURE=1 - Only on SUNOS, which forgets this in stdlib.h.
-DEXIT_SUCCESS=0 - Only on SUNOS, which forgets this in stdlib.h.
On our primary development system, HP-UX 10, only -DHPUX usually appears,
and possibly -DUSE_EPICS.
CCINCS
- Use "CCINCS+=-I..." to append to the list of directories for include files.
CCLIBS
- Use "CCLIBS+=-L..." to append to the list of directories to search for libraries.
CCLINK
- Set this to a list of "-llibname" options for linking. For example, if your program
requires symbols from "libm.a", use
CCLINK += -lm
CCINCSX11, CCLIBSX11, CCLINKX11
- These contain extra include paths, library paths, and library names, respectively,
to be used with X-applications. Since vendors put these in different places,
having these variables defined makes it easy within projects to indicate a program
needs X by just saying:
CCINCS += $(CCINCSX11)
CCLIBS += $(CCLIBSX11)
CCLINK += $(CCLINKX11)
CCLINKNET
- Any application that uses unix networking stuff (sockets, hostname lookup, etc.)
should add the following to their Makefile:
CCLINK += $(CCLINKNET)
Because some platforms (namely new Sun Solaris) need to add "-lsocket" and "-lnsl"
in the link stage for the proper network routines. Other platforms may need
a "-lresolv" here also for hostname lookup. Simply using CCLINKNET takes
care of whatever might be needed here.
Variables That Might Be Useful in the Makefile
HOSTNAME
- Contains the name of the host that the project is currently being
built on, as returned by the hostname command.
TARGET
- This is the equivalent of the "SUNOS", "SOLARIS", "HPUX" symbols defined
for C programs, for use within the Makefile. If you wanted certain projects
to be built only on a certain architecture, you could use this variable.
It contains the name of the operating system, as returned by "uname -s" followed
by a dash (-) and the major revision of the OS. For SunOS, this is either
a 4 or a 5, and for HP it is either an A (version 9) or a B (version 10).
For example, to have certain projects build themselves only on old Suns:
SUBDIRS = libdet cdma chmem deti detio lu trafficoff
ifeq ($(TARGET),SunOS-4)
SUBDIRS += detserver rdmem wrmem
endif
NO_CFHTLOG
- If /tmp/pipes/syslog.np exists on the machine, this variable contains
nothing. If /tmp/pipes/syslog.np is missing, this will contain
"-DNO_CFHTLOG", and it will be passed to your C programs as well.
If you want to do something differently depending on whether cfht_log
facilities exist, you could do something like this in the Makefile, if
you only need libcfht when cfht_log is used:
ifeq ($(NO_CFHTLOG),)
CCLINK += -lcfht
endif
And something like this in the C source code:
#ifdef NO_CFHTLOG
syslog(syslog_type, message);
#else
cfht_log(CFHT_MAIN, cfht_log_type, message);
#endif
Variables That Depend on Local Installation
Make.Common assumes that gcc is available. At CFHT, the following
variables are set correctly for our installation, but at another site
where gcc is not available (at least as a symbolic link) in /usr/local/bin,
or in a case where gcc was not compiled to also use the Gnu linker, you
may need to tweak some variables in Make.Common itself. (For all the
variables mentioned previously, you override them in the individual
project Makefiles, but for site installation stuff, you'll have to
modify Make.Common).
DIR_GNU
- If gcc is in /usr/local/bin or /usr/bin, there is no need to change
this. Otherwise, you should set this to the path where `gcc' can be
found.
INSTALL
- This must be set to the name of a BSD compatible install program.
If you don't have GNU install on your system and you have
a compatible install program, you can try putting it here (with full
path). Otherwise it is recommended to download "fileutils-X.YY.tar.gz"
from ftp.gnu.ai.mit.edu or a mirror and install it. Be sure to configure
it with "./configure --program-prefix=g" so it doesn't use
names that conflict with the vendor-provided file utilities on your system.
Although I wouldn't recommend it, it is possible to go through
Make.Common and search for all $(INSTALL)'s and replace them with
regular "cp" or "mkdir" commands (depending on whether it is installing
a file or a directory.) GNU fileutils are not difficult to install, so
try that first.
CCLINK
- The default setting for CCLINK under Solaris may be problematic if you
do not have a gcc that uses the GNU linker. Search for "-Wl,-rpath,".
This garbage is needed to ensure that shared libraries will be found
even if a user has an incorrect LD_LIBRARY_PATH or if the program needs
to run without a complete environment (e.g. from a cgi script.) I
think the equivalent of "-rpath" for the Sun linker is "-R", but you
can comment out the entire CCLINK setting as long as you have the
proper search paths in your LD_LIBRARY_PATH and/or the program is
statically linked with any libraries that are in non-standard places.
Sidik Isani
Last modified: Wed Sep 29 16:26:04 HST