source: trunk/coin_fortran.m4

Last change on this file was 3875, checked in by stefan, 14 months ago

add macros to check for various name mangling schemes in link check; add new macro to check for lapack

  • added AC_COIN_TRY_LINK to check whether a function exists in a library, thereby trying different name mangling scheme and recording the successful one
  • added AC_COIN_DEFINENAMEMANGLING to define XYZ_FUNC/XYZ_FUNC_ macros depending on given name mangling scheme
  • add AC_COIN_CHK_LAPACK to check for Lapack and define COIN_LAPACK_FUNC(_) according to found name mangling scheme
  • do all this without requiring or assuming Fortran
File size: 20.0 KB
Line 
1
2###########################################################################
3#                  Fortran Utility Macros                                 #
4###########################################################################
5# Macros that help with building Fortran code or simply linking to Fortran
6# code.
7###########################################################################
8
9# Due to the way AC_REQUIRE is implemented (REQUIREd macros are expanded
10# before the body of the topmost unexpanded macro) it's impossible to use
11# any variation of nested macro calls to invoke COIN_PROG_F77 to check
12# for a compiler, then conditionally invoke the macros required for a fully
13# functional environment based on the value of the shell variable F77.  If your
14# configuration requires that you handle both cases (working compiler and
15# no compiler) you need to invoke COIN_PROG_F77 from configure.ac, then test
16# the value of the variable F77 and invoke the appropriate follow-on macro, as
17#
18#   AC_COIN_PROG_F77
19#   if test "$F77" != "unavailable" ; then
20#     AC_COIN_F77_SETUP
21#   else
22#     AC_COIN_F77_WRAPPERS
23#   fi
24#
25# If all you want to do is link to Fortran libraries from C/C++ code
26# and you have no intention of compiling Fortran code, just invoke
27# AC_COIN_F77_WRAPPERS.
28#
29# If a working Fortran compiler is necessary and you would like configuration
30# to abort if a working compiler can't be found, try
31#
32#   AC_COIN_PROG_F77
33#   if test "$F77" != "unavailable" ; then
34#     AC_COIN_F77_SETUP
35#   else
36#     AC_MSG_ERROR([cannot find a working Fortran compiler!])
37#   fi
38
39###########################################################################
40#                   COIN_PROG_F77                                         #
41###########################################################################
42
43# COIN_PROG_F77 will find a Fortran compiler, or set F77 to unavailable. Alone,
44# this is not sufficient to actually build Fortran code. For that, use
45# COIN_F77_SETUP.
46
47# Unlike C/C++, automake doesn't mess with AC_PROG_F77.
48
49AC_DEFUN_ONCE([AC_COIN_PROG_F77],
50[
51  # AC_MSG_NOTICE([In COIN_PROG_F77])
52  AC_REQUIRE([AC_COIN_ENABLE_MSVC])
53
54# If enable-msvc, then test only for Intel (on Windows) Fortran compiler
55
56  if test $enable_msvc = yes ; then
57    comps="ifort"
58  else
59    # TODO old buildtools was doing some $build specific logic here, do we still
60    # need this?
61    comps="gfortran ifort g95 fort77 f77 f95 f90 g77 pgf90 pgf77 ifc frt af77 xlf_r fl32"
62  fi
63  AC_PROG_F77([$comps])
64
65# Allow for the possibility that there is no Fortran compiler on the system.
66
67  if test "${F77:-unavailable}" = unavailable ; then
68    F77=unavailable
69    AC_MSG_NOTICE([No Fortran compiler available.])
70  fi
71  # AC_MSG_NOTICE([Leaving COIN_PROG_F77])
72])
73
74
75###########################################################################
76#                   COIN_PROG_FC                                          #
77###########################################################################
78
79AC_DEFUN_ONCE([AC_COIN_PROG_FC],
80[
81  AC_REQUIRE([AC_COIN_ENABLE_MSVC])
82
83  # TODO
84  AC_MSG_ERROR(["AC_COIN_PROG_FC not implemented yet"])
85])
86
87
88###########################################################################
89#                   COIN_F77_SETUP                                        #
90###########################################################################
91
92# Do the necessary work to make it possible to compile Fortran object files
93# and invoke Fortran functions from C/C++ code. Requires a working Fortran
94# compiler, otherwise configure will fail. See comments at top of file.
95#
96# If all you want to do is link to Fortran code, try AC_COIN_F77_WRAPPERS.
97
98AC_DEFUN([AC_COIN_F77_SETUP],
99[
100  # AC_MSG_NOTICE([In COIN_F77_SETUP])
101
102# F77_WRAPPERS will trigger the necessary F77 setup macros (F77_MAIN,
103# F77_LIBRARY_LDFLAGS, etc.)
104
105  AC_F77_WRAPPERS
106  AC_PROG_F77_C_O
107  if test $ac_cv_prog_f77_c_o = no ; then
108    F77="$am_aux_dir/compile $F77"
109  fi
110  # AC_MSG_NOTICE([Leaving COIN_F77_SETUP])
111])
112
113# COIN_F77_WRAPPERS (lib,func)
114# -------------------------------------------------------------------------
115# Determine C/C++ name mangling without a Fortran compiler, to allow linking
116# with Fortran libraries on systems where there's no working Fortran compiler.
117#  lib ($1) a library we're attempting to link to
118#  func ($2) a function within that library
119
120# Ideally, the function name will contain an embedded underscore but the
121# macro doesn't require that because typical COIN use cases (BLAS, LAPACK)
122# don't have any names with embedded underscores. The default is `no extra
123# underscore' (because this is tested first and will succeed if the name
124# has no embedded underscore).
125
126# The possibilities amount to
127# { lower / upper case } X (no) trailing underscore X (no) extra underscore
128# where the extra underscore is applied to name with an embedded underscore.
129
130# ac_cv_f77_mangling is documented, so should be fairly safe to use.
131
132# The trick here is to avoid any of the documented F77_ macros, as they all
133# eventually REQUIRE a macro that requires a functioning Fortran compiler.
134
135# -------------------------------------------------------------------------
136
137AC_DEFUN([AC_COIN_F77_WRAPPERS],
138[
139  # AC_MSG_NOTICE([In COIN_F77_WRAPPERS])
140  AC_CACHE_CHECK(
141    [Fortran name mangling scheme],
142    [ac_cv_f77_mangling],
143    [ac_save_LIBS=$LIBS
144     LIBS="-l$1"
145     for ac_case in "lower case" "upper case" ; do
146       for ac_trail in "underscore" "no underscore" ; do
147         for ac_extra in "no extra underscore" "extra underscore" ; do
148           ac_cv_f77_mangling="${ac_case}, ${ac_trail}, ${ac_extra}"
149           # AC_MSG_NOTICE([Attempting link for $ac_cv_f77_mangling])
150           case $ac_case in
151             "lower case")
152               ac_name=m4_tolower($2)
153               ;;
154             "upper case")
155               ac_name=m4_toupper($2)
156               ;;
157           esac
158           if test "$ac_trail" = underscore ; then
159             ac_name=${ac_name}_
160           fi
161           # AC_MSG_CHECKING([$2 -> $ac_name])
162           AC_LINK_IFELSE(
163             [AC_LANG_PROGRAM(
164                [#ifdef __cplusplus
165                  extern "C"
166                 #endif
167                 void $ac_name();],
168                [$ac_name()])],
169             [ac_result=success],
170             [ac_result=failure])
171           # AC_MSG_RESULT([$result])
172           if test $ac_result = success ; then
173             break 3
174           fi
175         done
176       done
177     done
178     if test "$ac_result" = "failure" ; then
179       ac_cv_f77_mangling=unknown
180       AC_MSG_WARN([Unable to determine correct Fortran name mangling scheme])
181     fi
182     LIBS=$ac_save_LIBS])
183
184# Invoke the second-level internal autoconf macro _AC_FC_WRAPPERS to give the
185# functionality of AC_F77_WRAPPERS.
186
187  if test "$ac_cv_f77_mangling" != unknown ; then
188    AC_LANG_PUSH([Fortran 77])
189    _AC_FC_WRAPPERS
190    AC_LANG_POP([Fortran 77])
191  fi
192  # AC_MSG_NOTICE([Done COIN_F77_WRAPPERS])
193])
194
195
196# COIN_F77_FUNC(ftn_name,c_name)
197# -------------------------------------------------------------------------
198# Sets the shell variable c_name to the appropriate mangle of the Fortran
199# function ftn_name.
200#
201# Duplicates the direct result of F77_FUNC by invoking the second level
202# internal autoconf macro. This sidesteps a REQUIRE of a macro chain that
203# requires a functioning Fortran compiler. This macro requires that
204# ac_cv_f77_mangling be defined, either by invoking F77_WRAPPERS (if a Fortran
205# compiler exists) or COIN_F77_WRAPPERS (if a Fortran compiler does not exist).
206# -------------------------------------------------------------------------
207
208AC_DEFUN([AC_COIN_F77_FUNC],
209[ AC_LANG_PUSH(Fortran 77)
210  _AC_FC_FUNC($1,$2)
211  AC_LANG_POP(Fortran 77)
212])
213
214
215# COIN_TRY_FLINK(fname,[action if success],[action if failure])
216
217# Auxilliary macro to test if a Fortran function fname can be linked, given
218# the current settings of LIBS.  We determine from the context (ac_ext, the
219# source file extension), what the currently active programming language is,
220# and cast the name accordingly.  The first argument is the name of the
221# function/subroutine, the second argument is the actions taken when the
222# test works, and the third argument is the actions taken if the test fails.
223# Note that we're using COIN_F77_FUNC rather than F77_FUNC to avoid triggering
224# macros that require a working Fortran compiler.
225
226AC_DEFUN([AC_COIN_TRY_FLINK],
227[ # AC_MSG_NOTICE([In COIN_TRY_FLINK])
228  case $ac_ext in
229    f)
230      AC_TRY_LINK(,[      call $1],[flink_try=yes],[flink_try=no])
231      ;;
232    c)
233      coin_need_flibs=no
234      flink_try=no
235      AC_COIN_F77_FUNC($1,cfunc$1)
236      # AC_MSG_NOTICE([COIN_TRY_FLINK: $1 -> $cfunc$1])
237      AC_LINK_IFELSE(
238        [AC_LANG_PROGRAM([void $cfunc$1();],[$cfunc$1()])],
239        [flink_try=yes],
240        [if test x"$FLIBS" != x ; then
241           flink_save_libs="$LIBS"
242           LIBS="$LIBS $FLIBS"
243           AC_LINK_IFELSE(
244             [AC_LANG_PROGRAM([void $cfunc$1();],[$cfunc$1()])],
245             [coin_need_flibs=yes
246              flink_try=yes]
247           )
248           LIBS="$flink_save_libs"
249         fi
250        ]
251      )
252      ;;
253    cc|cpp)
254      coin_need_flibs=no
255      flink_try=no
256      AC_COIN_F77_FUNC($1,cfunc$1)
257      AC_LINK_IFELSE(
258        [AC_LANG_PROGRAM([extern "C" {void $cfunc$1();}],[$cfunc$1()])],
259        [flink_try=yes],
260        [if test x"$FLIBS" != x ; then
261           flink_save_libs="$LIBS"
262           LIBS="$LIBS $FLIBS"
263           AC_LINK_IFELSE(
264             [AC_LANG_PROGRAM([extern "C" {void $cfunc$1();}],[$cfunc$1()])],
265             [coin_need_flibs=yes
266              flink_try=yes]
267           )
268           LIBS="$flink_save_libs"
269         fi
270        ]
271      )
272      ;;
273  esac
274  if test $flink_try = yes ; then
275    $2
276  else
277    $3
278  fi
279  # AC_MSG_NOTICE([Done COIN_TRY_FLINK])
280]) # AC_COIN_TRY_FLINK
281
282
283###########################################################################
284#                       COIN_CHK_PKG_FLINK                                #
285###########################################################################
286
287# This is a helper macro, common code for checking if a library can be linked.
288#   COIN_CHK_PKG_FLINK(varname,func,extra_libs)
289# If func can be linked with extra_libs, varname is set to extra_libs,
290# possibly augmented with $FLIBS if these are required. If func cannot be
291# linked, varname is set to the null string.
292
293AC_DEFUN([AC_COIN_CHK_PKG_FLINK],
294[
295  coin_save_LIBS="$LIBS"
296  LIBS="$3 $LIBS"
297  AC_COIN_TRY_FLINK([$2],
298    [if test $coin_need_flibs = no ; then
299       $1="$3"
300     else
301       $1="$3 $FLIBS"
302     fi
303     AC_MSG_RESULT([yes: $[]$1])],
304    [$1=
305     AC_MSG_RESULT([no])])
306  LIBS="$coin_save_LIBS"
307])
308
309###########################################################################
310#                         COIN_CHK_BLAS                                   #
311###########################################################################
312
313# COIN_CHK_BLAS([client packages],[nolinkcheck])
314
315# This macro checks for a BLAS library and adds the information necessary to
316# use it to the _LFLAGS, _CFLAGS, and _PCFILES variables of the client packages
317# passed as a space-separated list in parameter $1. These correspond to
318# Libs.private, Cflags.private, and Requires.private, respectively, in a .pc
319# file.
320
321# The algorithm first invokes FIND_PRIM_PKG. The parameters --with-blas,
322# --with-blas-lflags, and --with-blas-cflags are interpreted there. If nothing
323# is found, default locations are checked.
324
325# When checking default locations, the macro uses a link check because it's
326# really the only way to decide if a guess is correct. But a link check is
327# always a good idea just in case FLIBS (Fortran intrinsic & runtime libraries)
328# is also necessary. You can suppress the link check for a library spec given
329# on the command line or obtained via a .pc file by adding `nolinkcheck' as $2.
330
331AC_DEFUN([AC_COIN_CHK_BLAS],
332[
333  AC_REQUIRE([AC_COIN_PROG_F77])
334
335  AC_MSG_CHECKING([for package BLAS])
336
337# Make sure the necessary variables exist for each client package.
338
339  m4_foreach_w([myvar],[$1],
340    [AC_SUBST(m4_toupper(myvar)_LFLAGS)
341     AC_SUBST(m4_toupper(myvar)_CFLAGS)
342     AC_SUBST(m4_toupper(myvar)_PCFILES)
343    ])
344
345# Set up command line arguments with DEF_PRIM_ARGS and give FIND_PRIM_PKG
346# a chance, just in case blas.pc exists. The result (coin_has_blas) will
347# be one of yes (either the user specified something or pkgconfig found
348# something), no (user specified nothing and pkgconfig found nothing) or
349# skipping (user said do not use). We'll also have variables blas_lflags,
350# blas_cflags, blas_data, and blas_pcfiles.
351
352  AC_COIN_DEF_PRIM_ARGS([blas],yes,yes,yes,no)
353  AC_COIN_FIND_PRIM_PKG([blas])
354
355# If FIND_PRIM_PKG found something and the user wants a link check, do it. For
356# a successful link check, update blas_libs just in case FLIBS was added.
357
358  if test "$coin_has_blas" = yes ; then
359    m4_if([$2],[nolinkcheck],[:],
360      [use_blas=
361       AC_COIN_CHK_PKG_FLINK([use_blas],[daxpy],[$blas_lflags])
362       if test -n "$use_blas" ; then
363         blas_lflags=$use_blas
364       else
365         AC_MSG_WARN([BLAS failed to link with "$blas_lflags"])
366       fi])
367
368# If FIND_PRIM_PKG didn't find anything, try a few guesses.  Try some
369# specialised checks based on the host system type first.  If none of them
370# are applicable, or the applicable one fails, try the generic -lblas.
371
372  elif test "$coin_has_blas" = no ; then
373    AC_MSG_RESULT([nothing yet])
374    case $build in
375      *-sgi-*)
376        AC_MSG_CHECKING([for BLAS in -lcomplib.sgimath])
377        AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],[-lcomplib.sgimath])
378        ;;
379
380      *-*-solaris*)
381        # Ideally, we'd use -library=sunperf, but it's an imperfect world.
382        # Studio cc doesn't recognise -library, it wants -xlic_lib. Studio 12
383        # CC doesn't recognise -xlic_lib. Libtool doesn't like -xlic_lib
384        # anyway. Sun claims that CC and cc will understand -library in Studio
385        # 13. The main extra function of -xlic_lib and -library is to arrange
386        # for the Fortran run-time libraries to be linked for C++ and C. We
387        # can arrange that explicitly.
388        AC_MSG_CHECKING([for BLAS in -lsunperf])
389        AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],[-lsunperf])
390        ;;
391       
392      *-cygwin* | *-mingw*)
393        case "$CC" in
394          clang* ) ;;
395          cl* | */cl* | CL* | */CL* | icl* | */icl* | ICL* | */ICL*)
396            AC_MSG_CHECKING([for BLAS in MKL (32bit)])
397            AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],
398              [mkl_intel_c.lib mkl_sequential.lib mkl_core.lib])
399            if test -z "$blas_lflags" ; then
400              AC_MSG_CHECKING([for BLAS in MKL (64bit)])
401              AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],
402                [mkl_intel_lp64.lib mkl_sequential.lib mkl_core.lib])
403            fi
404            ;;
405        esac
406        ;;
407       
408       *-darwin*)
409        AC_MSG_CHECKING([for BLAS in Veclib])
410        AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],[-framework Accelerate])
411        ;;
412    esac
413    if test -z "$blas_lflags" ; then
414      AC_MSG_CHECKING([for BLAS in -lblas])
415      AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],[-lblas])
416    fi
417    if test -n "$blas_lflags" ; then
418      coin_has_blas=yes
419    fi
420  fi
421
422# Done. Time to set some variables. Create an automake conditional
423# COIN_HAS_BLAS.
424
425  AM_CONDITIONAL(m4_toupper(COIN_HAS_BLAS),[test $coin_has_blas = yes])
426
427# If we've located the package, define preprocessor symbol COIN_HAS_BLAS
428# and augment the necessary variables for the client packages.
429
430  if test $coin_has_blas = yes ; then
431    AC_DEFINE(m4_toupper(COIN_HAS_BLAS),[1],
432      [Define to 1 if BLAS is available.])
433    m4_foreach_w([myvar],[$1],
434      [m4_toupper(myvar)_PCFILES="$blas_pcfiles $m4_toupper(myvar)_PCFILES"
435       m4_toupper(myvar)_LFLAGS="$blas_lflags $m4_toupper(myvar)_LFLAGS"
436       m4_toupper(myvar)_CFLAGS="$blas_cflags $m4_toupper(myvar)_CFLAGS"
437      ])
438  else
439    AC_MSG_RESULT([$coin_has_blas])
440  fi
441
442]) # AC_COIN_CHK_BLAS
443
444
445###########################################################################
446#                       COIN_CHK_LAPACK                                   #
447###########################################################################
448
449# COIN_CHK_LAPACK([client packages],[nolinkcheck])
450
451# This macro checks for a LAPACK library and adds the information necessary to
452# use it to the _LFLAGS, _CFLAGS, and _PCFILES variables of the client packages
453# passed as a space-separated list in parameter $1. These correspond to
454# Libs.private, Cflags.private, and Requires.private, respectively, in a .pc
455# file.
456
457# The algorithm first invokes FIND_PRIM_PKG. The parameters --with-lapack,
458# --with-lapack-lflags, and --with-lapack-cflags are interpreted there. If
459# nothing is found, default locations are checked.
460
461# When checking default locations, the macro uses a link check because it's
462# really the only way to decide if a guess is correct. But a link check is
463# always a good idea just in case FLIBS (Fortran intrinsic & runtime libraries)
464# is also necessary. You can suppress the link check for a library spec given
465# on the command line or obtained via a .pc file by adding `nolinkcheck' as $2.
466
467AC_DEFUN([AC_COIN_CHK_LAPACK_OLD],
468[
469  AC_REQUIRE([AC_COIN_PROG_F77])
470
471  AC_MSG_CHECKING([for package LAPACK])
472
473# Make sure the necessary variables exist for each client package.
474
475  m4_foreach_w([myvar],[$1],
476    [AC_SUBST(m4_toupper(myvar)_LIBS)
477     AC_SUBST(m4_toupper(myvar)_CFLAGS)
478     AC_SUBST(m4_toupper(myvar)_PCFILES)
479    ])
480
481# Set up command line arguments with DEF_PRIM_ARGS and give FIND_PRIM_PKG
482# a chance, just in case lapack.pc exists. The result (coin_has_lapack)
483# will be one of yes (either the user specified something or pkgconfig
484# found something), no (user specified nothing and pkgconfig found nothing)
485# or skipping (user said do not use). We'll also have variables lapack_lflags,
486# lapack_cflags, lapack_data, and lapack_pcfiles.
487
488  AC_COIN_DEF_PRIM_ARGS([lapack],yes,yes,yes,no)
489  AC_COIN_FIND_PRIM_PKG([lapack])
490
491# If FIND_PRIM_PKG found something and the user wants a link check, do it. For
492# a successful link check, update lapack_lflags just in case FLIBS was added.
493
494  if test "$coin_has_lapack" = yes ; then
495    m4_if([$2],[nolinkcheck],[:],
496      [use_lapack=
497       AC_COIN_CHK_PKG_FLINK([use_lapack],[daxpy],[$lapack_lflags])
498       if test -n "$use_lapack" ; then
499         lapack_lflags=$use_lapack
500       else
501         AC_MSG_WARN([LAPACK failed to link with "$lapack_lflags"])
502       fi])
503
504# If FIND_PRIM_PKG didn't find anything, try a few guesses. First, try some
505# specialised checks based on the host system type. If none of them are
506# applicable, or the applicable one fails, try the generic -llapack.
507
508  elif test "$coin_has_lapack" = no ; then
509    AC_MSG_RESULT([nothing yet])
510    case $build in
511      *-sgi-*)
512        AC_MSG_CHECKING([for LAPACK in -lcomplib.sgimath])
513        AC_COIN_CHK_PKG_FLINK([lapack_lflags],[dsyev],[-lcomplib.sgimath])
514        ;;
515
516      *-*-solaris*)
517        # See comments in COIN_CHK_PKG_BLAS.
518        AC_MSG_CHECKING([for LAPACK in -lsunperf])
519        AC_COIN_CHK_PKG_FLINK([lapack_lflags],[dsyev],[-lsunperf])
520        ;;
521
522        # On cygwin, do this check only if doscompile is disabled. The
523        # prebuilt library will want to link with cygwin, hence won't run
524        # standalone in DOS.
525
526    esac
527    if test -z "$lapack_lflags" ; then
528      AC_MSG_CHECKING([for LAPACK in -llapack])
529      AC_COIN_CHK_PKG_FLINK([lapack_lflags],[dsyev],[-llapack])
530    fi
531    if test -n "$lapack_lflags" ; then
532      coin_has_lapack=yes
533    fi
534  fi
535
536# Done. Time to set some variables. Create an automake conditional
537# COIN_HAS_LAPACK.
538
539  AM_CONDITIONAL(m4_toupper(COIN_HAS_LAPACK),[test $coin_has_lapack = yes])
540
541# If we've located the package, define preprocessor symbol COIN_HAS_LAPACK
542# and augment the necessary variables for the client packages.
543
544  if test $coin_has_lapack = yes ; then
545    AC_DEFINE(m4_toupper(COIN_HAS_LAPACK),[1],
546      [Define to 1 if the LAPACK package is available])
547    m4_foreach_w([myvar],[$1],
548      [m4_toupper(myvar)_PCFILES="$lapack_pcfiles $m4_toupper(myvar)_PCFILES"
549       m4_toupper(myvar)_LFLAGS="$lapack_lflags $m4_toupper(myvar)_LFLAGS"
550       m4_toupper(myvar)_CFLAGS="$lapack_cflags $m4_toupper(myvar)_CFLAGS"
551      ])
552  else
553    AC_MSG_RESULT([$coin_has_lapack])
554  fi
555
556]) # AC_COIN_CHK_LAPACK
557
Note: See TracBrowser for help on using the repository browser.