
#  N.B. the previous line should be blank.
#++
#  Name:
#     ast_link

#  Purpose:
#     Link a program with the AST library.

#  Type of Module:
#     Shell script.

#  Description:
#     This command should be used when building programs which use the AST
#     library, in order to generate the correct arguments to allow the compiler
#     to link your program. The arguments generated are written to standard
#     output but may be substituted into the compiler command line in the
#     standard UNIX way using backward quotes (see below).
#
#     By default, it is assumed that you are building a stand-alone program
#     which does not produce graphical output. However, switches are provided
#     for linking other types of program.
#
#     Note, since AST uses the SLALIB library (Starlink User Note SUN/67) for 
#     its low-level coordinate conversions, SLALIB must be installed prior to 
#     using AST. 

#  Invocation:
#c     cc program.c -L/star/lib `ast_link [switches]` -o program
#f     f77 program.f -L/star/lib `ast_link [switches]` -o program

#  Switches:
#     The following switches may optionally be given to this command to
#     modify its behaviour:
#
#     - ``-csla'': Requests that the program be linked so that it uses the
#     C implementation of the SLALIB positional astronomy library. By default,
#     the Fortran implementation is used (Starlink User Note SUN/67). Note
#     that both implementations of SLALIB use the same name (``libsla.a'') for
#     their library, so you must ensure that the directories searched to
#     resolve library references will result in the correct version of this
#     file (Fortran or C) being located. Note, the Fortran version of SLALIB
#     includes a script called sla_link which should be available on the 
#     current PATH if the Fortran version is to be used. If this script cannot
#     be found, then no options to link with SLALIB will be included and 
#     consequently errors will probably be reported by the compiler because 
#     of unresolved references to the SLALIB routines used by AST. If the 
#     ``-csla'' option is used, then the sla_link script is not needed.
#
#     - ``-ems'': Requests that the program be linked so that error messages
#     produced by the AST library are delivered via the Starlink EMS (Error
#     Message Service) library (Starlink System Note SSN/4). By default,
#     error messages are simply written to standard error.
#
#     - ``-grf'': Requests that no arguments be generated to specify which
#     graphics system is used to display output from the AST library. You
#     should use this option only if you have implemented an interface to a
#     new graphics system yourself and wish to provide your own arguments for
#     linking with it. This switch differs from the other ``grf'' switches in 
#     that it assumes that your graphics module implements the complete 
#     interface required by the current version of AST. If future versions of 
#     AST introduce new functions to the graphics interface, this switch will 
#     cause ``unresolved symbol'' errors to occur during linking, warning you 
#     that you need to implement new functions in your graphics module. To 
#     avoid such errors, you can use one of the other, version-specific, 
#     switches in place of the ``-grf'' switch, but these will cause run-time 
#     errors to be reported if any AST function is invoked which requires 
#     facilities not in the implemented interface.
#
#     - ``-grf_v2.0'': This switch is equivalent to the ``-mygrf'' switch.
#     It indicates that you want to link with your own graphics module which 
#     implements the graphics interface required by V2.0 of AST.
#
#     - ``-grf_v3.2'': Indicates that you want to link with your own graphics 
#     module which implements the graphics interface required by V3.2 of AST.
#
#     - ``-myerr'': Requests that no arguments be generated to specify how
#     error messages produced by the AST library should be delivered. You
#     should use this option only if you have implemented an interface to a
#     new error delivery system yourself and wish to provide your own
#     arguments for linking with it.
#
#     - ``-mygrf'': This switch has been superceeded by the ``-grf'' switch,
#     but is retained in order to allow applications to be linked with a 
#     graphics module which implements the interface used by AST V2.0. It is 
#     equivalent to the ``-grf_v2.0'' switch.
#
#     - ``-pgp'': Requests that the program be linked so that
#     graphical output from the AST library is displayed via the
#     Starlink version of the PGPLOT graphics package (which uses GKS
#     for its output). By default, no graphics package is linked and
#     this will result in an error at run time if AST routines are
#     invoked that attempt to generate graphical output.
#
#     - ``-pgplot'': Requests that the program be linked so that
#     graphical output from the AST library is displayed via the
#     standard (or ``native'') version of the PGPLOT graphics
#     package. By default, no graphics package is linked and this will
#     result in an error at run time if AST routines are invoked that
#     attempt to generate graphical output.

