2012-08-14 116 views
5

在混合C/Fortran应用程序的上下文中,有没有办法检查编译器是否知道“iso_c_binding”(例如GCC 4.1.2不知道它,而while 4.3.4是否),像预处理指令或其他? 我不能简单地检查GCC的版本,因为我可能使用其他编译器。检查编译时iso_c_binding是否可用

感谢

+0

检查'#ifdef来iso_c_binding'等作品... – 2012-08-14 15:14:01

+3

编译使用你'ISO_C_BINDING'需要的东西一个简单的程序。如果编译并运行,则可以将预处理器符号定义附加到某个配置头文件。使这部分代码构建过程成为可能。这就是GNU'autoconf'在'configure'脚本中的作用。 – 2012-08-14 15:22:24

+0

有没有可能用CMake做这样的事情? – sunmat 2012-08-14 15:30:13

回答

2

你只有两个选择,我能想到的,都推出自己的iso_c_binding版本不具有该模块(as suggested by @HighPerformanceMark)或使用预处理器有条件地编译代码的部分系统取决于编译器版本。在这两种情况下,您都必须努力确保您的代码可跨系统移植。正如@HighPerformanceMark所建议的那样,您可以复制并粘贴一个开源实现iso_c_binding,但是对于每个新系统,将代码移植到您之前必须检查此实现是否正确。

根据您希望如何你的代码的行为,如果iso_c_binding缴费我会建议使用预处理方法。你声明“我不能简单地检查GCC的版本,因为我可能使用其他编译器”。但是,您的所有选项都需要您的工作来维护您的代码以便在不同的系统上使用,预处理器方法在我的操作中需要的工作量最少。

以下代码使用预处理器确定编译器版本,并可用于根据编译器版本是否满足某些最低版本条件编译您的代码。对于gfortran

如果GNU的Fortran调用预,__GFORTRAN__被定义和__GNUC____GNUC_MINOR____GNUC_PATCHLEVEL__可以用于确定编译器的版本。

在一个文件中,比如说precomp.inc我会包含一些预编译器检查,它们决定了哪些功能包含在你的代码中。例如,我会检查编译器的版本,如果它支持使用iso_c_binding模块,我会定义一个预处理器宏HAS_ISO_C_BINDING(或类似的)。文件precomp.inc然后可以包含在您的代码的其他部分。该文件可能看起来是这样的:

!> \file precomp.inc 
!! Preprocessor feature detection. 

#if defined(__GFORTRAN__) 

#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 
#define HAS_ISO_C_BINDING 1 
#else 
#define HAS_ISO_C_BINDING 0 
#endif 

#elif defined(__INTEL_COMPILER) 
#error "I haven't implemented this yet..." 

#else 
#error "Compiler not yet supported." 

#endif 

误差的最后#else子句中可以用HAS_ISO_C_BINDING=0被替换,如果你希望能够不为ISO_C_BINDING模块的支持编译。

你的Fortran源会看起来像

program main 

#include 'precomp.h' 
#if HAS_ISO_C_BINDING 
use iso_c_binding 
#endif 

implicit none 

! Some code... 

#if HAS_ISO_C_BINDING 
! Code which depends on iso_c_binding 
#else 
! Fallback code 
#end if 

! Some more code... 

end program main 

同样,要使用正确的方法取决于你想如何代码编译,如果iso_c_binding不缴费。如果你的代码需要在没有这个模块的系统上编译,那么@HighPerformanceMark的答案可能会更好。如果你可以在编译时引发一个错误,或者如果你有一些后备代码,如果iso_c_binding不可用,那么我会使用这个预处理器方法,因为这只需要为每个你需要使用的新编译器添加一个额外的检查。

+0

哇!伙计。我特别是不建议复制了'iso_c_binding'英特尔Fortran的来源,可能是英特尔的知识产权的侵犯,它可以是非法或对合同的,我的雇主必须与英特尔的软件供应条款。我建议复制一个开源的模块实现,我编辑了你的问题来删除你的诽谤性断言。 – 2012-08-15 10:03:03

+0

够公平的 - apologie为此。 – Chris 2012-08-15 10:06:44

0

问题是错误的。实际上,您要问的是,伴随Fortran处理器(假设它存在)是否支持C程序需要的C互操作性的必要方面。C互操作性远远超过了内在模块的存在。

例如,F2003处理器提供ISO_C_BINDING是合理的,然后说C几乎所有方面的互操作性都不被支持(像C_FLOAT,C_REAL等常量可能有负值,意思是“不”支持的”)。

所以,除非你的C互操作的使用是非常基本的(有些方面必须由F2003处理器的支持 - 如c_int的,C_LOC,C_F_POINTER等),唯一可行的方法来确定功能有:

  • 要编译一个小的Fortran程序,明确使用是必要的实体,并测试它们的值(不同的负数解释为什么Fortran的处理器不提供支持)。正如其他人所写的,如果编译成功,编译的成功或失败以及可能随后的程序输出都可以用来配置构建的其他方面。

  • 要读取的Fortran处理器的手册。