Discussion:
Fortran wrappers
Andy May
2017-05-19 09:11:56 UTC
Permalink
Hi,

We have a project which is comprised of Fortran and C++ code, linked
together at the end with the C++ compiler. I have configure setup
with AC_LANG([C++]), and push/pop to Fortran as required. I notice that
using AC_FC_WRAPPERS() results in configure containing all the extra
infrastructure for C compilation and those tests use CC and CFLAGS.

Looking at fortran.m4 I see the reason is there are a few instances of
explicitly using the C compiler. Would it somehow be possible via an extra
argument or otherwise to add the ability to instruct those macros to use
the C++ compiler instead?

Many thanks,

Andy
Rhys Ulerich
2017-05-19 17:06:09 UTC
Permalink
Post by Andy May
Would it somehow be possible via an extra
argument or otherwise to add the ability to instruct those macros to use
the C++ compiler instead?

A hack: Look for C++ first then CC=$CXX?

- Rhys
Daily, Jeff A
2017-05-19 17:06:42 UTC
Permalink
Post by Andy May
We have a project which is comprised of Fortran and C++ code, linked
together at the end with the C++ compiler. I have configure setup
with AC_LANG([C++]), and push/pop to Fortran as required. I notice that
using AC_FC_WRAPPERS() results in configure containing all the extra
infrastructure for C compilation and those tests use CC and CFLAGS.
Looking at fortran.m4 I see the reason is there are a few instances of
explicitly using the C compiler. Would it somehow be possible via an extra
argument or otherwise to add the ability to instruct those macros to use
the C++ compiler instead?
Is it causing problems to have the C infrastructure within the Makefile? Or are you simply hoping for a cleaner, stripped-down Makefile?



If you’re worried about the C compiler configure checks automatically testing for headers, etc., just make sure you test for the same features with the C++ compiler first and those C tests should (I think) get skipped since the results were already provided using the C++ compiler.



Looks like the Fortran tests that trigger a C compiler are:

_AC_FC_DUMMY_MAIN

_AC_FC_MAIN

__AC_FC_NAME_MANGLING



And _AC_FC_DUMMY_MAIN is required by AC_FC_WRAPPERS, eventually.



Though not ideal, you could write your own name mangling configure test and substitute the C++ compiler. I’ve attached a file “my_fc_name_mangling.m4” that does just that. Not sure it’ll make it to the autoconf list as an attachment, so I’ll copy and paste below. I’ve renamed the various __AC_* and _AC_* and AC_* macros to “MY”, commented out the required call to _AC_FC_DUMMY_MAIN (YMMV whether you need that, but I’ll require a C compile again), and substituted the C++ compiler within the name mangling test code. Place that file wherever your ACLOCAL_AMFLAGS variable in the top of your Makefile.am points to so that autoreconf will pick it up. Use “MY_FC_NAME_MANGLING” – or the F77 one – in your configure.ac file.





File: my_fc_name_mangling.m4



# This file was copied and modified from Autoconf. Original license

# information appears below.



# This file is part of Autoconf. -*- Autoconf -*-

# Fortran languages support.

# Copyright (C) 2001, 2003-2012 Free Software Foundation, Inc.



# This file is part of Autoconf. This program is free

# software; you can redistribute it and/or modify it under the

# terms of the GNU General Public License as published by the

# Free Software Foundation, either version 3 of the License, or

# (at your option) any later version.

#

# This program is distributed in the hope that it will be useful,

# but WITHOUT ANY WARRANTY; without even the implied warranty of

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

# GNU General Public License for more details.

#

# Under Section 7 of GPL version 3, you are granted additional

# permissions described in the Autoconf Configure Script Exception,

# version 3.0, as published by the Free Software Foundation.

#

# You should have received a copy of the GNU General Public License

# and a copy of the Autoconf Configure Script Exception along with

# this program; see the files COPYINGv3 and COPYING.EXCEPTION

# respectively. If not, see <http://www.gnu.org/licenses/>.



# Written by David MacKenzie, with help from

# Franc,ois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,

# Roland McGrath, Noah Friedman, david d zuhn, and many others.



# __MY_FC_NAME_MANGLING

# ---------------------

# Test for the name mangling scheme used by the Fortran compiler.

#

# Sets ac_cv_{f77,fc}_mangling. The value contains three fields, separated

