MAKEFILE tutorial, copied from the original site in Spain

Much of the information below is just pasted from the man pages.
 

MAKE  

The purpose of the make utility is to determine automatically which pieces of a large program need to be recompiled, and issue the commands to recompile them. To prepare to use make, you must write a file called the makefile that describes the relationships among files in  your program, and the states the commands for updating each file.  In a program, typically the executable file is  updated from object files, which are in turn made by compiling source files.

Once a suitable makefile exists, each time you change some  source files, this simple shell command:

               make

suffices to perform all necessary recompilations.  The make program uses the makefile data base and the last- modification times of the files to decide which of the files need to be updated.  For each of those files, it issues the commands recorded in the data base.

make executes commands in the makefile to update one or more target names, where name is typically a program. 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.)

OPTIONS

The followings are the relevant options of make. They must be given in the command line and you must be sure that you control all the options that are beins issued (environment variable MAKEFLAGS can be set to some of them and you might not notice it).

          -f file
               Use file as a makefile.

           -i
                Ignore all errors in commands executed to remake files.

          -I dir
               Specifies a directory dir to search for included makefiles.  If several -I options are used to specify several directories, the directories are searched in the order specified.  Unlike the arguments to other flags of make, directories given with -I flags may come directly after the flag: -Idir is allowed, as well as -I dir.  This syntax is allowed for compatibility with the C preprocessor's -I flag.

          -n
                Print the commands that would be executed, but do not execute them.

          -p
                Print the data base (rules and variable values) that results from reading the makefiles; then execute as  usual or as otherwise specified.  This also prints the version information given by the -v switch (see below). To print the data base without trying to remake any files, use make -p -f/dev/null.

           -s
                Silent operation; do not print the commands as they are executed.
 
           -W file
               Pretend that the target file has just been modified. When used with the -n flag, this shows you what would happen if you were to modify that file.  Without -n, it is almost the same as running a touch command on the given file before running make, except that the modification time is changed only in the imagination of make.
 
 ENVIRONMENT VARIABLES
 
The value of the SHELL environment variable will not be used as a macro and will not be modified by defining the SHELL macro in a makefile or on the command line. All other environment variables, including those with null values, are used as macros, as defined in the "Macros" section.
 

 MAKEFILE 

