Fortran共享库中符号的命名,intel与gcc有何区别?

4

有没有一种方法可以控制共享库中符号的命名?具体而言,我正在使用GCC进行一个项目,在其中通过Python中的C-Types访问共享库。这很好用,但最近我在使用建议使用Intel编译器的系统。我可以很好地构建共享对象,但我发现符号的命名约定与intel略有不同。具体而言,当我使用gcc编译时,符号名称看起来像:

__test_function_MOD_read_a_file

英特尔编译的共享对象具有以下符号名称:

test_function_mp_read_a_file__

有没有办法强制保持命名的一致性,或者至少在事后更改符号的名称?
例如,请考虑以下代码test_function.f90
MODULE test_function
   CONTAINS
   SUBROUTINE read_a_file
      PRINT *,'I did a thing!'
   END SUBROUTINE
END

编译命令应该长成这个样子:
gfortran -fPIC -c test_function.f90
gfortran -shared -o libtest_function.so test_function.o

1
你的问题与共享库无关,而与Fortran有关。我会这样表述:“如何使gfortran和英特尔ifort的外部函数具有一致的名称?” - Employed Russian
模块文件及其符号名称混淆在不同编译器之间完全不兼容,甚至在同一编译器的主要版本之间也是如此。 - tim18
当然,如果您像这样声明变量 real(C_FLOAT) bind(C,name=....) x,您可以精确地控制与兼容的 C 编译器看到的符号名称。 - tim18
1
需要模块的子程序和函数的代码在不同编译器之间很容易出现完全不兼容的情况。例如,GCC和Intel的数组描述符是不同的。这样的代码在这两者之间使用时将会崩溃。 - Vladimir F Героям слава
如果您希望在此上下文中使用数组描述符,只要Fortran编译器与相同的C编译器兼容,且您的编译器实现了新的F2008功能,那么这应该是可能的。 - tim18
@tim18 但仅适用于 bind(C) 过程。 - Vladimir F Героям слава
1个回答

8

两个编译器都在修改模块中包含的子程序的名称。Fortran标准没有规定任何命名约定。您可以使用Fortran的ISO C绑定功能来为子程序指定特定的名称,以防止名称混淆。例如,

module bar
   contains
   function fun(x) bind(c, name='foo')
       real fun, x
       fun = x
   end function fun
   function goo(x)
       real goo, x
       goo = x
   end function goo
end module bar

使用gfortran编译时,生成的目标文件包含以下内容:

gfortran -c a.f90
nm a.o
00000000 T __bar_MOD_goo
00000013 T foo

因此,在库中可以将函数fun称为foo。您可能还希望使用iso_c_binding模块定义的类型。

1
这是唯一的便携选项。 - Vladimir F Героям слава

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