#  Examples:
#c     cc display.c -L/star/lib `ast_link -pgplot` -o display
#c        Compiles and links a C program called ``display'' which uses
#c        the standard version of PGPLOT for graphical output.
#c     cc import.c -L/star/lib `ast_link -csla` -o import
#c        Compiles and links a C program called ``import'' which does
#c        not produce any graphical output. The ``-csla'' flag indicates that
#c        the C version of SLALIB should be used by AST (to avoid conflict
#c        with the main program which may already be calling this version).
#c     cc plotit.c -L. -L/star/lib `ast_link -grf` -lgrf -o plotit
#c        Compiles and links a C program ``plotit''. The ``-grf''
#c        switch indicates that graphical output will be delivered through
#c        a graphical interface which you have implemented yourself, which 
#c        corresponds to the interface required by the current version of AST. 
#c        Here, this interface is supplied by means of the ``-lgrf'' library 
#c        reference.
#c     cc plotit.c -L. -L/star/lib `ast_link -grf_v2.0` -lgrf -o plotit
#c        Compiles and links a C program ``plotit''. The ``-grf_v2.0''
#c        switch indicates that graphical output will be delivered through
#c        a graphical interface which you have implemented yourself, which 
#c        corresponds to the interface required by version 2.0 of AST. 
#c        Here, this interface is supplied by means of the ``-lgrf'' library 
#c        reference.
#f     f77 display.f -L/star/lib `ast_link -pgplot` -o display
#f        Compiles and links a Fortran program called ``display'' which uses
#f        the standard version of PGPLOT for graphical output.
#f     f77 import.f -L/star/lib `ast_link -csla` -o import
#f        Compiles and links a Fortran program called ``import'' which does
#f        not produce any graphical output. The ``-csla'' flag indicates that
#f        the C version of SLALIB should be used by AST (this should be avoided
#f        if the main program already calls the Fortran version).
#f     f77 plotit.f -L. -L/star/lib `ast_link -grf` -lgrf -o plotit
#f        Compiles and links a Fortran program ``plotit''. The ``-grf''
#f        switch indicates that graphical output will be delivered through
#f        a graphical interface which you have implemented yourself, which 
#f        corresponds to the interface required by the current version of AST. 
#f        Here, this interface is supplied by means of the ``-lgrf'' library 
#f        reference.
#f     f77 plotit.f -L. -L/star/lib `ast_link -grf_v2.0` -lgrf -o plotit
#f        Compiles and links a Fortran program ``plotit''. The ``-grf_v2.0''
#f        switch indicates that graphical output will be delivered through
#f        a graphical interface which you have implemented yourself, which 
#f        corresponds to the interface required by version 2.0 of AST. 
#f        Here, this interface is supplied by means of the ``-lgrf'' library 
#f        reference.

#  Copyright:
#     Copyright (C) 2004 Central Laboratory of the Research Councils

#  Authors:
#     RFWS: R.F. Warren-Smith (STARLINK)
#     DSB: David S. Berry (STARLINK)
#     {enter_new_authors_here}

#  History:
#     11-JUN-1996 (RFWS):
#        Original version.
#     11-NOV-1996 (RFWS):
#        Added switches.
#     18-NOV-1997 (RFWS):
#        Adapted prologue for document extraction.
#     28-SEP-1998 (RFWS):
#        Distinguish between -pgp and -pgplot options.
#     12-JAN-2001 (DSB):
#        Move terminating "}" in function "find" onto a new line to
#        avoid error when run under bash 2.04.11(1) (redhat 7).
#     3-MAY-2001 (DSB):
#        Added a terminating ";" to the "done" statement at the end of 
#        the "find" function, so that ast_link can be used on Debian Linux.
#     23-JAN-2004 (DSB):
#        Added switches to support older grf implementations.
#     {enter_further_changes_here}

#  Bugs:
#     {note_any_bugs_here}

#--

#  This line is edited during installation of this script to define a list
#  of the libraries that must be linked in order to resolve Fortran 77
#  references made from within a C main program. Typically, these will arise
#  from libraries written in Fortran which the C program calls.
      flibs='FLIBS'

#  This function searches the directory path specified in PATH, looking for
#  an executable file which is not a directory. If found, it echos the full
#  file name to standard output. Otherwise, it outputs nothing.
      find() { IFS=':'; for d in $PATH; do f="${d:=.}/${1}"
                  test -x "${f}" -a ! -d "${f}" && echo "${f}" && break
               done;
             }

#  Initialise linking options.
      err=''
      grf=''
      sla=''
      f77=''

#  Interpret command line switches.
#  --------------------------------
      while :; do
         case "${1}" in

#  -csla - Requests C version of SLALIB.
         -csla)
            sla='c'
            shift;;

#  -ems - Requests error reporting through EMS.
         -ems)
            err='ems'
            shift;;

