
#  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.

#  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'': Ignored. Provided for backward compatibility only.
#
#     - ``-fsla'': Ignored. Provided for backward compatibility only.
#
#     - ``-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.
#
#     - ``-drama'': Requests that the program be linked so that error messages
#     produced by the AST library are delivered via the DRAMA Ers (Error
#     Reporting Service) library. By default, error messages are simply
#     written to standard error.
#
#     - ``-grf'': Requests that no arguments be generated to specify which
#     2D 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 2D 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 2D graphics interface required by
#     V3.2 of AST.
#
#     - ``-grf_v5.6'': Indicates that you want to link with your own
#     graphics module which implements the 2D graphics interface required by
#     V5.6 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 2D interface used by AST V2.0. It
#     is equivalent to the ``-grf_v2.0'' switch.
#
#     - ``-pgp'': Requests that the program be linked so that 2D
#     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 2D 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 2D
#     graphical output from the AST library is displayed via
#     the standard (or ``native'') version of the PGPLOT graphics
#     package. By default, no 2D 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.
#
#     - ``-grf3d'': Requests that no arguments be generated to specify which
#     3D 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 3D graphics system yourself and wish to provide your own arguments
#     for linking with it.
#
#     - ``-pgp3d'': Requests that the program be linked so that 3D
#     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 3D 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.
#
#     - ``-pgplot3d'': Requests that the program be linked so that 3D
#     graphical output from the AST library is displayed via
#     the standard (or ``native'') version of the PGPLOT graphics
#     package. By default, no 3D 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.

#  ERFA & PAL:
#     The AST distribution includes bundled copies of the ERFA and PAL
#     libraries. These will be used for fundamental positional astronomy
#     calculations unless the "--with-external_pal" option was used when
#     AST was configured. If "--with-external_pal" is used, this script
#     will include "-lpal" in the returned list of linking options, and
#     the user should then ensure that external copies of the PAL and
#     ERFA libraries are available (ERFA functions are used within PAL).

#  CMINPACK:
#     The AST distribution includes a bundled copy of the CMINPACK
#     library. This will be used for various minimisation processes
#     unless the "--with-external_cminpack" option was used when AST
#     was configured. If "--with-external_cminpack" is used, this script
#     will include "-lcminpack" in the returned list of linking options,
#     and the user should then ensure that an external copy of the
#     CMINPACK library is available.

#  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 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 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) 1997-2006 Council for the Central Laboratory of the Research Councils
#     Copyright (C) 2007-2008 Science & Technology Facilities Council.
#     All Rights Reserved.

#  Authors:
#     RFWS: R.F. Warren-Smith (STARLINK)
#     DSB: David S. Berry (STARLINK)
#     TIMJ: Tim Jenness (JAC, Hawaii)
#     {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.
#     24-AUG-2004 (DSB):
#        Removed f77='y' from -ems case.
#     21-APR-2005 (DSB):
#        Added "-fsla" option.
#     16-JUN-2006 (DSB):
#        Ignore "-fsla" and "-clsa" options, and always use PAL.
#     26-JUN-2007 (DSB):
#        Added "-grf3d", "-pgplot3d" and "-pgp3d" flags.
#     13-NOV-2008 (TIMJ):
#        Add -drama option for DRAMA Ers support.
#     3-MAR-2011 (DSB):
#        Added grf 5.6 options.
#     13-OCT-2021 (DSB):
#        Added support for link with an external cminpack library.
#     {enter_further_changes_here}

#  Bugs:
#     {note_any_bugs_here}

#--

#  This line is edited during configuration 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 AST library (or the C
#  program) calls.  The value here is worked out by the autoconf macro
#  AC_FC_LIBRARY_LDFLAGS.
      flibs=' -L/opt/local/lib -L/opt/local/lib/gcc15/gcc/aarch64-apple-darwin22/15.2.0 -L/opt/local/lib/gcc15/gcc/aarch64-apple-darwin22/15.2.0/../../.. -lemutls_w -lheapt_w -lgfortran -lquadmath'

#  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=''
      grf3d=''
      sla=''
      f77=''

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

#  -csla - Previously used to request C version of SLALIB. Now ignored.
         -csla)
#            sla='c'
            shift;;

#  -fsla - Previously used to request Fortran version of SLALIB. Now ignored.
         -fsla)
#            sla='f'
            shift;;

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

#  -drama - Requests error reporting through DRAMA Ers.
         -drama)
            err='drama'
            shift;;

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

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

#  -mygrf - Requests no 2D 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 2D 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 2D graphics, except for null implementations of
#  functions aded to the grf interface after AST V3.2.
         -grf_v3.2)
            grf='v3.2'
            shift;;

#  -grf_v5.6 - Requests no 2D graphics, except for null implementations of
#  functions aded to the grf interface after AST V5.6.
         -grf_v5.6)
            grf='v5.6'
            shift;;

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

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

#  -grf3d - Requests no 3D graphics.
         -grf3d)
            grf3d='current'
            shift;;

#  -pgp3d - Requests 3D graphical output through Starlink PGPLOT.
         -pgp3d)
            grf3d='pgp'
            shift;;

#  -pgplot3d - Requests 3D graphical output through native PGPLOT.
         -pgplot3d)
            grf3d='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.
      args='-last '

#  Generate arguments for linking PAL.
#  -----------------------------------

      case "0" in

#  If we configured --with-external_pal include a link option to pick up
#  an external PAL library.
      1) args="${args} -lpal";;

#  Otherwise, use the internal PAL & ERFA libraries.
      *) args="${args} -last_pal";;

      esac

#  Generate arguments for linking CMINPACK.
#  -----------------------------------

      case "0" in

#  If we configured --with-external_cminpack include a link option to pick up
#  an external CMINPACK library.
      1) args="${args} -lcminpack";;

#  Otherwise, use the internal CMINPACK library.
      *) args="${args} -last_cminpack";;

      esac

#  Generate arguments for linking the 2D 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 5.6
#  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 5.6.
      v5.6) :;;

#  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) args="${args} -last_grf_5.6";;

#  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 -last_grf_5.6";;

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


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

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

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

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

#  Default graphics (none) requires linking with all the default (null) AST
#  "grf3d" modules.
      *) args="${args} -last_grf3d";;
      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\``";;

#  If using DRAMA, link with the AST DRAMA interface and the DRAMA Ers library
#  via the link script (if found).
      drama) args="${args} -last_drama -lers";;

#  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"

#  Link with the yaml library.
#  ----------------------------
      if test "0" = '1'; then args="${args} -lyaml"; fi

#  Link with the starmem library, if available.
#  --------------------------------------------
      args="${args} `\`find starmem_link\``"

#  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.
