Chapter 6
Miscellaneous hints and tips

 6.1 Forcing automake’s choice of linking language
 6.2 Conditionally building components, I
 6.3 Conditionally Building Components, II
 6.4 Manipulating compiler and linker flags
 A.1 AC_FC_CHECK_HEADERS
 A.2 AC_FC_CHECK_INTRINSICS
 A.3 AC_FC_HAVE_BOZ
 A.4 AC_FC_HAVE_OLD_TYPELESS_BOZ
 A.5 AC_FC_HAVE_PERCENTLOC
 A.6 AC_FC_HAVE_PERCENTVAL
 A.7 AC_FC_HAVE_TYPELESS_BOZ
 A.8 AC_FC_HAVE_VOLATILE
 A.9 AC_FC_LITERAL_BACKSLASH
 A.10 AC_FC_OPEN_SPECIFIERS
 A.11 AC_FC_RECL_UNIT
 A.12 AC_PROG_FC
 A.13 AC_PROG_FPP
 A.14 STAR_CHECK_PROGS
 A.15 STAR_CNF_BLANK_COMMON
 A.16 STAR_CNF_COMPATIBLE_SYMBOLS
 A.17 STAR_DECLARE_DEPENDENCIES
 A.18 STAR_DEFAULTS
 A.19 STAR_INITIALISE_FORTRAN_RTL
 A.20 STAR_LARGEFILE_SUPPORT
 A.21 STAR_LATEX_DOCUMENTATION
 A.22 Variable STAR_MANIFEST_DIR
 A.23 STAR_MESSGEN
 A.24 STAR_MONOLITHS
 A.25 STAR_PATH_TCLTK
 A.26 STAR_PLATFORM_SOURCES
 A.27 STAR_PREDIST_SOURCES
 A.28 STAR_PRM_COMPATIBLE_SYMBOLS
 A.29 STAR_SPECIAL_INSTALL_COMMAND
 A.30 STAR_SUPPRESS_BUILD_IF
 A.31 STAR_XML_DOCUMENTATION
 A.32 starxxx_DATA – special installation directories
 A.33 Obsolete macros
  A.33.1 AC_F77_HAVE_OPEN_READONLY
  A.33.2 STAR_DOCS_FILES and friends
  A.33.3 STAR_FC_LIBRARY_LDFLAGS
  A.33.4 STAR_HAVE_FC_OPEN_READONLY

This section contains assorted techniques and patterns which don’t fit neatly in anywhere else. Please do add to this section.

6.1 Forcing automake’s choice of linking language

XXX no: there’s an better mechanism, as yet undocumented. Watch this space, but don’t use this technique.

When building a library or application, automake needs to make a decision about which language to use to do the final link. For example, it must use the Fortran linker to make a library which consists of or includes Fortran modules, and the C linker if it consists of pure C. This matters more on some platforms than others – the OSX linker has some very fixed ideas on this point (it heartily disapproves of common blocks, and so needs special Fortran juju to make a library from Fortran which uses them).

Automake makes this decision based on the source code which is listed in the library’s _SOURCES variable. When you are assembling a library purely from convenience libraries, however (see section ‘Linking static libraries’ in the Libtool manual), the _SOURCES variable is empty, and automake ends up using the C linker, for want of any other information.

You can avoid this problem, and indicate to automake which langauge it should use, by giving a dummy value for the _SOURCES variable as follows:

  libsubpar_adam_la_SOURCES = dummy_routine.f
  libsubpar_adam_la_LIBADD = \
          subpar/libsubpar_convenience.la \
          parsecon/libparsecon_convenience.la

where the dummy_fortran.f module is a trivial Fortran routine:

  C A dummy Fortran routine.  See comments in Makefile.am
        SUBROUTINE DUMMY
        END

As the comment indicates, it is wise to include an explanation of this ... let’s not call it a hack ... in the Makefile.am.

This is currently used in the ‘pcs’, ‘gks’, ‘astrom’ and ‘pgplot’ components.

6.2 Conditionally building components, I

It is occasionally useful to build code conditionally, depending on features of the environment. About the only place where this is necessary, however, is when building a target of a configure dependency (see Sec. A.17), where a library (for example) must be built only if it is not available on the platform already.

There is no way to decide not to build a component, so instead we arrange the configuration of the component in such a way that if the component’s code is not required, then the component trivially builds and installs nothing, or nothing more than a stamp file.

