检查编译时是否可用iso_c_binding

5
在混合C/Fortran应用程序的情况下,是否有一种方法可以检查编译器是否知道“iso_c_binding”(例如,GCC 4.1.2不知道它,而4.3.4则知道),比如预处理指令或其他方法?
我不能仅仅检查GCC的版本,因为我可能会使用其他编译器。
谢谢。

检查 #ifdef iso_c_binding 是否有效... - user529758
3
编写一个简单的程序,使用ISO_C_BINDING所需的内容。如果编译和运行成功,您可以将预处理器符号定义附加到某个配置头文件中。将此纳入代码构建过程。这是GNU autoconfconfigure脚本中执行的方式。 - Hristo Iliev
使用CMake可以做到这样的事情吗? - sunmat
@H2CO3:不好意思,它不起作用 :( - sunmat
抱歉,对于我来说,CMake就像黑魔法一样。也许可以运行一个外部程序(编译测试源代码并运行它),并根据结果设置CMake变量,例如将-DHAS_ISO_C_BINDING附加到编译器/预处理器命令行选项中。 - Hristo Iliev
如果iso_c_binding不可用,您想要做什么?中止编译还是只编译与该模块相关的部分? - Chris
2个回答

2
我能想到的只有两个选择,一个是为那些没有这个模块的系统编写自己的版本iso_c_binding(如@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不可用,则我会使用这种预处理器方法,因为这只需要为每个新编译器添加一个额外的检查即可。

哇塞,伙计。我特别没有建议复制英特尔Fortran源代码中的iso_c_binding,因为那可能侵犯英特尔的知识产权,这可能是非法的或违反我们雇主与英特尔供应软件的合同条款。我建议复制一个开源实现的模块。我已经编辑了你的问题,删除了你的诽谤性言论。 - High Performance Mark
好的 - 对此表示歉意。 - Chris

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处理器的手册。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接