# by commas:

#

# lower case / upper case:

# case translation of the Fortran symbols

# underscore / no underscore:

# whether the compiler appends "_" to symbol names

# extra underscore / no extra underscore:

# whether the compiler appends an extra "_" to symbol names already

# containing at least one underscore

#

AC_DEFUN([__MY_FC_NAME_MANGLING],

[_AC_FORTRAN_ASSERT()dnl

AC_CACHE_CHECK([for _AC_LANG name-mangling scheme],

ac_cv_[]_AC_LANG_ABBREV[]_mangling,

[AC_COMPILE_IFELSE(

[[ subroutine foobar()

return

end

subroutine foo_bar()

return

end]],

[mv conftest.$ac_objext cfortran_test.$ac_objext



ac_save_LIBS=$LIBS

LIBS="cfortran_test.$ac_objext $LIBS $[]_AC_LANG_PREFIX[]LIBS"



AC_LANG_PUSH(C++)dnl

ac_success=no

for ac_foobar in foobar FOOBAR; do

for ac_underscore in "" "_"; do

ac_func="$ac_foobar$ac_underscore"

AC_LINK_IFELSE([AC_LANG_CALL([], [$ac_func])],

[ac_success=yes; break 2])

done

done

AC_LANG_POP(C++)dnl



if test "$ac_success" = "yes"; then

case $ac_foobar in

foobar)

ac_case=lower

ac_foo_bar=foo_bar

;;

FOOBAR)

ac_case=upper

ac_foo_bar=FOO_BAR

;;

esac



AC_LANG_PUSH(C++)dnl

ac_success_extra=no

for ac_extra in "" "_"; do

ac_func="$ac_foo_bar$ac_underscore$ac_extra"

AC_LINK_IFELSE([AC_LANG_CALL([], [$ac_func])],

[ac_success_extra=yes; break])

done

AC_LANG_POP(C++)dnl



if test "$ac_success_extra" = "yes"; then

ac_cv_[]_AC_LANG_ABBREV[]_mangling="$ac_case case"

if test -z "$ac_underscore"; then

ac_cv_[]_AC_LANG_ABBREV[]_mangling="$ac_cv_[]_AC_LANG_ABBREV[]_mangling, no underscore"

else

ac_cv_[]_AC_LANG_ABBREV[]_mangling="$ac_cv_[]_AC_LANG_ABBREV[]_mangling, underscore"

fi

if test -z "$ac_extra"; then

ac_cv_[]_AC_LANG_ABBREV[]_mangling="$ac_cv_[]_AC_LANG_ABBREV[]_mangling, no extra underscore"

else

ac_cv_[]_AC_LANG_ABBREV[]_mangling="$ac_cv_[]_AC_LANG_ABBREV[]_mangling, extra underscore"

fi

else

ac_cv_[]_AC_LANG_ABBREV[]_mangling="unknown"

fi

else

ac_cv_[]_AC_LANG_ABBREV[]_mangling="unknown"

fi



LIBS=$ac_save_LIBS

rm -rf conftest*

rm -f cfortran_test*],

[AC_MSG_FAILURE([cannot compile a simple Fortran program])])

])

])# __MY_FC_NAME_MANGLING





# The replacement is empty.

AU_DEFUN([AC_F77_NAME_MANGLING], [])





# _MY_F77_NAME_MANGLING

# ---------------------

AC_DEFUN([_MY_F77_NAME_MANGLING],

[AC_REQUIRE([AC_F77_LIBRARY_LDFLAGS])dnl

dnl AC_REQUIRE([AC_F77_DUMMY_MAIN])dnl

AC_LANG_PUSH(Fortran 77)dnl

__MY_FC_NAME_MANGLING

AC_LANG_POP(Fortran 77)dnl

])# _MY_F77_NAME_MANGLING





# _MY_FC_NAME_MANGLING

# --------------------

AC_DEFUN([_MY_FC_NAME_MANGLING],

[AC_REQUIRE([AC_FC_LIBRARY_LDFLAGS])dnl

dnl AC_REQUIRE([AC_FC_DUMMY_MAIN])dnl

AC_LANG_PUSH(Fortran)dnl

__MY_FC_NAME_MANGLING

AC_LANG_POP(Fortran)dnl

])# _MY_FC_NAME_MANGLING





