next up previous 211
Next: Overview of tools for making the modifications
Up: Modifications to code
Previous: Enlarging integer type in C


Changes to makefile/mk

Since not all build environments require the enlarged integers, the build process must be modified so that 64-bit integers are used for some build environments and 32-bit integers for others. Identifying build environments is done by using different values of the SYSTEM macro. As well as the existing supported values

which indicate that 32-bit integers should be used as before, the following new ones are added which indicate that 64-bit integers should be used. Thus two new stanzas are required in the mk file for each package setting the values of the other makefile macros for the newly supported systems.

Additionally, if the package contains Fortran source, a new macro INTEGER8 should be defined by the mk file. This should contain text which is to replace `INTEGER * 8' declarations in fortran source code. If blank (defined as spaces or the empty string) it means that INTEGER * 8 declarations should be left unchanged. Therefore for 64-bit systems this should be defined as the empty string, and for 32-bit systems it should be defined as `INTEGER    ' (defining it with four trailing spaces is not required, but improves the aesthetics of the modified source files). The makefile should then apply the INTEGER*8 -> $(INTEGER8) substitution to the fortran source files as it extracts them from the tar archive where they are stored. The recommended code for this is:

sed "s/^[ \t]*[Ii][Nn][Tt][Ee][Gg][Ee][Rr] *\* *8/      $(INTEGER8)/"
which should be applied only when test $(INTEGER8) is true. Note that this changes nothing except variable declarations; in particular it will not modify references to INTEGER*8 type in IMPLICIT statements. It also makes no allowance for the more bizarre spacing possibilities permissible in Fortran 77. It would be possible to use a more comprehensive editing script, but in the interests of clarity, and of simplicity at build time, it is recommended that the above is used, and source code required to match the given pattern where edits are needed.

The intention is that Fortran source code is stored in the source archive with INTEGER*8 declarations, and is edited if necessary as it is extracted from the tar file, prior to being written in the build directory. In this way, the set of Fortran files in the build directory will be consistent and compilable, though it may not have the same content as the set of files in the source archive.

For C files, the source code itself does not need to be modified at build time, but the INT_BIG preprocessor macro must be defined. This is most easily done by adding a -DINT_BIG=int or -DINT_BIG=long flag as appropriate to the CFLAGS macro in each mk stanza. Alternatively, a SOURCE_VARIANT-controlled header file could be written and included into all C source files; the header file extreme.h could be used for this purpose.

The following gives the relevant parts of a basic mk file by way of example:

   ...
#  Supported Systems:
#     The following systems are currently supported and may be
#     identified by defining the SYSTEM environment variable
#     appropriately before invoking this script:
#
#        alpha_OSF1
#           DEC Alpha machines running OSF1
#
#        alpha_OSF1_64
#           DEC Alpha machines running OSF1, long integers
#
#        ix86_Linux
#           Intel PC running Linux
#
#        sun4_Solaris
#           SUN Sparcstations running SunOS 5.x (Solaris)
#
#        sun4_Solaris_64
#           SUN Sparcstations running 64-bit SunOS 5.x (Solaris), long integers
   ...
#        CFLAGS (-O -DINT_BIG=int)
#           The C compiler options to use.
#
#        INTEGER8 (INTEGER    )
#           Replacement text for 'INTEGER * 8' declarations in the original
#           original Fortran source code.  If set to the empty string,
#           INTEGER * 8 declarations will not be modified.  For 64-bit
#           systems which must be able to deal with very large images
#           this should be set to the empty string (or 'INTEGER*8').
#           Otherwise, more efficient code may be generated by setting
#           it to 'INTEGER' or 'INTEGER*4'.  The trailing whitespace is
#           optional but may make source code more readable.
   ...

      export INTEGER8
   ...

      case "$SYSTEM" in

#  DEC Alpha machines running OSF1.
#  -------------------------------
         alpha_OSF1)
            CFLAGS='-DINT_BIG=int'
            INTEGER8='INTEGER    '
               ...

#  DEC Alpha machines running OSF1, long integers.
#  ----------------------------------------------
         alpha_OSF1_64)
            CFLAGS='-DINT_BIG=long'
            INTEGER8=''
               ...

#  SUN Sparcstations running SunOS 5.x (Solaris).
#  ---------------------------------------------
         sun4_Solaris)
            CFLAGS='-DINT_BIG=int'
            INTEGER8='INTEGER    '
               ...

#  SUN Sparcstations running 64-bit SunOS 5.x (Solaris), long integers.
#  -------------------------------------------------------------------
         sun4_Solaris_64)
            CFLAGS='-DINT_BIG=long -xarch=v9'
            FFLAGS='-xarch=v9'
            INTEGER8=''
               ...

#  Intel PC running Linux.
#  ----------------------
         ix86_Linux)
            CFLAGS='-DINT_BIG=int'
            INTEGER8='INTEGER    '
               ...