This is true for the jpeg component, which is a configure dependency of startcl, and located in the repository in thirdparty/ijg/jpeg. The important parts of jpeg’s configure.ac are as follows:

  AC_CHECK_HEADER([jpeglib.h],
    [MAIN_TARGET=jpeglib-stamp],
    [
    (
      cd src
      echo ./configure --prefix=$prefix --cache-file=config.cache
      ./configure --prefix=$prefix --cache-file=config.cache
    )
    MAIN_TARGET=jpeglib
  ])
  AC_SUBST(MAIN_TARGET)
  
  STAR_SPECIAL_INSTALL_COMMAND([
      if test $(MAIN_TARGET) = jpeglib; then
        cd src;
        for d in bin lib include man/man1;
          do $(mkdir_p) $$DESTDIR$(prefix)/$$d;
        done;
        $(MAKE) DESTDIR=$$DESTDIR install install-lib;
      fi])

The first part wraps the actual jpeglib configuration code (see Sec. 4.5.3 for the rationale for that code) inside an autoconf test for the jpeglib.h include file. If it finds it, there is nothing to do; if it doesn’t then it does actually configure the package. The decision it makes is recorded in the substituted variable @MAIN_TARGET@ and its corresponding Makefile variable $(MAIN_TARGET).

Note that the STAR_SPECIAL_INSTALL_COMMAND is expanded at a different time from the header test, with the effect that it is effective in both conditions, when the header file is there and when it isn’t. Thus the command inside it must be written with this in mind, and explicitly test the value of $(MAIN_TARGET).

The Makefile.am has corresponding support, the important parts of which are as follows.

  all-local: $(MAIN_TARGET)
  
  jpeglib:
          cd src; $(MAKE) all
  
  jpeglib-stamp:
          rm -f $@
          { date; \
            echo "jpeglib.h found in system -- no need to build our own"; } >$@

We can’t override the ‘all’ target, but instead use automake’s ‘all-local’ hook which, if it is present, is built at the same time as ‘all’. Thus depending on the value of the variable $(MAIN_TARGET), as determined and substituted by configure.ac, we build either the jpeglib software, or a stamp file. The install command in the configure.ac file above then avoids installing anything if $(MAIN_TARGET) is not the string jpeglib.

6.3 Conditionally Building Components, II

The other way in which you might conditionally build a component is to suppress building it at the end of the configuration stage, if it turns out that the important features are missing from the environment. For a description of this, see Sec. A.30.

6.4 Manipulating compiler and linker flags

Sometimes it is necessary to add compiler or linker flags for particular make targets, or add libraries to a link. This is described in the automake manual, in the section Program and Library Variables. This is a powerful mechanism, but there is a gotcha.

For each of the variables CFLAGS, LDFLAGS and so on, automake maintains a parallel variable AM_CFLAGS or AM_LDFLAGS, the contents of which are managed by automake and autoconf, so that the unprefixed variables are free to be overridden by the user (see section Variables reserved for the user of the automake manual; to be clear, ‘user’ in this context means the person building the distributed software, as opposed to the maintainer, or whoever is creating the distribution). If automake sees one of the above per-target variables, however, it carefully uses this instead of the AM_ variable, not in addition to it. This replacement is sensible, since if this were not the case then there would be no way to remove a problematic flag from an AM_ variable, but it is not the behaviour you might guess at first, and so can come as rather a surprise. Given that you want to add to these flags rather than replace them, you do so with the idiom:

  libxxx_la_FCFLAGS = $(AM_FCFLAGS) -my-magic-flag

An alternative to setting per-target flags like this is to set one or more of the AM_*FLAGS variables directly. These variables are ‘yours’ as the author of the Makefile.am and configure.ac files – the automake system ensures that the variables are included in the correct places in compile and link commands, but neither it nor autoconf set these flags. See the FAQ on ‘Flag Variables Ordering’ in the automake manual for some further discussion.

There is another set of similar variables, named STAR_*FLAGS, which are maintained by starconf and the STAR_* macros in configure.ac, and which are the means by which those macros pass their discovered magic on to the Makefile. You shouldn’t need to know that, and you should not need to adjust these variables at all, but if for some occult reason you need to refer to the complete set of flags used to compile and link programs, you will need to include these flags also. In general, Makefile variables such as $(COMPILE) and $(FCCOMPILE) are most suitable for any by-hand compilations you need to do, and they already have all the extra flags you need, in the right order..