# _MY_FC_WRAPPERS

# ---------------

# Defines C macros {F77,FC}_FUNC(name,NAME) and {F77,FC}_FUNC_(name,NAME) to

# properly mangle the names of C identifiers, and C identifiers with

# underscores, respectively, so that they match the name mangling

# scheme used by the Fortran compiler.

AC_DEFUN([_MY_FC_WRAPPERS],

[_AC_FORTRAN_ASSERT()dnl

AH_TEMPLATE(_AC_FC[_FUNC],

[Define to a macro mangling the given C identifier (in lower and upper

case), which must not contain underscores, for linking with Fortran.])dnl

AH_TEMPLATE(_AC_FC[_FUNC_],

[As ]_AC_FC[_FUNC, but for C identifiers containing underscores.])dnl

case $ac_cv_[]_AC_LANG_ABBREV[]_mangling in

"lower case, no underscore, no extra underscore")

AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [name])

AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name]) ;;

"lower case, no underscore, extra underscore")

AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [name])

AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name [##] _]) ;;

"lower case, underscore, no extra underscore")

AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [name [##] _])

AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name [##] _]) ;;

"lower case, underscore, extra underscore")

AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [name [##] _])

AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name [##] __]) ;;

"upper case, no underscore, no extra underscore")

AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [NAME])

AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME]) ;;

"upper case, no underscore, extra underscore")

AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [NAME])

AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME [##] _]) ;;

"upper case, underscore, no extra underscore")

AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [NAME [##] _])

AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME [##] _]) ;;

"upper case, underscore, extra underscore")

AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [NAME [##] _])

AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME [##] __]) ;;

*)

AC_MSG_WARN([unknown Fortran name-mangling scheme])

;;

esac

])# _MY_FC_WRAPPERS





# MY_F77_WRAPPERS

# ---------------

AC_DEFUN([MY_F77_WRAPPERS],

[AC_REQUIRE([_MY_F77_NAME_MANGLING])dnl

AC_LANG_PUSH(Fortran 77)dnl

_MY_FC_WRAPPERS

AC_LANG_POP(Fortran 77)dnl

])# MY_F77_WRAPPERS





# MY_FC_WRAPPERS

# --------------

AC_DEFUN([MY_FC_WRAPPERS],

[AC_REQUIRE([_MY_FC_NAME_MANGLING])dnl

AC_LANG_PUSH(Fortran)dnl

_MY_FC_WRAPPERS

AC_LANG_POP(Fortran)dnl

])# MY_FC_WRAPPERS
Andy May
2017-05-22 14:11:01 UTC
Permalink
Many thanks both for the suggestions.

Jeff: it doesn't cause any problems, it's just makes a longer configure
script and puts CC and CFLAGS under the list of 'influential environment
variables' for configure's help. I thought it worth mentioning as a
potential enhancement, perhaps to use the currently selected language,
defaulting to C if the current language is not appropriate. Probably I'll
use something based on what you attached, perhaps automatically generated
by applying some sed to fortran.m4 so that any updates in the future to
fortran.m4 are brought in.

Best wishes,

Andy
Post by Daily, Jeff A
Post by Andy May
We have a project which is comprised of Fortran and C++ code, linked
together at the end with the C++ compiler. I have configure setup
with AC_LANG([C++]), and push/pop to Fortran as required. I notice
that
Post by Andy May
using AC_FC_WRAPPERS() results in configure containing all the extra
infrastructure for C compilation and those tests use CC and CFLAGS.
Looking at fortran.m4 I see the reason is there are a few instances of
explicitly using the C compiler. Would it somehow be possible via an
extra
Post by Andy May
argument or otherwise to add the ability to instruct those macros to
use
Post by Andy May
the C++ compiler instead?
Is it causing problems to have the C infrastructure within the Makefile?
Or are you simply hoping for a cleaner, stripped-down Makefile?
If you’re worried about the C compiler configure checks automatically
testing for headers, etc., just make sure you test for the same features
with the C++ compiler first and those C tests should (I think) get skipped
since the results were already provided using the C++ compiler.
_AC_FC_DUMMY_MAIN
_AC_FC_MAIN
__AC_FC_NAME_MANGLING
And _AC_FC_DUMMY_MAIN is required by AC_FC_WRAPPERS, eventually.
Though not ideal, you could write your own name mangling configure test
and substitute the C++ compiler. I’ve attached a file
“my_fc_name_mangling.m4” that does just that. Not sure it’ll make it to
the autoconf list as an attachment, so I’ll copy and paste below. I’ve
renamed the various __AC_* and _AC_* and AC_* macros to “MY”, commented out
the required call to _AC_FC_DUMMY_MAIN (YMMV whether you need that, but
I’ll require a C compile again), and substituted the C++ compiler within
the name mangling test code. Place that file wherever your ACLOCAL_AMFLAGS
variable in the top of your Makefile.am points to so that autoreconf will
pick it up. Use “MY_FC_NAME_MANGLING” – or the F77 one – in your
configure.ac file.
File: my_fc_name_mangling.m4
# This file was copied and modified from Autoconf. Original license
# information appears below.
# This file is part of Autoconf. -*- Autoconf -*-
# Fortran languages support.
# Copyright (C) 2001, 2003-2012 Free Software Foundation, Inc.
# This file is part of Autoconf. This program is free
# software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the Autoconf Configure Script Exception,
# version 3.0, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License
# and a copy of the Autoconf Configure Script Exception along with
# this program; see the files COPYINGv3 and COPYING.EXCEPTION
# respectively. If not, see <http://www.gnu.org/licenses/>.
# Written by David MacKenzie, with help from
# Franc,ois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,
# Roland McGrath, Noah Friedman, david d zuhn, and many others.
# __MY_FC_NAME_MANGLING
# ---------------------
# Test for the name mangling scheme used by the Fortran compiler.
#
# Sets ac_cv_{f77,fc}_mangling. The value contains three fields, separated
#
# case translation of the Fortran symbols
# whether the compiler appends "_" to symbol names
# whether the compiler appends an extra "_" to symbol names already
# containing at least one underscore
#
AC_DEFUN([__MY_FC_NAME_MANGLING],
[_AC_FORTRAN_ASSERT()dnl
AC_CACHE_CHECK([for _AC_LANG name-mangling scheme],
ac_cv_[]_AC_LANG_ABBREV[]_mangling,
[AC_COMPILE_IFELSE(
[[ subroutine foobar()
return
end
subroutine foo_bar()
return
end]],
[mv conftest.$ac_objext cfortran_test.$ac_objext
ac_save_LIBS=$LIBS
LIBS="cfortran_test.$ac_objext $LIBS $[]_AC_LANG_PREFIX[]LIBS"
AC_LANG_PUSH(C++)dnl
ac_success=no
for ac_foobar in foobar FOOBAR; do
for ac_underscore in "" "_"; do
ac_func="$ac_foobar$ac_underscore"
AC_LINK_IFELSE([AC_LANG_CALL([], [$ac_func])],
[ac_success=yes; break 2])
done
done
AC_LANG_POP(C++)dnl
if test "$ac_success" = "yes"; then
case $ac_foobar in
foobar)
ac_case=lower
ac_foo_bar=foo_bar
;;
FOOBAR)
ac_case=upper
ac_foo_bar=FOO_BAR
;;
esac
AC_LANG_PUSH(C++)dnl
ac_success_extra=no
for ac_extra in "" "_"; do
ac_func="$ac_foo_bar$ac_underscore$ac_extra"
AC_LINK_IFELSE([AC_LANG_CALL([], [$ac_func])],
[ac_success_extra=yes; break])
done
AC_LANG_POP(C++)dnl
if test "$ac_success_extra" = "yes"; then
ac_cv_[]_AC_LANG_ABBREV[]_mangling="$ac_case case"
if test -z "$ac_underscore"; then
ac_cv_[]_AC_LANG_ABBREV[]_mangling="$ac_cv_[]_AC_LANG_ABBREV[]_mangling,
no underscore"
else
ac_cv_[]_AC_LANG_ABBREV[]_mangling="$ac_cv_[]_AC_LANG_ABBREV[]_mangling,
underscore"
fi
if test -z "$ac_extra"; then
ac_cv_[]_AC_LANG_ABBREV[]_mangling="$ac_cv_[]_AC_LANG_ABBREV[]_mangling,
no extra underscore"
else
ac_cv_[]_AC_LANG_ABBREV[]_mangling="$ac_cv_[]_AC_LANG_ABBREV[]_mangling,
extra underscore"
fi
else
ac_cv_[]_AC_LANG_ABBREV[]_mangling="unknown"
fi
else
ac_cv_[]_AC_LANG_ABBREV[]_mangling="unknown"
fi
LIBS=$ac_save_LIBS
rm -rf conftest*
rm -f cfortran_test*],
[AC_MSG_FAILURE([cannot compile a simple Fortran program])])
])
])# __MY_FC_NAME_MANGLING
# The replacement is empty.
AU_DEFUN([AC_F77_NAME_MANGLING], [])
# _MY_F77_NAME_MANGLING
# ---------------------
AC_DEFUN([_MY_F77_NAME_MANGLING],
[AC_REQUIRE([AC_F77_LIBRARY_LDFLAGS])dnl
dnl AC_REQUIRE([AC_F77_DUMMY_MAIN])dnl
AC_LANG_PUSH(Fortran 77)dnl
__MY_FC_NAME_MANGLING
AC_LANG_POP(Fortran 77)dnl
])# _MY_F77_NAME_MANGLING
# _MY_FC_NAME_MANGLING
# --------------------
AC_DEFUN([_MY_FC_NAME_MANGLING],
[AC_REQUIRE([AC_FC_LIBRARY_LDFLAGS])dnl
dnl AC_REQUIRE([AC_FC_DUMMY_MAIN])dnl
AC_LANG_PUSH(Fortran)dnl
__MY_FC_NAME_MANGLING
AC_LANG_POP(Fortran)dnl
])# _MY_FC_NAME_MANGLING
# _MY_FC_WRAPPERS
# ---------------
# Defines C macros {F77,FC}_FUNC(name,NAME) and {F77,FC}_FUNC_(name,NAME) to
# properly mangle the names of C identifiers, and C identifiers with
# underscores, respectively, so that they match the name mangling
# scheme used by the Fortran compiler.
AC_DEFUN([_MY_FC_WRAPPERS],
[_AC_FORTRAN_ASSERT()dnl
AH_TEMPLATE(_AC_FC[_FUNC],
[Define to a macro mangling the given C identifier (in lower and upper
case), which must not contain underscores, for linking with Fortran.])dnl
AH_TEMPLATE(_AC_FC[_FUNC_],
[As ]_AC_FC[_FUNC, but for C identifiers containing underscores.])dnl
case $ac_cv_[]_AC_LANG_ABBREV[]_mangling in
"lower case, no underscore, no extra underscore")
AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [name])
AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name]) ;;
"lower case, no underscore, extra underscore")
AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [name])
AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name [##] _]) ;;
"lower case, underscore, no extra underscore")
AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [name [##] _])
AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name [##] _]) ;;
"lower case, underscore, extra underscore")
AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [name [##] _])
AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [name [##] __]) ;;
"upper case, no underscore, no extra underscore")
AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [NAME])
AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME]) ;;
"upper case, no underscore, extra underscore")
AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [NAME])
AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME [##] _]) ;;
"upper case, underscore, no extra underscore")
AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [NAME [##] _])
AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME [##] _]) ;;
"upper case, underscore, extra underscore")
AC_DEFINE(_AC_FC[_FUNC(name,NAME)], [NAME [##] _])
AC_DEFINE(_AC_FC[_FUNC_(name,NAME)], [NAME [##] __]) ;;
*)
AC_MSG_WARN([unknown Fortran name-mangling scheme])
;;
esac
])# _MY_FC_WRAPPERS
# MY_F77_WRAPPERS
# ---------------
AC_DEFUN([MY_F77_WRAPPERS],
[AC_REQUIRE([_MY_F77_NAME_MANGLING])dnl
AC_LANG_PUSH(Fortran 77)dnl
_MY_FC_WRAPPERS
AC_LANG_POP(Fortran 77)dnl
])# MY_F77_WRAPPERS
# MY_FC_WRAPPERS
# --------------
AC_DEFUN([MY_FC_WRAPPERS],
[AC_REQUIRE([_MY_FC_NAME_MANGLING])dnl
AC_LANG_PUSH(Fortran)dnl
_MY_FC_WRAPPERS
AC_LANG_POP(Fortran)dnl
])# MY_FC_WRAPPERS
Loading...