Note the `-xarch=v9' addition to the sun4_Solaris_64 CFLAGS and FFLAGS variables, which instructs the compiler to compile for a 64-bit system. Tru64 Unix C compiles for 64 bit executables by default, so needs no extra flags.

It may also be desirable to add the lines:

            SOURCE_VARIANT='alpha_OSF1'
and
            SOURCE_VARIANT='sun4_Solaris'
to the alpha_OSF1_64 and sun4_Solaris_64 stanzas respectively, if the same machine-specific source files can be used for 32-bit and 64-bit builds on the same platforms; if this is not the case then SOURCE_VARIANT should be left to default to the value of SYSTEM as usual, and additional copies of the system-dependent files must be supplied.

The relevant parts of a suitable matching makefile would look something like this:

#  Default values for macros for compiling C and Fortran source code.

CFLAGS = -O -DINT_BIG=int
   ...

#  Default replacement text for Fortran INTEGER * 8 type.

INTEGER8 = INTEGER
   ...

#  Macro for filter to replace INTEGER * 8 declarations with INTEGER8.

REPLACE_INTEGER8 = sed \
   "s/^[ \t]*[Ii][Nn][Tt][Ee][Gg][Ee][Rr] *\* *8/      $(INTEGER8)/"

#  Rules for extracting non-Fortran source files from the source archive.

$(C_ROUTINES) $(PUBLIC_C_INCLUDES) $(PRIVATE_C_INCLUDES):
        $(TAR_OUT) $(PKG_NAME)_source.tar $@
        @ if test -f $@; then :;\
           else echo $@ is not in the tar file; exit 1; fi

#  Rules for extracting Fortran source files from the source archive.

$(F_ROUTINES) $(PUBLIC_F_INCLUDES) $(PRIVATE_F_INCLUDES):
        $(TAR_OUT) $(PKG_NAME)_source.tar $@
        @ if test -f $@; then :;\
           else echo $@ is not in the tar file; exit 1; fi
        if test $(INTEGER8); then \
           $(REPLACE_INTEGER8) < $@ > $@_tmp; \
           mv $@_tmp $@; \
        else :; fi

#  Rules for extracting platform specific Fortran files from the archive.

$(PLATFORM_F) dummy_target2:
        $(TAR_OUT) $(PKG_NAME)_source.tar $@_$(SOURCE_VARIANT)
        @ if test -f $@_$(SOURCE_VARIANT); then :;\
           else echo $@_$(SOURCE_VARIANT) is not in the tar file; exit 1; fi
        if test $(INTEGER8); then \
           $(REPLACE_INTEGER8) < $@_$(SOURCE_VARIANT) > $@; \
           rm -f $@_$(SOURCE_VARIANT); \
           else mv $@_$(SOURCE_VARIANT) $@; fi
   ...

#  Enter information about the current machine and build environment
#  into the date stamp file.
   ...
        @ echo '   INTEGER8: $(INTEGER8)'     >>$(DATE_STAMP)
Lists of files for extraction from the source archive may have to be split into Fortran and non-Fortran sublists since the code for extracting them will now differ. For instance it might be convenient to replace assignments like this:
PUBLIC_INCLUDES = $(PKG_NAME)_par $(PKG_NAME)_err $(PKG_NAME).h
with something like the following:
PUBLIC_F_INCLUDES = $(PKG_NAME)_par $(PKG_NAME)_err
PUBLIC_C_INCLUDES = $(PKG_NAME).h
PUBLIC_INCLUDES = $(PUBLIC_F_INCLUDES) $(PUBLIC_C_INCLUDES)
so that the lists of Fortran and C files can appear as targets of separate extraction rules, as in the example above.

It may also be necessary to add dependencies for INCLUDE files inserted by the conversion tools; inscnf may include CNF_PAR and crepint may include extreme.h in some modified source files. Rules will need to be made for building links to the referenced include files, and dependencies added for the object files corresponding to the source files so modified.

Files may be extracted from the source archive(s) in more places than one in the makefile - in particular, for some reason lost in the mists of time the do_test target usually extracts required files from the source archives explicitly rather than relying on a dependency. It will be necessary to identify all such places (try grepping for TAR_OUT), and ensure that the INTEGER8 macro is substituted in to the source code before it gets compiled.

Note that because of the way this approach edits Fortran source files on their way out of the source archive, the copies of the files in the build directory may not be the same as the files in the source archive, and so files cannot in general be transferred between the build directory and source archive simply using tar. This means that in general the source archive cannot be rebuilt from the files in the build directory. This may well break private, non-standard targets inserted into the makefile by the package developer (commonly called archive), and effectively means that it is not possible to tweak package source code in the build directory prior to re-exporting it.

The scripts extmk and extmakefile are provided to make the necessary modifications to mk and makefile files respectively, and are described fully in Appendix A. extmk can normally make all the required changes to mk, but extmakefile can only add some of the required parts; other edits such as deciding which files need to be extracted as Fortran and which as non-Fortran files must be made by hand.



next up previous 211
Next: Overview of tools for making the modifications
Up: Modifications to code
Previous: Enlarging integer type in C


Starlink System Note 73
Mark Taylor
13 August 2001
E-mail:ussc@star.rl.ac.uk

Copyright © 2001 Council for the Central Laboratory of the Research Councils