【问题标题】:Ambiguous C binding name in FortranFortran 中不明确的 C 绑定名称
【发布时间】:2020-09-02 22:26:08
【问题描述】:

我正在尝试构建和使用来自this repo (FTL) 的库。 FTL 围绕 POSIX 正则表达式提供 Fortran 包装器,并且可以使用来自<regex.h> 的标准 C 库实现或来自<pcreposix.h> 的 PCRE 实现来构建(根据其wiki)。我能够使用make test 成功编译 FTL 的单元测试,但它们在运行时执行失败。

这就是我认为会发生的事情。这两种实现具有某些常数的不同值。这些值是通过执行 C 程序 (configure/configure_ftlRegex.c) 定义的,其中包括 <pcreposix.h><regex.h>,具体取决于编译期间的宏定义。默认情况下(这就是我编译单元测试的方式)这些常量是使用来自<pcreposix.h> 的实现生成的。

现在,在src/ftlRegex.F90 中定义了以下与名称为regexec 的C 函数的绑定:

function C_regexec(preg, string, nmatch, pmatch, eflags) result(status) bind(C,name='regexec')
   import
   type(C_ptr)           , intent(in) , value :: preg
   character(kind=C_char), intent(in)         :: string(*)
   integer(C_size_t)     , intent(in) , value :: nmatch
   type(C_regmatch_t)    , intent(out)        :: pmatch(*)
   integer(C_int)        , intent(in) , value :: eflags
   integer(C_int)                             :: status
end function

但是,链接器可以使用两种regexec 实现(具有相同的签名):一种来自标准C 库(自动链接),另一种来自libpcreposix(通过-lpcre -lpcreposix 链接)。它实际上绑定到哪一个?

执行ldd tests 显示以下输出:

linux-vdso.so.1 (0x00007ffd255a0000)
libgfortran.so.5 => /usr/lib/x86_64-linux-gnu/libgfortran.so.5 (0x00007f721a27c000)
libm.so.6 => /usr/lib/x86_64-linux-gnu/libm.so.6 (0x00007f721a12d000)
libc.so.6 => /usr/lib/x86_64-linux-gnu/libc.so.6 (0x00007f7219f3b000)
libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007f7219ef1000)
libgcc_s.so.1 => /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7219ed6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f721a647000)

如您所见,libpcrelibpcreposix 不在列表中,这让我相信链接器选择绑定到 <regex.h> 实现,这是错误的,因为在期间使用了来自 <pcreposix.h> 的常量汇编。链接器如何决定在这种情况下应该使用什么实现?有没有办法强制使用特定实现或至少检查使用了哪个实现?

注意:以下命令用于链接单元测试(由 makefile 生成):

gfortran -std=f2008 -fall-intrinsics -ffree-line-length-none -Wall -Wextra -Wpedantic -Wno-target-lifetime -Wno-compare-reals -Jbuild.gnu.debug -g -Og -fcheck=bounds,do,mem,pointer,recursion -Isrc -Itests  -DUSE_PCRE tests/tests.F90 build.gnu.debug/*.o -lpcreposix -lpcre -o build.gnu.debug/tests

使用 GNU Fortran (Ubuntu 9.3.0-10ubuntu2) 9.3.0 执行。

【问题讨论】:

    标签: linker fortran gfortran fortran-iso-c-binding


    【解决方案1】:

    这并没有真正回答我最初的问题,但是,作为一种解决方法,我最终明确地绑定到我自己的虚拟 C 函数,该函数又根据预处理器包含的标头调用一个或另一个实现。

    【讨论】:

      猜你喜欢
      • 2020-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多