2013-09-06 5 views
1

컴파일러가 특정 언어 기능을 지원하는 경우 "컴파일 타임"(예 : 전처리 기 사용)을 어떻게 알 수 있습니까? 하지만 그게 내가 순간에 걱정 무엇 때문에프로빙 언어 기능

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

나는이 질문에 fortran 태그 오전 : 내가 생각하고 구체적인 예를 들어 내가 같은 것을 할 싶습니다 포트란 2008 년 NEWUNIT 지정자입니다 일반적인 대답은 포트란 (autoconf ??)을 넘어서야 할 수도 있습니다. 물론이 솔루션은 가능한 한 많은 컴파일러에서 작동해야하지만 대부분은 gfortranifort (둘 다 NEWUNIT 세미 -를 최근에 소개했습니다)에 관심이 있습니다.

명확한 설명 : 나는 그런 상황을 처리 할 수있는 자동 방법을 찾고 있어요

  1. . (이것은 단지 포트란 소스 파일 이상을 포함 할 수도 있습니다 - Makefiles ...)
  2. 대부분의 유닉스 계열 시스템에서 작동하는 한 "표준"이라면별로 신경 쓰지 않습니다.
+0

그런 것은 표준화되어 있지 않습니다. –

+0

C 컴파일러에 액세스 할 수있는 경우이를 사용하여 매크로 (gcc -E)를 사전 처리 한 다음 포트란 컴파일러를 사용하여 출력을 컴파일 할 수 있습니다. – cup

+1

Fortran 전 처리기가 표준화되지 않았기 때문에 가장 간단한 매크로 만 대부분의 컴파일러에서 작동 할 수 있습니다. 이것은 단순한'# ifdef'를위한 것입니다. 그러나 예를 들어 인텔의 fpp는 연속 문자로 '&'를 인식하는 반면 gcc의 전 처리기는 Fortran을 인식하지 못하기 때문에 그렇지 않습니다. –

답변

3

autotools을 사용하는 경로, 특히 autoconf을 사용하려면 다음 코드를 작성하면됩니다.

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

AC_PREREQ(2.61) 
AC_INIT([test], [0.0.1], [[email protected]]) 

# 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 

m4/ 하위 디렉토리에있는 ax_f08_newunit.m4 매크로를 만듭니다

configure.ac가 만듭니다. 내가 지정한 곳이기 때문에 매크로가 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 루틴을 따르

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 
: 다음

aclocal -I m4 
autoheader 
autoconf 

당신이 ./configure를 실행할 수 있습니다, 이것은 내 출력

마지막으로 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 "[email protected]" 

/* 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 

자본 F는 파일을 사전 처리해야 의미 이해 ifort 테스트 프로그램을 컴파일.

2

(표준) Fortran에는 실제로 원하는 기능을 수행 할 수있는 기능이 없습니다. 우리 (Fortran 프로그래머)의 대부분 (?)은 새로운 기능을 사용하는 코드를 컴파일하고 컴파일러 메시지를 연구함으로써 새로운 기능의 가용성을 테스트합니다. 우리는 컴파일러 문서를 참조 할 수도 있습니다.

Fortran 표준에 정의되지 않은 Fortran 전처리 기는 제 경험에서 볼 때 보통 Fortran에 대해 거의 사용할 수 있도록 충분히 배운 C 전 처리기입니다. 두 다리를 걸을 개를 가르치는 것을 생각해보십시오. 결코 두 발 다리가 될 수는 없으며 4 각형 이동을 완벽하게 능숙하게합니다. 그래서 요점은 무엇입니까?

필자의 편견을 잠시 접어두고 컴파일 타임에 새로운 기능을 사용하는 코드를 컴파일하는 것 외에는 컴파일 타임에 확인할 수있는 표준 방법이 없습니다.

90 년대에 Fortran에 대한 조건부 컴파일에 대한 기술 보고서가있었습니다 (필자는 생각합니다). 그러나 제안 된 언어에 대한 확장이 Fortran의 최신 버전으로 바뀌지는 않았습니다.

한 가지 방법은 리눅스 소프트웨어의 많은의 리드를 따라 먼저 (이 경우)의 기능을 결정하는 등 automakeautoconf 같은 도구를 사용하는 것입니다 포트란 : OP의 설명에 대응

컴파일러, 나중에는 매크로 프로세서를 사용하여 작성하거나 필요한 코드 조각을 선택하여 컴파일 가능한 프로그램을 구성 할 수 있습니다. 즉, configure, makeinstall입니다.

컴파일 타임에 새로운 유닛이 런타임에 필요할 때 어떤 유닛 번호가 사용되는지 알기는 쉽지 않으므로 새 유닛을 선택하는 구식 접근법으로 돌아 가야한다고 생각합니다 아는 미리 정의 된 범위의 숫자 (또는 코드가 충분히 크고 복잡하면 희망 만있는 경우)는 이미 사용되지 않습니다.