#  -myerr - Requests no error reporting.
         -myerr)
            err='my'
            shift;;

#  -grf - Requests no graphics.
         -grf)
            grf='current'
            shift;;

#  -mygrf - Requests no graphics, except for null implementations of 
#  functions aded to the grf interface after AST V2.0.
         -mygrf)
            grf='v2.0'
            shift;;

#  -grf_v2.0 - Requests no graphics, except for null implementations of 
#  functions aded to the grf interface after AST V2.0.
         -grf_v2.0)
            grf='v2.0'
            shift;;

#  -grf_v3.2 - Requests no graphics, except for null implementations of 
#  functions aded to the grf interface after AST V3.2. 
         -grf_v3.2)
            grf='v3.2'
            shift;;

#  -pgp - Requests graphical output through Starlink PGPLOT.
         -pgp)
            grf='pgp'
            shift;;

#  -pgplot - Requests graphical output through native PGPLOT.
         -pgplot)
            grf='pgplot'
            shift;;

#  Once all switches have been read, continue with the rest of the script.
         '') break;;

#  Catch unrecognised arguments and report an error.
         *)
            echo >&2 "ast_link: unknown argument \""${1}"\" given"
            exit 1;;
         esac
      done

#  Link with the main AST library.
#  -------------------------------
#  Start forming the list of arguments with the main AST library itself and
#  the "wcslib" module.
      args='-last -last_wcslib'

#  Generate arguments for linking SLALIB.
#  --------------------------------------
      case "${sla}" in

#  The C version of SLALIB has no link script, so simply specify the library
#  itself.
      c) args="${args} -lsla";;

#  Otherwise, link with the AST SLALIB interface and the Fortran library via
#  the SLALIB link script (if found).
      *) args="${args} -last_slalib `\`find sla_link\``"
         f77='y';;
      esac

#  Generate arguments for linking the graphics system.
#  ---------------------------------------------------
      case "${grf}" in

#  If using Starlink PGPLOT, link with the AST PGPLOT interface and
#  the Fortran library via the PGP link script (if found).
      pgp) args="${args} -last_pgplot `\`find pgp_link\``"
           f77='y';;

#  If using native PGPLOT, link with the AST PGPLOT interface and the
#  Fortran library via the PGPLOT link script (if found).
      pgplot) args="${args} -last_pgplot `\`find pgplot_link\``"
              f77='y';;

#  If using own graphics which conform to the requirements of the current 
#  version of AST, do not produce any arguments.
      current) :;;

#  If using own graphics which conform to the requirements of version 3.2 
#  of AST, produce arguments which link in dummy implementations of any 
#  functions which are required by the current version of AST but which were 
#  not required by version 3.2.
      v3.2) :;;

#  If using own graphics which conform to the requirements of version 2.0
#  of AST, produce arguments which link in dummy implementations of any 
#  functions which are required by the current version of AST but which were 
#  not required by version 2.0.
      v2.0) args="${args} -last_grf_3.2";;

#  Default graphics (none) requires linking with all the default (null) AST 
#  "grf" modules.
      *) args="${args} -last_grf_2.0 -last_grf_3.2";;
      esac

#  Make a second pass through the AST library.
#  -------------------------------------------
#  This library is a link to the main AST library and results in a second
#  pass to resolve any backward references generated by the other modules
#  used above. A different library name must be used to avoid the two passes
#  being merged into one (either below, or by other link scripts).
      args="${args} -last_pass2"

#  Generate arguments for linking the error reporting system.
#  ----------------------------------------------------------
      case "${err}" in

#  If using EMS, link with the AST EMS interface and the EMS library via the
#  link script (if found).
      ems) args="${args} -last_ems `\`find ems_link\``"
           f77='y';;

#  If using own error reporting, do not produce any arguments.
      my) :;;

#  Default error reporting requires linking with the default AST "err" module.
      *) args="${args} -last_err";;
      esac

#  Link with the maths library.
#  ----------------------------
      args="${args} -lm"

#  Resolve Fortran 77 references.
#  ------------------------------
#  If libraries written in Fortran are being linked against, then include
#  additional libaries needed to resolve the references these will produce
#  (in the event that the main program is not Fortran).
      if test "${f77}" = 'y'; then args="${args} ${flibs}"; fi

#  Pass the resulting argument list through an awk script which eliminates
#  all except the last reference to each library.
      echo "${args}" \
           | awk 'BEGIN{RS=" ";FS="\n"}
                  {if($1)f[i++]=$1}
                  END{for(;i--;)if(!w[f[i]]++)l=f[i]" "l;print l}'

#  End of script.
