【发布时间】: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)
如您所见,libpcre 和 libpcreposix 不在列表中,这让我相信链接器选择绑定到 <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