The rules in makefiles consist of the following types of lines: target rules, including special targets (see Target Rules);  inference rules (see Inference Rules); macro definitions (see Macros); empty lines; and comments.  Comments start with a number sign (#) and continue until an unescaped newline character is reached.

When an escaped newline character (one preceded by a backslash) is found anywhere in the makefile, it is replaced, along with any leading white space on the following line, with a single space character.

MAKEFILE EXECUTION

Command lines are processed one at a time by writing the command line to the standard output.  Commands will be executed by passing the command line to the command interpreter.

Command lines can have one or more of the following prefixes: a hyphen (-), an at sign (@), or a plus sign (+). These modify the way in which make processes the command. When a command is written to standard output, the prefix is not included in the output.

     -     If the command prefix contains a hyphen,  any error found while executing the command will be ignored.
     @   If the command prefix contains an at sign, the command will not be written to standard output before it is executed.
     +     If the command prefix contains a plus sign, this indicates a command line that will be executed even if -n, -q or -t is specified.

INCLUDE FILES

If the string include or sinclude appears at the beginning of a line in a makefile, and is followed by a blank or a tab, the rest of the line is  assumed to be a filename and will be read by the current invocation,  after substituting for any macros.  For include it is a fatal error if the file is not readable, for sinclude a non-readable file is silently ignored.

SOME DEFINITIONS

Target rules are specified by the user in a makefile for a particular target.  Inference rules are user- or make -specified rules for a particular class of target names. Explicit prerequisites are those prerequisites specified in a makefile on target lines. Implicit prerequisites are those prerequisites that are generated when inference rules are used.  Inference rules are applied to implicit prerequisites or to explicit prerequisites that do not have target rules defined for them in the makefile. Target rules are applied to targets specified in the makefile.

TARGET RULES

Target rules are formatted as follows:

          target [target...]: [prerequisite...][; command ]
          [<tab> command
          <tab> command
          ...]
          line that does not begin with <tab>

Special targets:
     .DEFAULT     If the makefile uses this special target, it must be  specified with commands, but without prerequisites. The  commands will be used by make if there are no other rules available to build a target.

     .IGNORE      Prerequisites of this special target are targets themselves; this will cause errors from commands associated with them to be ignored in the same manner as specified by the -i option. Subsequent occurrences of .IGNORE add to the list of targets ignoring command errors. If no prerequisites are specified, make will behave as if the -i option had been specified and errors from all commands associated with all targets will be ignored.

     .SILENT      Prerequisites of this special target are targets themselves; this causes commands associated with them to not be written to the standard output before they are executed. Subsequent  occurrences of .SILENT add to the list of targets with  silent commands. If no prerequisites are specified, make  will behave as if the -s option had been specified and no commands or touch messages associated with any target will be written to standard output.

     .SUFFIXES    Prerequisites of .SUFFIXES are appended to the list of known suffixes and are used in conjunction with the inference  rules (see "Inference Rules" ). If .SUFFIXES does not have any prerequisites, the list of known suffixes will be cleared. Makefiles must not associate commands with .SUFFIXES.

MACROS

Macro definitions are in the form:

          string1 = [ string2 ]

The macro named string1 is defined as having the value of string2, where  string2 is defined as all characters, if any, after the equal sign, up to a comment character (#) or an unescaped newline character. Any blank characters immediately before or after the equal sign will be ignored.

Subsequent appearances of $(string1) or ${string1} are replaced by string2. The parentheses or braces are optional if string1 is a single character. The macro $$ is replaced by the single character $.

Macros can appear anywhere in the makefile. Macros in target lines will be evaluated when the target line is read. Macros in command lines will be evaluated when the command is executed. Macros in macro definition lines will not be evaluated until the new macro being defined is used in a rule or command. A macro that has not been defined will evaluate to a null string without causing any error condition.

Macro assignments will be accepted from the sources listed below, in the order shown. If a macro name already exists at the time it is being processed, the newer definition will replace the existing definition.

     1.  Macros defined in make's built-in inference rules.
     2.  The contents of the environment, including the variables with null values, in the order defined in the environment.
     3.  Macros defined in the makefiles, processed in the order specified.
     4.  Macros specified on the command line. It is unspecified whether the internal macros defined in Internal Macros are accepted from the command line.

INFERENCE RULES

Inference rules are formatted as follows:

          target:
          <tab>command
          [<tab>command ]
          ...
          line that does not begin with <tab> or #

The target portion must be a valid target name (see "Target Rules") of the form .s2 or .s1.s2 (where .s1 and .s2 are suffixes that have been  given as prerequisites of the .SUFFIXES special target and s1 and s2 do not contain any slashes or periods.) If there is only one period in the target, it is a single-suffix inference rule. Targets with two periods are double-suffix inference rules.  Inference rules can have only one target before the colon.

The makefile must not specify prerequisites for inference rules; no characters other than white space can follow the colon in the first line, except when creating the empty rule, described below.  Prerequisites are inferred, as described below.

The make utility uses the suffixes of targets and their prerequisites to infer how a target can be made up-to-date. A list of inference rules defines the commands to be executed. By default, make contains a built-in set of inference rules.  Additional rules can be specified in the makefile.

The special target .SUFFIXES contains as its prerequisites a list of  suffixes that are to be used by the inference rules. The order in which the suffixes are specified defines the order in which the inference rules for the suffixes are used. New suffixes will be appended to the current list by specifying a .SUFFIXES special target in the makefile. A .SUFFIXES target with no prerequisites will clear the list of suffixes. An empty .SUFFIXES target followed by a new .SUFFIXES list is required to change the order of the suffixes.

Normally, the user would provide an inference rule for each suffix. The inference rule to update a target with a suffix .s1 from a prerequisite with a suffix .s2 is specified as a target .s2.s1. The internal macros provide the means to specify general inference rules. (See Internal Macros)

When no target rule is found to update a target, the inference rules are checked. The suffix of the target (.s1) to be built is compared to the list of suffixes specified by the .s1 suffix is found in .SUFFIXES, the inference rules are searched in the order defined for the first .s2.s1 rule whose prerequisite file ($*.s2) exists. If the target is out-of-date with respect to this prerequisite, the commands for that inference rule are executed.

If the target to be built does not contain a suffix and there is no rule for the target, the single suffix inference rules will be checked. The single-suffix inference rules define how to build a target if a file is found with a name that matches the target name with one of the single suffixes appended. A rule with one suffix .s2 is the definition of how to build target from target.s2. The other suffix (.s1) is treated as null.
 
LIBRARIES

If a target or prerequisite contains parentheses, it will be treated as a member of an archive library. For the lib(member.o) expression lib refers to the name of the archive library and member.o to the member name. The member must be an object file with the .o suffix. The modification time of the expression is the modification time for the member as kept in the archive library (See ar). The .a suffix refers to an archive library. The .s2.a rule is used to update a member in the library from a file with a suffix .s2.

INTERNAL MACROS

     $@      The $@ evaluates to the full target name of the current target, or the archive filename part of a library archive target. It is evaluated for both target and inference rules.  For example, in the .c.a inference rule, $@ represents the out-of-date .a file to be built. Similarly, in a makefile target rule to build lib.a from file.c, $@ represents the out-of-date lib.a.

     $$@     The $$@ macro stands for the full target name of the current target (which is $@).  It has meaning only on the dependency line in a makefile.  Thus, in the following:

                 cat dd: $$@.c

 the dependency is translated at execution time first to the string cat.c, then to the string dd.c.

     $%      The $% macro is evaluated only when the current target is an archive library member of the form libname(member.o). In these cases, $@ evaluates to libname and $% evaluates to member.o. The $% macro is evaluated for both target and inference rules. For example, in a makefile target rule to build lib.a(file.o), $% represents file.o as opposed to $@, which represents lib.a.

     $?      The $? macro evaluates to the list of prerequisites that are newer than the current target. It is evaluated for both target  and inference rules. For example, in a makefile target rule to build prog from file1.o, file2.o and file3.o, and where prog is not out of date  with respect to file1.o, but is out of date with respect to file2.o and file3.o, $? represents file2.o and file3.o.

     $<      In an inference rule, $< evaluates to the file name whose existence allowed the inference rule to be chosen for the target. In the .DEFAULT rule, the $< macro evaluates to the current target name. The $< macro is evaluated only for inference rules. For example, in the .c.a inference rule, $< represents the prerequisite .c file.

     $*      The $* macro evaluates to the current target name with its suffix deleted. It is evaluated at least for inference rules. For example, in the .c.a inference rule, $*.o represents the out-of-date .o file that corresponds to the prerequisite .c file.

Each of the internal macros has an alternative form. When an upper-case D or F is appended to any of the macros, the meaning is changed to the directory part for D and filename part for F. The directory part is the path prefix of the file without a trailing slash; for the current directory, the directory part is ``.''. When the $? macro contains more than one prerequisite filename, the $(?D) and $(?F) (or ${?D} and ${?F}) macros expand to a list of directory name parts and filename parts respectively.

For the target lib(member.o) and the s2.a rule, the internal macros are defined as:

     $<      member.s2
     $*      member
     $@      lib
     $?      member.s2
     $%      member.o

DEFAULT RULES

      .SUFFIXES: .o .c .y l .a .sh .f .c~ .y~ .l~ .sh~ .f~

     MAKE=make
     AR=ar
     ARFLAGS=-rv
     LFLAGS= LDFLAGS=
     CC=c89
     CFLAGS=-O
     FC=fort77
     FFLAGS=-O 1

      .c:
               $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
      .f:
               $(FC) $(FFLAGS) $(LDFLAGS) -o $@ $<
      .c.o:
               $(CC) $(CFLAGS) -c $<
      .f.o:
               $(FC) $(FFLAGS) -c $<
      .c.a:
               $(CC) -c $(CFLAGS) $<
               $(AR) $(ARFLAGS) $@ $*.o
               rm -f $*.o
      .f.a:
               $(FC) -c $(FFLAGS) $<
               $(AR) $(ARFLAGS) $@ $*.o
               rm -f $*.o

NOTES

1. Macros used within other macros are evaluated when the new macro is used rather than when the new macro is defined. Therefore:

          MACRO = value1
          NEW   = $(MACRO)
          MACRO = value2

          target:
                 echo $(NEW)

would produce value2 and not value1 since NEW was not expanded until it was needed in the echo command line.

2. For inference rules, the description of $< and $? seem similar.  However, an example shows the minor difference. In a makefile containing:

          foo.o: foo.h

if foo.h is newer than foo.o, yet foo.c is older than foo.o, the built-in rule to make foo.o from foo.c will be used, with $< equal to foo.c and $? equal to foo.h. If foo.c is also newer than foo.o, $< is equal to foo.c and $? is equal to foo.h foo.c.

SHORT EXAMPLES

1.  The following command makes the first target found in the makefile.
              make
 
2.  The following command makes the target junk.
             make junk

3.  The following makefile says that pgm depends on two files, a.o and b.o, and that they in turn depend on their corresponding source files (a.c and b.c), and a common file incl.h:
         pgm: a.o b.o
                 c89 a.o b.o -o pgm
         a.o: incl.h a.c
                 c89 -c a.c
         b.o: incl.h b.c
                 c89 -c b.c

4.  An example for making optimised .o files from .c files is:
          .c.o:
                 c89 -c -O $*.c
         or:
          .c.o:
                 c89 -c -O $<

5.  The most common use of the archive interface follows.  Here, it is assumed that the source files are all C-language source:
         lib:   lib(file1.o) lib(file2.o) lib(file3.o)
                @echo lib is now up-to-date

The .c.a rule is used to make file1.o, file2.o and file3.o and insert them into lib.

6. If $? were:  /usr/include/stdio.h /usr/include/unistd.h foo.h
then $(?D) would be: /usr/include /usr/include .
and $(?F) would be:  stdio.h unistd.h foo.h
 

MAKEDEPEND 

Makedepend reads each sourcefile in sequence and parses it like a C-preprocessor, processing all #include, #define, #undef, #ifdef, #ifndef, #endif, #if and #else directives so that it can correctly tell which #include, directives would be used in a compilation.  Any #include, directives can reference files having other #include directives, and parsing will occur in these files as well.

Every file that a sourcefile includes, directly or indirectly, is what makedepend calls a "dependency".  These dependencies are then written to a makefile in such a way that make(1) will know which object files must be recompiled when a dependency has changed.

By default, makedepend places its output in the file named makefile if it exists, otherwise Makefile. An alternate makefile may be specified with the -f option.  It first searches the makefile for the line

              # DO NOT DELETE THIS LINE -- make depend depends on it.

or one provided with the -s option, as a delimiter for the dependency output.  If it finds it, it will delete everything following this to the end of the makefile and put the output after this line.  If it doesn't find it, the program will append the string to the end of the makefile and place the output following that.  For each sourcefile appearing on the command line, makedepend puts lines in the makefile of the form

               sourcefile.o: dfile ...

Where "sourcefile.o" is the name from the command line with its suffix replaced with ".o", and "dfile" is a dependency discovered in a #include directive while parsing sourcefile or one of the files it included.

Example: inside Makefile
              SOURCES = file1.c file2.c ...
              CFLAGS = -DHACK -I../includes
              depend:
                      makedepend  $(CFLAGS)  $(SOURCES)
 

COMPILERS 

There are several compilers the ones we usually use are cc, gcc and g++. cc and gcc are for normal C while g++ for C++. I will give the syntaxis and  more common options for gcc as they are nearly the same in cc and gcc. The specific feature of specifying the libraries to be linked (32/64 bits) will be addressed later.

          gcc [ option | filename ]...

Linking is performed by a call to the compiler but this operation implies another executable file, the link editor, usually called 'ld' and its purpose is to combine several Elf Object Files, ie, to link.

OVERALL OPTIONS

 -c   Compile or assemble the source files, but do not  link.
 -S   Stop after the stage of compilation proper; do not  assemble.
 -o file
        Place output in file file.  This applies regardless  to whatever sort of output GCC is producing, whether it be an executable file, an object file, an  assembler  file or preprocessed C code. If you do not specify `-o', the default is  to  put  an executable   file  in  `a.out',  the  object  file  for `source.suffix' in `source.o', its  assembler  file  in `source.s',  and  all preprocessed C source on standard output.

LANGUAGE OPTIONS

 -ansi  Support all ANSI standard C programs.

PREPROCESSOR OPTIONS

 -include file
         Process file as input before processing the regular input file.
 -Dmacro
         Define  macro. It is the same as if inside the .c file we would declare #define macro.
 -Dmacro=defn
         Define macro macro as defn.

LINKER OPTIONS

These options come into play when the compiler links  object files  into an executable output file.  They are meaningless if the compiler is not doing a link step.

object-file-name
           A file name that does not end in a  special  recognized  suffix is considered to name an object file or library.  (Object files are distinguished from libraries  by  the  linker  according to the file contents.)  If GCC does a  link step, these object files are used as input to  the  linker.

-llibrary
            Use the library named library when linking.  The  linker searches a standard list of directories for   the  library,  which   is   actually   a   file   named  `liblibrary.a'.   The  linker then uses this file as if it had been specified precisely by name. The directories searched include several standard  system directories plus any that you specify with `-L'.

-Wl,option
               Pass option as an option to the linker.  If option contains commas, it is split into multiple options at  the commas.

 DIRECTORY OPTIONS

-Idir
           Append   directory  dir  to  the  list  of  directories searched for include files.
-Ldir
           Add  directory  dir  to  the  list of directories to be searched for `-l'.
-Bprefix
           This option specifies where to  find  the  executables, libraries and data files of the compiler itself.

WARNING OPTIONS

-w
           Inhibit all warning messages.
-pedantic
           Issue all the warnings demanded by strict ANSI standard C; reject all programs that use forbidden extensions.
-W
           Print extra warning messages for strange events such as possible changes in variables after long jumps, a function which might not return a value, possible castings, ...
-Wall
            Print warnings for a large amount of possible error conditions.

DEBUGGING OPTIONS

-g
            Produce debugging information in the operating system's native  format (stabs, COFF, XCOFF, or DWARF).  GDB can work with this debugging information. This option activates debugging at all levels, but there are also options for accomplishing a fixed level of debugging or a special feature.

OPTIMIZATION OPTIONS

-O
            Produce optimized code for the program. There are two more levels of optimization (-O2 and -O3), but usually this basic level is enough. As in debugging control can be applied to many little features.

FILE LOCATIONS

/usr/include                                                            --> a "boom mix" of headers affecting many kinds of libraries, included C standard
/usr/local/contrib/?????/include                        --> each package installed in bossa-nova has got its includes in this directory
 

"STATIC" LINKER 

Ld, the link editor, links Elf object files. The archive format ld is the one created by the archiver ar(1).

 ld is normally invoked by cc(1), although it can be run separately.  When ld is used as part of a cc compilation, the ld options must be passed via the -Wl mechanism.  See cc(1) for details of -Wl.

The ld command combines several object files into one, performs relocation, resolves external symbols, builds tables and relocation information for run-time linkage in case of doing shared link, and supports symbol table information for symbolic debugging.  In the simplest case, the names of several object files are given.  ld combines them, producing an object module that can be executed or used as input for a subsequent ld run.  (In the latter case, the -r option must be given to preserve the relocation entries.)  The output of ld is left in a.out.  By default, this file is a dynamic executable if no errors occurred during the load.

There are two kinds of libraries, archives and dynamic shared objects.  When linking with archives, only those routines defining an unresolved external reference are loaded. Shared objects are used only if the output is to be dynamic. In that case, only the name is used for external resolution, no object is included as part of the output object file.  Note that any symbol remaining unresolved are not consider an error when the linkage is to be shared or dynamic.  The library (archive) symbol table (see ar(1)) is a hash table and is searched to resolved external references that can be satisfied by library members.  The ordering of library members is unimportant.

Linking against a dynamic shared object will normally cause that object to be loaded (see rld(1) and dso(5)) whenever the object being created is loaded, thus resolving the symbols supplied by that object.  The loading of a dynamic shared object can be delayed using the -delay_load option. In this case the object is not loaded until a symbol supplied by the object is actually referenced.  Symbols from a delay loaded object do not preempt symbols from other libraries; they are resolved as if the object was last on the link line.

When searching for ucode libraries the default directories searched are /usr/lib/, /lib/ and /usr/local/lib/.  Note that, although archives will be found in /usr/local/lib/, shared objects should not be installed there, as they will not be found by rld(1).  When searching for 64bit libraries the default directories searched are /usr/lib64/, /lib64/ and /usr/local/lib64/.  When searching for n32 libraries the default directories searched are /usr/lib32/, /lib32/ and /usr/local/lib32/.

OPTIONS

-o outfile
          Produce an output object file by the name outfile. The name of the default object file is a.out.

-lx
          Search a library libx.{so,a}, where x is a string.  A shared object or an archive is searched when its name is encountered, so the placement of a -l is significant.

-L  dir
          Change the algorithm of searching for libx.{so,a} or libx.b to look in dir before looking in the default directories.  This option is effective only if it precedes the -l options on the command line.

-v
          Set verbose mode.  Print the name of each file as it is processed.

-32
          Specifies that the object to be linked (and the input objects) are to be 32-bit ucode objects.

-n32
          Specifies that the object to be linked (and the input objects) are to be 32-bit n32 objects.

-64
          Specifies that the object to be linked (and the input objects) are to be 64-bit objects.
 
FILES IMPLIED
 
     /lib/lib*.so
     /lib/lib*.a
     /usr/lib/lib*.so
     /usr/lib/lib*.a
     /usr/local/lib/lib*.a
 

RUNTIME LINKER  

rld, the runtime linker. It is invoked when running a dynamic executable.  It maps in shared objects used by this executable, resolves relocations as ld does at static link time, and allocates common if required. When any dynamic executable is run, the system will first run an interpreter which is responsible for collecting together the appropriate objects, mapping them into memory and resolving references during runtime. The name of the interpreter is included in the executable file. Dynamic execution is only supported with ELF format executables.  Such executables will have an INTERP section which specifies the name of this interpreter.  The default name of this interpreter is /usr/lib/libc.so.1.

For 64-bit programs the name of this interpreter is /usr/lib64/libc.so.1. The discussion below applies to 64-bit programs if the directory /usr/lib64 is substituted for the directory  /usr/lib and the directory /lib64 is substituted for /lib. For new 32-bit ABI programs the name of this interpreter is /usr/lib32/libc.so.1.  The discussion below applies to new 32-bit ABI programs if the directory /usr/lib32 is substituted for the directory /usr/lib and the directory /lib32 is substituted for /lib.

The file /usr/lib/libc.so.1 is the standard C/system library in the form of a shared object.  In addition /usr/lib/libc.so.1 contains code which will load the interpreter into its address space and set it to work.  The default such interpreter is /lib/rld.

One of the primary features of dynamic linking is that it gives users the ability to change library implementations without recompiling the executable. Some mechanisms for this are listed below.  However, /usr/lib/libc.so.1 is not subject to any of the mechanisms listed below, since it is known to the executable as the interpreter as well as a needed shared object.  If you wish to substitute /usr/lib/libc.so.1, the best way is to make use of the -I flag to the linker (ld(1)).  This can be passed from the compiler driver using the -Wl,-I,myinterpname format. However, any such shared object specified must be able to act as interpreter (or invoke rld).

Because there are three distinct ABI's used by Irix programs with accompanying libraries, there are three distinct sets of RLD search paths and three sets of environment variables.

The default library search path for o32 (32-bit) programs is (/usr/lib:/lib), which can be overridden by either of the environment variables LD_LIBRARY_PATH. The default library search path for 64 (64-bit) programs is (/usr/lib64:/lib64), which can be overridden by either of the environment variables LD_LIBRARY64_PATH. The default library search path for n32 (new 32-bit ABI) programs is (/usr/lib32:/lib32), which can be overridden by either of the environment variables LD_LIBRARYN32_PATH. For n32 or 64-bit programs, if LD_LIBRARYN32_PATH or LD_LIBRARY64_PATH is not specified, then rld will honor LD_LIBRARY_PATH if specified.

The search path for shared objects is acquired in the following order:
     1.   The path of the shared object if given in the liblist, (i.e., if the soname of the shared object has a path (see ld(1));
     2.   RPATH if it is defined in the main executable, (via the -rpath switch to ld(1) when the executable is created);
     3.   Use LD_LIBRARY_PATH if defined in the environment at the time of execution;
     4.   The default library search path.

LD_LIBRARY_PATH is a colon(:) separated list of directories; and, if defined, specifies an extra set of directories in which rld is to look when searching for shared objects. LD_LIBRARY64_PATH and LD_LIBRARYN32_PATH are treated in a similar fashion.

ENVIRONMENT VARIABLES VALUES

LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib
LD_LIBRARYN32_PATH=/usr/lib32:/lib32:/usr/local/lib32
LD_LIBRARY64_PATH=/usr/lib64:/lib64:/usr/local/lib64
 

IMAKEFILE 

Imake is used to generate Makefiles from a template, a set of cpp macro functions, and a per-directory input file called an Imakefile.  This allows machine dependencies (such as compiler options, alternate command names, and special make rules) to be kept separate from the descriptions of the various items to be built.

It is not simple to describe and understand, I refer to 'man imake' for more information, imake executable file is in /usr/bin/X11, while configuration, rule generation and basic template are in /usr/lib/X11/config. A look to these last files can give a light on how this Makefile generator works.

In our package XV Makefile is generated using an Imakefile.
 

 XMKMF 

The xmkmf command is the normal way to create a Makefile from an Imakefile shipped with third-party software.

When invoked with no arguments in a directory containing an Imakefile, the imake program is run with arguments appropriate for your system (configured into xmkmf when X was built) and generates a Makefile.

When invoked with the -a option, xmkmf builds the Makefile in the current directory, and then automatically executes ``make Makefiles'' (in case there are subdirectories), ``make includes'', and ``make depend'' for you.  This is the normal way to configure software that is outside the X Consortium build tree.

This command is also used for building Linux packages. Again the executable is in /usr/bin/X11.
 

EXPERIENCED ERRORS 

 make: file `Makefile' line 359: Must be a separator (: or ::) for rules (bu39)
line 359 begins with spaces and not with TAB, it is very important that the rule's bodies begin with TAB.
 
 infinitely recursive macro?
Macro definitions of the fashion (see below) cannot be done, the definition is thought to be recursive. A second variable must be used for the second macro definitions
LIBPATHS =
LIBPATHS = -L/usr/lib $(LIBPATHS)
 
 C++ compilation with gcc
An error has been detected using gcc, according to the man page the syntax is

      gcc [ option | filename ]...

but the line "gcc -I$(INC) -L$(LIB) -lnno -lm strain.cc -o strain" does not work and needs to be replaced by "gcc strain.cc -o strain -I$(INC) -L$(LIB) -lnno -lm", that is to say, the programs first and then the options.

Another source of error comes from the fact that gcc interprets *.c files as plain C code. If you want a program to be interpreted as C++ code you must use an extension for it such as *.cc or *.C.

 line continuations
Pay attention to the correct way of continuing a line, for exmple, in the first 'if' sentence slashes (\) are very important. The following code is OK, but not the second code where a wrong continuation has been used (marked in red), it should be removed if we want the program to be right.  The error generated for this situation is shown after the words "CODE 2:", as it can be seen it is not very useful in order to detect the error.q

CODE 1:
@if [ -f local_def ]; then \
  echo "DIRINST       = $(DIRINST)" > local_def ;\
 else \
  echo "DIRINST       = $(DIRINST)" >> local_def ;\
 fi
 @echo "DIRBIN        = $(DIRBIN)"        >> local_def
 @echo "DIRLIB        = $(DIRLIB)"        >> local_def
 @echo "DIRDOC        = $(DIRDOC)"        >> local_def
 @echo "CC            = $(CC)"            >> local_def
 @echo "AR            = $(AR)"            >> local_def
 @echo "MACHINE       = $(MACHINE)"       >> local_def
 @echo "XLIBS         = $(XLIBS)"         >> local_def
 @echo "XMLIBS        = $(XMLIBS)"        >> local_def
 @echo "LIBMIP        = $(LIBRARIES)"     >> local_def
 @echo "COMPILERFLAGS = $(COMPILERFLAGS)" >> local_def
 @echo "LINKERFLAGS   = $(LINKERFLAGS)"   >> local_def
 @echo "ANSIFLAGS     = $(ANSIFLAGS)"     >> local_def
 @for i in $(ALLSUBDIRS) ;\
 do \
  echo "creating Makefile in $$i..."; \
  ( cd $$i ; cat $(DIRINST)/local_def Makefile.std > Makefile) \
 done

CODE 2:
sh: syntax error at line 3 : `do' unexpected
*** Error code 2 (bu21)
 @echo "COMPILERFLAGS = $(COMPILERFLAGS)" >> local_def ;\
 echo "LINKERFLAGS   = $(LINKERFLAGS)"   >> local_def ;\
 echo "ANSIFLAGS     = $(ANSIFLAGS)"     >> local_def ;\
 @for i in $(ALLSUBDIRS) ;\
 do \
  echo "creating Makefile in $$i..."; \
  ( cd $$i ; cat $(DIRINST)/local_def Makefile.std > Makefile) \
 done
 
 Operation between types pointer and integer is not allowed.
This error can mean that the prototype of a function is not known, so an integer returned value is assumed for that function. If the function actually returns a pointer then a type conflict is detected, althoguh the problem is not the type conflict but that the prototype of the function has not been included. You have to check the includes.

Example Code:
   #include <string.h>
   ....
   char *str1, *str2;
   ....
   str2 = strdup(str1);
 
 cc: illegal suffix of output filename
This error is produced by some compilers when they are recquired to link and not to link at the same time. Other compilers solve this ambiguity by linking. For example look at the following command
cc -c -O -D_sunOSV -I/volatil/Xmipp/Lib  elimin.c lvq_pak.o lvq_rout.o -lm -o elimin -L/volatil/Xmipp/Lib

 Makefile:31: warning: overriding commands for target `infogeo'
 Makefile:28: warning: ignoring old commands for target `infogeo'
 There are two rules (with actions) for building infogeo, one in line 28 and another one in line 31.

 make: Circular infogeo <- infogeo dependency dropped.
The prerrequisite of a rule is the same as the rule name, it is some kind of recursion.
 
 templates and linking
When using templates from a different module, say "matrices.cc",you cannot (with the actual implementations of compilers and linkers) compile with the library containing all those routines, instead in your program you must include the whole "matrices.cc" file.

 Merging C and C++
Every time you need to use a plain C routine, compiled as plain C you must declare it as extern "C", if not strange prefixes and suffixes will be added to the routine name and it will not be found in the correspondient library. For heading files it is useful to add at the beginnig of the file the macro

   #ifdef __cplusplus
   #   define CDECL "C"
   #else
   #   define CDECL
   #endif

and then the routines are declared inside the header file as

   extern CDECL int image_io (char **,char **,int,int,char *,int,int,int);
 
 CVD cannot read variable values
CVD is a debugger compiled for SGI, then it can only read code generated by SGI compilers, more or less. If you compile with gcc you are generating GNU code which cannot be read by CVD, instead compile with cc or CC.

 CVD cannot execute your program
Close the execution window, despite the warning telling you that the execution might be wrong.

 Passing a matrix as a parameter to a function
It is not the same the definition of a matrix as double T[3][3]; or double **T; and then allocating twice. In the second case an extra array of pointers is created besides the arrays for double data, while in the first one this extra array is not.

 aggregate `class img' has incomplete type and cannot be initialized
class img is using another class which has not been defined within this context. Surely an include is missing.

 Programs compile but different modules cannot link
Check that all modules have been compiled with the same compiler and library. A usual symptom is that it says that there are referenced functions which do not exist when you know they do.

 An included file is not found at compilation time
When you know that you have set the right paths to see all the includes. Take into account that symbols like ~ are not resolved. For example, these two commands are not the same and the first one will not work.
    gcc -g -c -D_sunOSV -DMIPG -I~coss/Xmipp/Lib             correct_create.c
    gcc -g -c -D_sunOSV -DMIPG -I/u/bioinfo/coss/Xmipp/Lib   correct_create.c

 libraries are not loaded at linking time
Libraries to be loaded must be at the end of the command line. The next first line will not work, but the second yes
    cc -g -o correct_create correct_create.o -lm /u/bioinfo/coss/Xmipp/Lib/libS62mip.a
    cc -g -o correct_create correct_create.o  /u/bioinfo/coss/Xmipp/Lib/libS62mip.a -lm
Also you must specify the libraries from more complexity to less, ie, if a library is making use of symbols of a second library the command line must have the first library in first place and the second one in second place, and the order is very important. Otherwise, some symbols might not be found when linking.

 sscanf does not work
If you are using sscanf(str,"%s %d",another_str,integer_var), you must be sure that integer_var is of type int, if it is short, for instance, the string another_str will not be read properly. sscanf cannot work neither with the STL strings, even if you pass as argument %s, the function str.c_str(). The solution is to use an intermidiate char array to serve as interface between strings and sscanf.

 reserve in STL
Be careful that the reserve function of vectors in the STL library allocates memory but doesn't call to you initializer fo the object, so it's better to make a call to push_back, or make a manual initialisation of the object.
 

REAL-LIFE EXAMPLES 

From this point you will find several examples from Xmipp, I hope you find them useful.
  1. Xmipp: General Xmipp Makefile, for the whole package
  2. User Libraries: Makefile for a User Defined Library, such as Xmipp/Lib
  3. User Programs: Makefile.std for a User Program, such as Xmipp/Artkbcc
  4. Merging Fortran: How to include Fortran routines in our C programs
  5. Checking Heading Dependencies: usually 'make' does not check dependencies with .h files
  6. Using Qt
  7. Choosing between 32 or 64 bits compilation
  8. Using C++
Carlos Oscar
 

REAL-LIFE MAKEFILE 1:  XMIPP 

The following example is the Complete Xmipp Makefile, some comments will be done among the file. Much of the redundant information (many directories, programs, ...) are removed, here I only want to give an idea of what should be done.
 
############################################################################
#                                                                          #
#                          Makefile for XMIPP                              #
#                             Version 2.0                                  #
#                            September 1996                                #
#                                                                          #
############################################################################

SHELL=/bin/sh

########################  Platform specific definitions ####################

CC            =  cc
#CC           =  xlc     # for AIX
#CC           =  cc -32  # for IRIX_6
'ar rc' is the command used to create libraries: c means the library will be created if it does not exist, and r that new objects replace old objects with the same name (if any).
AR            =  ar rc
CCOPTS        =  -c -O

# if you want compile with Pure ANSI/ISO C ,UNCOMMENT one of these lines:
#
#    if you're running IRIX
#    ANSIFLAGS = -ansi
#    ...................................................................
#    if you're running sunOS 5.x
#    ANSIFLAGS = -Xa
#    ...................................................................
#    if you're running AIX
#    ANSIFLAGS = -D_POSIX_SOURCE
#    ...................................................................
#
# else if you're using a SGI running IRIX 5 with NO Pure ANSI/ISO C
# (this is the best choice for IRIX), UNCOMMENT the next line:(It is not necesary
# for Solaris)
# ANSIFLAGS = -D__STDC__

# if you are running IRIX 6
# ANSIFLAGS = -D__STDC -D_IRIX6
 

# if you're using a Sun running OpenWindows (SOLARIS 2.x),
# uncomment the following lines
#XWINDFLAGS = -I/usr/openwin/include -L/usr/openwin/lib
#XMOTIFLAGS = -I/usr/dt/include -I/usr/openwin/include -L/usr/dt/lib -L/usr/openwin/lib

# Likewise, if your X11 and Xm include files and libraries aren't in the
# 'standard' places in which the C compiler looks, you should add '-L' and
# '-I' options on the next line to tell the compiler where said files are.

XWINDFLAGS =
XMOTIFLAGS =

#############  LIBRARIES
# Perhaps , you'll want to add some libraries. There are three kinds of
# libraries defined here:
#
#    1. Libraries for X-Windows : set up XLIBS
#
#        if you're using a Sun running OpenWindows (Solaris 2.x)
#     UNCOMMENT the next line
# XLIBS = -lX11 -lnsl
#       if you're using IRIX or AIX UNCOMMENT the next line
# XLIBS = -lX11
#
#    2. Libraries for Motif: set up XMLIBS
#
#       if you're using a Sun running OpenWindows UNCOMMENT the next line
# XMLIBS = -lXm -lXt -lX11
#       if you're using IRIX or AIX UNCOMMENT the next line
# XMLIBS = -lXm -lPW -lXt -lX11
#
#    3. Other libraries : set up EXTRA_LIBRARIES
#
# actually only '-lm' is needed , so you DON'T need modify the next line.
#
EXTRA_LIBRARIES=
 

####################### CONFIGURATION OPTIONS #######################
MACHINE =SGI
### Others could be SGI, IRIS6, AIX, etc
# if compiling on a IRIX machine, uncomment the following line:
# EXTRAFLAGS = -D_sgIRIX
#
# or, if compiling on a AIX machine, uncomment the following line:
# EXTRAFLAGS = -D_CCAIX3
#
# or, if compiling on a sunOS machine, uncomment the following line:
# EXTRAFLAGS = -D_sunOSV
#

################        INSTALLATION OPTIONS          #################

########  Path to directory  with the thing ... modify as you like ...

# the sources: The environmental variable PWD can be used as a Macro
# SOURCEDIR =  $(PWD)
SOURCEDIR =  /volatil/Xmipp

TOPDIR    = $(SOURCEDIR)

# Path to binary files :
DIRBIN    = $(TOPDIR)/bin

# Path to help files
DIRDOC    = $(TOPDIR)/help
 

###################### END OF CONFIGURATION OPTIONS #####################
 

#########################################################################
##  Nothing to change below here...

DIRINST       = $(SOURCEDIR)
DIRLIB        = $(DIRINST)/Lib
ARTLIB        = $(DIRINST)/LibArt

COMPILERFLAGS = $(CCOPTS) $(EXTRAFLAGS)

LIBXMIPP      = $(DIRLIB)/libmip$(MACHINE).a
LIBMIP        = $(LIBXMIPP) $(EXTRA_LIBRARIES)

########################################################################
#
# The subdirs ....

APPLYGEDIR = $(DIRINST)/Applygeo
ARTKDIR    = $(DIRINST)/Artkbcc
BACKGEODIR = $(DIRINST)/Backgeo
... and so on

SUBDIRS = $(3DPACK)  $(APPLYGEDIR)  $(ARTKDIR) $(BACKGEODIR) $(CENTILDIR) \
 $(CLUSTDIR)   $(COMBIVECDIR) $(CONTOURDIR)  $(CONVERCCDIR) \
 ...

#
# What to do when there's nothing to do...
#
all:
 make Makefiles
 make libraries
 make progs
 make install
 make clean

###########################################################################
# rules for building in SUBDIRS - do not edit

ALLSUBDIRS = $(DIRLIB) $(ARTLIB) $(SUBDIRS)

Notice that these commands are from the O.S. and not from Makefile, there is one target (install) without any prerequisites. Makefile macros can be used as environment variables (look the use of $(DIRBIN)). Be careful that [-d $(DIRBIN)] is a /bin/sh condition which checks if a directory really exists, it has nothing to do with the Makefile.
install:: --> I don't know why the double colon
 -@if [ -d $(DIRBIN) ] ; \  --> This line will be executed ignoring errors(-) and in silent mode (@)
 then : ;\
 else   mkdir $(DIRBIN) ;\
 fi; \
 if [ -d $(DIRDOC) ] ; \
 then : ;\
 else   mkdir $(DIRDOC) ;\
 fi; \
 for i in $(SUBDIRS) ;\
 do \
  ( cd $$i ; make install ) \
 done

clean::
 -@for i in $(ALLSUBDIRS) ;\
 do \
  ( cd $$i ; echo "cleaning" "in $$i..."; make clean ) \
 done; \

This time there is a prerequisite (FORCE) but it is empty, this way it is as if no prerequisite were needed. [-f ...] checks if a file exist.
In local_def several variables are defined, they are the same for all Makefiles in all Xmipp programs. Particularities are given by Makefile.std, when these two files are put together they yield the real Makefile.
Makefiles: FORCE
 -@if [ -f local_def ]; then \
  echo "DIRINST       = $(DIRINST)"      >  local_def ;\
 else \
  echo "DIRINST       = $(DIRINST)"      >> local_def ;\
 fi ; \
 echo "DIRSRC        = $(SOURCEDIR)"     >> local_def ;\
 echo "MACHINE       = $(MACHINE)"       >> local_def ;\
 echo "DIRBIN        = $(DIRBIN)"        >> local_def ;\
 echo "DIRLIB        = $(DIRLIB)"        >> local_def ;\
 echo "DIRDOC        = $(DIRDOC)"        >> local_def ;\
 echo "CC            = $(CC)"            >> local_def ;\
 echo "AR            = $(AR)"            >> local_def ;\
 echo "XLIBS         = $(XLIBS)"         >> local_def ;\
 echo "XMLIBS        = $(XMLIBS)"        >> local_def ;\
 echo "LIBMIP        = $(LIBMIP)"        >> local_def ;\
 echo "COMPILERFLAGS = $(COMPILERFLAGS)" >> local_def ;\
 echo "ANSIFLAGS     = $(ANSIFLAGS)"     >> local_def ;\
 echo "XWINDFLAGS    = $(XWINDFLAGS)"    >> local_def ;\
 echo "XMOTIFLAGS    = $(XMOTIFLAGS)"    >> local_def
 -@for i in $(ALLSUBDIRS) ;\
 do \
  echo "creating Makefile in $$i..."; \
  ( cd $$i ; cat $(SOURCEDIR)/local_def Makefile.std > Makefile) \
 done

FORCE:

Pay attention to the change of a macro inside the make of DIRLIB and ARTLIB
libraries::
 ( cd $(DIRLIB); make CC='$(CC)' )
 ( cd $(ARTLIB); make CC='$(CC)' MIPGlib.a)

progs:
 -@for i in $(SUBDIRS) ;\
 do \
  ( cd $$i ; echo "compiling in $$i..."; \
  make all ) \
 done
 

REAL-LIFE MAKEFILE 2: USER DEFINED LIBRARIES 

 The Makefile.std for a User Defined Library is like the following.

###########################################################################
LIBPROJ = libmip$(MACHINE).a
LIBS = -lm
LOCALFLAGS =
CFLAGS= $(COMPILERFLAGS) $(ANSIFLAGS) $(LOCALFLAGS)
GROELIB= $(DIRINST)/Lib/

List of programs that integrate the library
LIBOBJS = cabecero.o varios.o varios2.o varios3.o dimension.o \
             floatnat.o iocabecero.o usages.o fft.o fftmod.o fftn.o allfft.o

It is important to keep 'make all' because this command will be given from the main Makefile (see Makefile.Xmipp). This 'make all' does nothing but call 'make $(LIBPROJ)'
all:  $(LIBPROJ)

To make the library first the programs must be compiled (prerequisite = $(LIBOBJS)), then the old library file is removed and the new objects are put together with ar
$(LIBPROJ): $(LIBOBJS)
 rm -f $(LIBPROJ)
 $(AR) $(LIBPROJ)  $(LIBOBJS)

For any program listed in $(LIBOBJS) the only thing we have to do is to compile it, many of the CFLAGS are "inherited" from local_defs (see in Makefile.Xmipp that this objects are only compiled and no executable file is generated for them). Pay attention to the use of the internal macro $* which meant the current target without suffix.
$(LIBOBJS):
 $(CC) $(CFLAGS) $*.c

When cleaning you only have to remove the object files and the library itself!!! (this is a design option)
clean:
 rm -f  *.o  $(LIBPROJ)
 

REAL-LIFE MAKEFILE 3: MAKEFILE.STD AND FINAL MAKEFILE  

In this example we will see how the final Makefile relates to the original Makefile.std. Remember Makefile.std keeps the particularities of a fixed program while local_defs mantains information of variables in this compilation, these two files are mixed up to yield the final Makefile. The original Makefile.std for artKbcc is, for example. Nothing is really new with this Makefile.

######################################################################
PROJ = artkbcc
LIBS = -lm
LOCALFLAGS =
CFLAGS = $(COMPILERFLAGS) $(ANSIFLAGS) $(LOCALFLAGS)
GROELIB= $(DIRINST)/Lib/
ARTLIB= $(DIRINST)/LibArt/

List of modules to be compiled and linked together
OBJS = artKbcc.o blob_fns.o basisfns.o besselfns.o funciones.o ruido.o

Remember that when compiling 'make all' will be called.
all: $(PROJ)

$(PROJ): $(OBJS)
         $(CC) -o $(PROJ) $(OBJS) $(LIBMIP) $(ARTLIB)/MIPGlib.a $(LIBS)

$(OBJS):
         $(CC) $(CFLAGS) -I$(ARTLIB) $*.c

install: $(PROJ)
         @echo "Installing $(PROJ) ..."
         cp $(PROJ) $(DIRBIN)/$(PROJ)
         chmod a+rx $(DIRBIN)/$(PROJ)
         @echo "done"

clean:
         rm -f  *.o  $(PROJ)

When local_defs is taken into account the all variable definitions are put in the beginning of the file. Look, from the #### .... ### the two files are identical.

DIRINST       = /volatil/Xmipp
DIRSRC        = /volatil/Xmipp
MACHINE       = IRIS6
DIRBIN        = /volatil/Xmipp/bin
DIRLIB        = /volatil/Xmipp/Lib
DIRDOC        = /volatil/Xmipp/help
CC            = cc -64
AR            = ar rc
XLIBS         =
XMLIBS        =
LIBMIP        = /volatil/Xmipp/Lib/libmipIRIS6.a
COMPILERFLAGS = -c -O -D_64BITS
ANSIFLAGS     =
XWINDFLAGS    =
XMOTIFLAGS    =
######################################################################
PROJ = artkbcc
LIBS = -lm
LOCALFLAGS =
CFLAGS = $(COMPILERFLAGS) $(ANSIFLAGS) $(LOCALFLAGS)
GROELIB= $(DIRINST)/Lib/
ARTLIB= $(DIRINST)/LibArt/

OBJS = artKbcc.o blob_fns.o basisfns.o besselfns.o funciones.o ruido.o

all: $(PROJ)

$(PROJ): $(OBJS)
         $(CC) -o $(PROJ) $(OBJS) $(LIBMIP) $(ARTLIB)/MIPGlib.a $(LIBS)

$(OBJS):
         $(CC) $(CFLAGS) -I$(ARTLIB) $*.c

install: $(PROJ)
         @echo "Installing $(PROJ) ..."
         cp $(PROJ) $(DIRBIN)/$(PROJ)
         chmod a+rx $(DIRBIN)/$(PROJ)
         @echo "done"

clean:
         rm -f  *.o  $(PROJ)
 

REAL-LIFE MAKEFILE 4: MERGING FORTRAN AND C  

I will only indicate the changes from the standard Makefile in order to merge Fortran routines with C. More information about the pass (in and out) of parameters can be taken in .../Xmipp/3Dpack/Radon/*

Compilador de Fortran con librerias de 64 bits.
F77           = f77 -64
###########################################
LIBS       = -lspider$(MACHINE) -ltgc$(MACHINE) -lm
LFLAGS     = -L$(DIRSRC)/3Dpack/Lib
LOCALFLAGS = -I$(DIRSRC)/3Dpack/include
CFLAGS     = $(COMPILERFLAGS) $(ANSIFLAGS) $(LOCALFLAGS)
FFLAGS     = $(COMPILERFLAGS)

PROJ21     = doradon2d
OBJS21     = doradon2d.o radon.o
PROJ22     = fftra2d
OBJS22     = fftra2d.o fftradon.o
There are more definitions of C modules and programs but they are not necessary for the comprehension of the Fortran-C mix.

OBJFOR     = mrfft.o mrfour1.o

all: 2D 3D

2D: $(PROJ21)  $(PROJ22)  $(PROJ23)
3D: $(PROJ31)  $(PROJ32)  $(PROJ33)

This is a program completely made in C
$(PROJ21): $(OBJS21)
           $(CC) $(LFLAGS) $(OBJS21) -o $(PROJ21) -lmipp$(MACHINE) $(LIBS)
$(OBJS21):
           $(CC) $(CFLAGS) $*.c

This program, instead, is made up of 2 modules: one in C and another in Fortran. Modules are compiled separately and finally are linked by the Fortran "compiler"
$(PROJ22): $(OBJS22) $(OBJFOR)
           $(F77) $(LFLAGS) $(OBJS22) $(OBJFOR) -o $(PROJ22) $(LIBS)
$(OBJS22):
           $(CC) $(CFLAGS) $*.c
Only compilation
$(OBJFOR):
           $(F77) $(FFLAGS) $*.f
 

 REAL-LIFE MAKEFILE 5: DEPENDENCIES  

This Makefile is taken from a Qt test program, please, don't pay attention to parameters, I only want to make remarks on the dependencies generated by makedepend. The idea is to take into account, not only changes in source (.c) files, but changes in header files. The first time Makefile is created the file ends in the line that says "DO NOT DELETE THIS LINE ...", after the first call to make (which should be 'make depend') the lines below this point are added by makedepend itself.

####### This section was automatically generated from
#######    /home/hanord/qt/tutorial/Makefile for building on
#######     on Tue Apr  1 19:27:47 MET DST 1997

QTDIR  = /usr/local/contrib/qt-1.32
INCDIR = $(QTDIR)/include
CFLAGS =  -O2 -fno-strength-reduce -Wall -W
LIBCFLAGS = -fPIC
YACCCFLAGS = -Wno-unused -Wno-parentheses
LFLAGS = -L$(QTDIR)/lib -lqt
CC = gcc
MOC = /opt/qt-1.32/bin/moc
SHELL = /bin/sh

####### End of automatically generated section
#
# $Source: /local/lib/cvs/qt/tutorial/t1/Makefile,v $
#

####### Files

SOURCES = mywidget.cpp
OBJECTS = mywidget.o
TARGET  = mywidget

####### Implicit rules
This is the first time .SUFFIXES target is introduced. It means that our files can have a new extension, namely, .cpp. This line is needed if we are to define the next inference rule.
.SUFFIXES: .cpp

The following rule gives the way to pass from a .cpp file to a .o, ie, compile a C++ program. $< meant the file which shot this rule.
.cpp.o:
           $(CC) -c $(CFLAGS) -I$(INCDIR) $<

####### Build rules
all: $(TARGET)

$OBJECTS is the prerequisite for $TARGET, but there is no target rule for $OBJECTS so an inference rule is looked for (.cpp.o) and $OBJECTS is resolved according to that rule. Once the different modules are compiled this rule only have to link
$(TARGET): $(OBJECTS)
           $(CC) $(OBJECTS) -o $(TARGET) $(LFLAGS) -lm

Generate dependencies with header files. Any change in a header file will cause the remake of the program. The first call to make should be 'make depend'
depend:
           @makedepend -I$(INCDIR) $(SOURCES) 2> /dev/null

Show files implied; as $(HEADERS) is not initialiazed, it is empty.
showfiles:
           @echo $(HEADERS) $(SOURCES) Makefile

The next "strange" file names are not Make macros
clean:
           rm -f *.o *.bak *~ *% #*
           rm -f $(TARGET)

# DO NOT DELETE THIS LINE -- make depend depends on it.

Dependencies of mywidget.o with different header files
mywidget.o: /usr/local/contrib/qt-1.32/include/qwidget.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qwindefs.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qobjdefs.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qglobal.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qobject.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qstring.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qarray.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qgarray.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qshared.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qgeneric.h
mywidget.o: /usr/include/string.h /usr/include/standards.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qevent.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qrect.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qsize.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qpoint.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qpaintd.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qpalette.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qcolor.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qcursor.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qfont.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qfontmet.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qfontinf.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qpainter.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qregion.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qpen.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qbrush.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qpntarry.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qwmatrix.h
mywidget.o: /usr/local/contrib/qt-1.32/include/qapp.h /usr/include/stdio.h
mywidget.o: /usr/include/sgidefs.h
 

REAL-LIFE MAKEFILE 6: QT  

This Makefile is the same as the one in the previous example, but this time I want to emphasize on the libraries and options selected for compilation with Qt. All the options are taken from a demo Qt program, this options are not compulsory needed, in fact I would remove several in order to have more or less the same options in all Xmipp programs. I will mark in blue all options that are "optional".

####### This section was automatically generated from
#######    /home/hanord/qt/tutorial/Makefile for building on
#######     on Tue Apr  1 19:27:47 MET DST 1997

This is the QTDIR in bossa-nova
QTDIR  = /usr/local/contrib/qt-1.32
INCDIR = $(QTDIR)/include

Compiler flags:
O2                                    Optimization level 2
no-strength-reduce    Not documented
W Wall                            High level of information about Warnings
CFLAGS =  -O2 -fno-strength-reduce -Wall -W

fPIC                                  Generate Position Independent Code, for dynamic linking
LIBCFLAGS = -fPIC

Wno-unused                 Not documented
Wno-parentheses        Not documented
YACCCFLAGS = -Wno-unused -Wno-parentheses

Library to include and where to find it
LFLAGS = -L$(QTDIR)/lib -lqt

CC = gcc

moc is a executable file I don't know what for
MOC = /opt/qt-1.32/bin/moc
SHELL = /bin/sh

####### End of automatically generated section
#
# $Source: /local/lib/cvs/qt/tutorial/t1/Makefile,v $
#

####### Files

SOURCES = mywidget.cpp
OBJECTS = mywidget.o
TARGET  = mywidget

From this point it is commented in the previous example
####### Implicit rules
.SUFFIXES: .cpp

.cpp.o:
           $(CC) -c $(CFLAGS) -I$(INCDIR) $<

####### Build rules
all: $(TARGET)

$(TARGET): $(OBJECTS)
           $(CC) $(OBJECTS) -o $(TARGET) $(LFLAGS) -lm

depend:
           @makedepend -I$(INCDIR) $(SOURCES) 2> /dev/null

showfiles:
           @echo $(HEADERS) $(SOURCES) Makefile

clean:
           rm -f *.o *.bak *~ *% #*
           rm -f $(TARGET)

# DO NOT DELETE THIS LINE -- make depend depends on it.
 

REAL-LIFE MAKEFILE 7: 32/64 BITS LIBRARIES  

Just suppose we want to link a program with 32 or 64 bits. First of all it is very important you have the correct path to the libraries in the variables

LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib
LD_LIBRARYN32_PATH=/usr/lib32:/lib32:/usr/local/lib32
LD_LIBRARY64_PATH=/usr/lib64:/lib64:/usr/local/lib64
 
This is usually done in the .profile file. Now it's time to say with which library we want to compile (remember that things only run with 64 bits in bossa-nova, and not in rumba, indy, b12sg1, ...). Let's start with 32 bits and then point the changes for 64 bits. It is important to say that 32 bits must be assume in compile stage, linking stage and library inclusion!!! That is to say even the library which is referenced must be compiled with 32 bits. For instance, for the Markhan program the Makefile is

DIRINST       = /mnt/bioinfo/volatil/Xmipp
DIRBIN        = /mnt/bioinfo/volatil/Xmipp/bin
DIRLIB        = /mnt/bioinfo/volatil/Xmipp/Lib
DIRDOC        = /mnt/bioinfo/volatil/Xmipp/help
CC            = cc
AR            = ar rc
XLIBS         = -lX11
XMLIBS        = -lXm -lPW -lXt -lX11
LIBMIP        = /mnt/bioinfo/volatil/Xmipp/Lib/libS62mip.a
COMPILERFLAGS = -c -D_sgIRIX -I/mnt/bioinfo/volatil/Xmipp/Lib
ANSIFLAGS     = -D__STDC -D_IRIX5
XWINDFLAGS    =
XMOTIFLAGS    =
###########################################################################
PROJ = markhan
LIBS = -lm
LOCALFLAGS =
CFLAGS= -32 $(COMPILERFLAGS) $(ANSIFLAGS) $(LOCALFLAGS)

OBJS= markhan.o

all:  $(PROJ)

# link

$(PROJ): $(OBJS)
 $(CC) -32 -o $(PROJ) $(OBJS) $(LIBMIP) $(LIBS)
#
# compiled

$(OBJS) :
 $(CC) $(CFLAGS) $*.c
#
install: $(PROJ)
 @echo "Installing $(PROJ) ..."
 cp $(PROJ) $(DIRBIN)/$(PROJ)
 chmod a+rx $(DIRBIN)/$(PROJ)
 @echo "done"

clean:
 rm -f  *.o  $(PROJ)

As it can be seen there is no simple way of expressing the 32 bits compilation in both stages (compiling and linking) just because in link phase there is no way of telling flags from Makefile.Xmipp.  DON'T FORGET that ALL libraries implied must be compiled with 32 bits, namely, libm.a and libS62mip.a must have been compiled with 32 bits.

If we wanted to generate a file to run with 64 bits then we only need to substitute the two red labels (-32) in the Makefile with a new label (-64). In theory any C program could run in a 32 bits architecture as well as in a 64 bits one, unless the programmer uses pointers in a 'bad' manner. In pointer arithmetic if p is a pointer to structure, p+1 is a pointer to the following structure and not to the following byte. The compiler will make the work for you of calculating the exact displacement that must be applied to the pointer. However there are programmers who prefer do it by themselves and prefer to do something like this (struct structname *) ((char *) p + sizeof(struct structname)). This kind of instructions change from a 32 bits to a 64 bits architecture as addresses differ in the number of bytes. I don't know if there are any other problem such that a program in 32 bits could not run in 64.
 

REAL-LIFE MAKEFILE 8: C++  

*** Ver groe.h de ~coss/Xmipp/Lib para hacer luego una descripción de qué es lo que hay que variar para mezclar cosas de C y C++