source: trunk/coin_fortran.m4 @ 3850

Last change on this file since 3850 was 3848, checked in by lou, 13 months ago

Introduce CHK_HERE, {_CFLAGS,_LFLAGS}_NOPC for use in .pc files and remove
_PUB variables, rename a few variables, and generally clean up accumulation
of compiler and linker flags.

File size: 19.2 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# Set up command line arguments with DEF_PRIM_ARGS and give FIND_PRIM_PKG
345# a chance, just in case blas.pc exists. The result (coin_has_blas) will
346# be one of yes (either the user specified something or pkgconfig found
347# something), no (user specified nothing and pkgconfig found nothing) or
348# skipping (user said do not use). We'll also have variables blas_lflags,
349# blas_cflags, blas_data, and blas_pcfiles.
350
351  AC_COIN_DEF_PRIM_ARGS([blas],yes,yes,yes,no)
352  AC_COIN_FIND_PRIM_PKG([blas])
353
354# If FIND_PRIM_PKG found something and the user wants a link check, do it. For
355# a successful link check, update blas_libs just in case FLIBS was added.
356
357  if test "$coin_has_blas" = yes ; then
358    m4_if([$2],[nolinkcheck],[:],
359      [use_blas=
360       AC_COIN_CHK_PKG_FLINK([use_blas],[daxpy],[$blas_lflags])
361       if test -n "$use_blas" ; then
362         blas_lflags=$use_blas
363       else
364         AC_MSG_WARN([BLAS failed to link with "$blas_lflags"])
365       fi])
366
367# If FIND_PRIM_PKG didn't find anything, try a few guesses.  Try some
368# specialised checks based on the host system type first.  If none of them
369# are applicable, or the applicable one fails, try the generic -lblas.
370
371  elif test "$coin_has_blas" = no ; then
372    AC_MSG_RESULT([nothing yet])
373    case $build in
374      *-sgi-*)
375        AC_MSG_CHECKING([for BLAS in -lcomplib.sgimath])
376        AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],[-lcomplib.sgimath])
377        ;;
378
379      *-*-solaris*)
380        # Ideally, we'd use -library=sunperf, but it's an imperfect world.
381        # Studio cc doesn't recognise -library, it wants -xlic_lib. Studio 12
382        # CC doesn't recognise -xlic_lib. Libtool doesn't like -xlic_lib
383        # anyway. Sun claims that CC and cc will understand -library in Studio
384        # 13. The main extra function of -xlic_lib and -library is to arrange
385        # for the Fortran run-time libraries to be linked for C++ and C. We
386        # can arrange that explicitly.
387        AC_MSG_CHECKING([for BLAS in -lsunperf])
388        AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],[-lsunperf])
389        ;;
390       
391      *-cygwin* | *-mingw*)
392        case "$CC" in
393          clang* ) ;;
394          cl* | */cl* | CL* | */CL* | icl* | */icl* | ICL* | */ICL*)
395            AC_MSG_CHECKING([for BLAS in MKL (32bit)])
396            AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],
397              [mkl_intel_c.lib mkl_sequential.lib mkl_core.lib])
398            if test -z "$blas_lflags" ; then
399              AC_MSG_CHECKING([for BLAS in MKL (64bit)])
400              AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],
401                [mkl_intel_lp64.lib mkl_sequential.lib mkl_core.lib])
402            fi
403            ;;
404        esac
405        ;;
406       
407       *-darwin*)
408        AC_MSG_CHECKING([for BLAS in Veclib])
409        AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],[-framework Accelerate])
410        ;;
411    esac
412    if test -z "$blas_lflags" ; then
413      AC_MSG_CHECKING([for BLAS in -lblas])
414      AC_COIN_CHK_PKG_FLINK([blas_lflags],[daxpy],[-lblas])
415    fi
416    if test -n "$blas_lflags" ; then
417      coin_has_blas=yes
418    fi
419  fi
420
421# Done. Time to set some variables. Create an automake conditional
422# COIN_HAS_BLAS.
423
424  AM_CONDITIONAL(m4_toupper(COIN_HAS_BLAS),[test $coin_has_blas = yes])
425
426# If we've located the package, define preprocessor symbol COIN_HAS_BLAS
427# and augment the necessary variables for the client packages.
428
429  if test $coin_has_blas = yes ; then
430    AC_DEFINE(m4_toupper(COIN_HAS_BLAS),[1],
431      [Define to 1 if BLAS is available.])
432    m4_foreach_w([myvar],[$1],
433      [m4_toupper(myvar)_PCFILES="$blas_pcfiles $m4_toupper(myvar)_PCFILES"
434       m4_toupper(myvar)_LFLAGS="$blas_lflags $m4_toupper(myvar)_LFLAGS"
435       m4_toupper(myvar)_CFLAGS="$blas_cflags $m4_toupper(myvar)_CFLAGS"])
436  else
437    AC_MSG_RESULT([$coin_has_blas])
438  fi
439
440]) # AC_COIN_CHK_BLAS
441
442
443###########################################################################
444#                       COIN_CHK_LAPACK                                   #
445###########################################################################
446
447# COIN_CHK_LAPACK([client packages],[nolinkcheck])
448
449# This macro checks for a LAPACK library and adds the information necessary to
450# use it to the _LFLAGS, _CFLAGS, and _PCFILES variables of the client packages
451# passed as a space-separated list in parameter $1. These correspond to
452# Libs.private, Cflags.private, and Requires.private, respectively, in a .pc
453# file.
454
455# The algorithm first invokes FIND_PRIM_PKG. The parameters --with-lapack,
456# --with-lapack-lflags, and --with-lapack-cflags are interpreted there. If
457# nothing is found, default locations are checked.
458
459# When checking default locations, the macro uses a link check because it's
460# really the only way to decide if a guess is correct. But a link check is
461# always a good idea just in case FLIBS (Fortran intrinsic & runtime libraries)
462# is also necessary. You can suppress the link check for a library spec given
463# on the command line or obtained via a .pc file by adding `nolinkcheck' as $2.
464
465AC_DEFUN([AC_COIN_CHK_LAPACK],
466[
467  AC_REQUIRE([AC_COIN_PROG_F77])
468
469  AC_MSG_CHECKING([for package LAPACK])
470
471# Make sure the necessary variables exist for each client package.
472
473  m4_foreach_w([myvar],[$1],
474    [AC_SUBST(m4_toupper(myvar)_LIBS)
475     AC_SUBST(m4_toupper(myvar)_CFLAGS)
476     AC_SUBST(m4_toupper(myvar)_PCFILES)])
477
478# Set up command line arguments with DEF_PRIM_ARGS and give FIND_PRIM_PKG
479# a chance, just in case lapack.pc exists. The result (coin_has_lapack)
480# will be one of yes (either the user specified something or pkgconfig
481# found something), no (user specified nothing and pkgconfig found nothing)
482# or skipping (user said do not use). We'll also have variables lapack_lflags,
483# lapack_cflags, lapack_data, and lapack_pcfiles.
484
485  AC_COIN_DEF_PRIM_ARGS([lapack],yes,yes,yes,no)
486  AC_COIN_FIND_PRIM_PKG([lapack])
487
488# If FIND_PRIM_PKG found something and the user wants a link check, do it. For
489# a successful link check, update lapack_lflags just in case FLIBS was added.
490
491  if test "$coin_has_lapack" = yes ; then
492    m4_if([$2],[nolinkcheck],[:],
493      [use_lapack=
494       AC_COIN_CHK_PKG_FLINK([use_lapack],[daxpy],[$lapack_lflags])
495       if test -n "$use_lapack" ; then
496         lapack_lflags=$use_lapack
497       else
498         AC_MSG_WARN([LAPACK failed to link with "$lapack_lflags"])
499       fi])
500
501# If FIND_PRIM_PKG didn't find anything, try a few guesses. First, try some
502# specialised checks based on the host system type. If none of them are
503# applicable, or the applicable one fails, try the generic -llapack.
504
505  elif test "$coin_has_lapack" = no ; then
506    AC_MSG_RESULT([nothing yet])
507    case $build in
508      *-sgi-*)
509        AC_MSG_CHECKING([for LAPACK in -lcomplib.sgimath])
510        AC_COIN_CHK_PKG_FLINK([lapack_lflags],[dsyev],[-lcomplib.sgimath])
511        ;;
512
513      *-*-solaris*)
514        # See comments in COIN_CHK_PKG_BLAS.
515        AC_MSG_CHECKING([for LAPACK in -lsunperf])
516        AC_COIN_CHK_PKG_FLINK([lapack_lflags],[dsyev],[-lsunperf])
517        ;;
518
519        # On cygwin, do this check only if doscompile is disabled. The
520        # prebuilt library will want to link with cygwin, hence won't run
521        # standalone in DOS.
522
523    esac
524    if test -z "$lapack_lflags" ; then
525      AC_MSG_CHECKING([for LAPACK in -llapack])
526      AC_COIN_CHK_PKG_FLINK([lapack_lflags],[dsyev],[-llapack])
527    fi
528    if test -n "$lapack_lflags" ; then
529      coin_has_lapack=yes
530    fi
531  fi
532
533# Done. Time to set some variables. Create an automake conditional
534# COIN_HAS_LAPACK.
535
536  AM_CONDITIONAL(m4_toupper(COIN_HAS_LAPACK),[test $coin_has_lapack = yes])
537
538# If we've located the package, define preprocessor symbol COIN_HAS_LAPACK
539# and augment the necessary variables for the client packages.
540
541  if test $coin_has_lapack = yes ; then
542    AC_DEFINE(m4_toupper(COIN_HAS_LAPACK),[1],
543      [Define to 1 if the LAPACK package is available])
544    m4_foreach_w([myvar],[$1],
545      [m4_toupper(myvar)_PCFILES="$lapack_pcfiles $m4_toupper(myvar)_PCFILES"
546       m4_toupper(myvar)_LFLAGS="$lapack_lflags $m4_toupper(myvar)_LFLAGS"
547       m4_toupper(myvar)_CFLAGS="$lapack_cflags $m4_toupper(myvar)_CFLAGS"])
548  else
549    AC_MSG_RESULT([$coin_has_lapack])
550  fi
551
552]) # AC_COIN_CHK_LAPACK
553
Note: See TracBrowser for help on using the repository browser.