1

コンパイラが特定の言語機能をサポートしているかどうかを「コンパイル時」に (たとえば、プリプロセッサを使用して) 確認するにはどうすればよいですか? 私が考えている具体的な例はNEWUNIT、Fortran 2008 の指定子です。次のようなことをしたいと思います。

#ifdef HAVE_NEWUNIT
! go ahead and use that
#else
! activate workaround
#endif

fortran一般的な答えは Fortran ( autoconf??)を超える必要があるのではないかと思いますが、現時点で関心があるため、この質問にタグを付けています。もちろん、このソリューションはできるだけ多くのコンパイラで動作するはずですが、ほとんどの場合、私が気にするのはgfortranand ifort(どちらもNEWUNIT最近導入されたものです) です。

説明:

  1. このような状況を自動的に処理する方法を探しています。(これには、Fortran ソース ファイル以外のものが含まれる場合があります -- Makefiles …)
  2. ほとんどの Unix タイプのシステムで動作する限り、それが「標準」であるかどうかはあまり気にしません。
4

2 に答える 2

4

を使用するルートをたどる場合autotools、具体的autoconfには、次のようにすべてをコーディングします。

を作成しますconfigure.ac

dnl                                               -*- Autoconf -*-
dnl Process this file with autoconf to produce a configure script.
dnl

AC_PREREQ(2.61)
AC_INIT([test], [0.0.1], [me@example.com])

# Define our M4 macro directory
AC_CONFIG_MACRO_DIR([m4])

# Put our generated config header in the source directory
AC_CONFIG_HEADERS([src/config.h])

# Make sure we have a fortran compiler
AC_PROG_FC([ifort xlf pgfortran gfortran])
AC_LANG([Fortran])
AC_FC_FREEFORM

# Check for newunit option to open()
AX_F08_NEWUNIT

AC_OUTPUT

サブディレクトリにax_f08_newunit.m4マクロを作成します。m4/これは私が指定した場所なので、マクロは次の場所にありますconfigure.ac

AC_DEFUN([AX_F08_NEWUNIT], [

AC_REQUIRE([AC_PROG_FC])
AC_LANG_PUSH([Fortran])

AC_MSG_CHECKING([for NEWUNIT support])
AC_COMPILE_IFELSE([
       program conftest
       integer :: i
       open(newunit=i,file='test')
       end program conftest],
[ax_f08_newunit=yes], [ax_f08_newunit=no])

AC_LANG_POP([Fortran])

if test "x$ax_f08_newunit" = "xyes"; then
    AC_MSG_RESULT([yes])
    AC_DEFINE([HAVE_NEWUNIT], [1], [NEWUNIT support])
else
    AC_MSG_RESULT([no])
fi

])

次に、すべての通常のautotoolsルーチンに従います。

aclocal -I m4
autoheader
autoconf

次に、実行できます./configure。これが私の出力です:

checking for Fortran compiler default output file name... a.out
checking whether the Fortran compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU Fortran compiler... no
checking whether ifort accepts -g... yes
checking for Fortran flag needed to allow free-form source... -FR
checking for NEWUNIT support... yes
configure: creating ./config.status
config.status: creating src/config.h

最後に、src/config.hファイルには次のものが必要です。

/* src/config.h.  Generated from config.h.in by configure.  */
/* src/config.h.in.  Generated from configure.ac by autoheader.  */

/* NEWUNIT support */
#define HAVE_NEWUNIT 1

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "me@example.com"

/* Define to the full name of this package. */
#define PACKAGE_NAME "test"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "test 0.0.1"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "test"

/* Define to the version of this package. */
#define PACKAGE_VERSION "0.0.1"

もちろん、ソース コードもプリプロセッサを介して実行する必要があります。例src/test.F90:

program test
#include "config.h"

integer :: i

#ifdef HAVE_NEWUNIT
  open(newunit=i,file='data')
#else
  i = 7
  open(unit=i,file='data')
#endif

end program test

テスト プログラムをコンパイルifortすると、大文字の F はファイルを前処理する必要があることを意味します。

于 2013-09-06T21:49:26.173 に答える
1

(標準) Fortran には、ユーザーが望むことを行う機能が実際にはありません。私たち (Fortran プログラマー) のほとんど (?) は、それを使用するコードをコンパイルし、コンパイラーのメッセージを調べることによって、新しい機能の可用性をテストします。また、コンパイラのドキュメントを参照することもあります。

Fortran 標準で定義されていない Fortran プリプロセッサは、私の経験では、通常、ほとんど使用できるように Fortran について十分に教えられた C プリプロセッサです。犬に二足歩行を教えることを考えてみてください。真の二足歩行になることは決してなく、四足歩行が完全に得意なので、ポイントは何ですか?

私自身の偏見はさておき、コンパイル時に、それを使用するコードをコンパイルする以外に、新しい機能が利用可能かどうかをチェックする標準的な方法はありません。

90 年代に Fortran の条件付きコンパイルに関するテクニカル レポートがありましたが (私が思うに)、それが提案した言語の拡張機能は、最近の Fortran の版には反映されていません。

OPの説明に応えて:

1 つのアプローチは、多くの Linux ソフトウェアのリードに従い、 などのツールを使用して (この場合は) Fortran コンパイラの機能automakeautoconf最初に判断し、後で (おそらくマクロ プロセッサを使用して) 書き込むか、コードの必要な断片を選択し、それによってコンパイル可能なプログラムを構築します。つまり、configuremakeおよびinstall.

実行時に新しいユニット番号が必要になったときに、どのユニット番号が使用されているかをコンパイル時に判断するのは簡単なことではないので、事前に新しいユニット番号を選択するという昔ながらのアプローチに頼る必要があると思います。あなたが知っている-定義された範囲(または、コードが十分に大きく複雑な場合は、希望するだけです)はまだ使用されていません。

于 2013-09-06T08:37:35.367 に答える