如何告诉 f2py 模块在当前目录中查找共享对象依赖项

how to tell f2py module to look in current directory for shared object dependency

system: lubuntu 18.04, running in VirtualBox

假设我有以下源目录(底部的代码):

/f2pyproject/
  - lib.f
  - prog.f
  - f2pyprog.f
  - test.py

prog.f 是一个简单的 fortran 可执行文件,它将调用从 lib.f.

编译的共享对象中的子例程

实现这个:

>>> gfortran -shared lib.f -o lib.so
>>> gfortran prog.f lib.so -o prog.exe -Wl,-rpath=.
>>> ./prog.exe
    hello world

其中 -Wl,-rpath=. 选项告诉 prog.exe 在当前目录中查找其链接的共享对象,这样我就不用担心 $LD_LIBRARY_PATH

现在我想在 python 中调用相同的链接子例程,所以我使用 f2py 调用编译 f2pyprog.f:

>>> python3 -m numpy.f2py -c f2pyprog.f lib.so -m prog

现在在这种情况下,prog.cpython-blah-blah.so 是一个共享对象,而不是可执行文件,所以我不知道的是,如何调用这个工作流而不必担心 LD_LIBRARY_PATH 但保持f2py编译库同目录下的共享对象

调用 test.py 失败:

>>> python3 test.py  (fails with ImportError, cannot open shared object file)

设置LD_LIBRARY_PATH第一次成功:

>>> export LD_LIBRARY_PATH=`pwd`
>>> python3 test.py
    hello world

主要问题:

是否可以使用 -rpath 链接器选项之类的东西在当前目录中链接一个共享对象来构建这个(或任何)f2py 扩展,而不必担心 $LD_LIBRARY_PATH 环境变量?

来源:

lib.f:

  subroutine helloworld()
      print*, "hello world"
  return
  end subroutine

prog.f:

  program helloworldprog
    call helloworld()
  end program helloworldprog

f2pyprog.f:

  subroutine pyhelloworld()
    call helloworld()
  return
  end subroutine

test.py

import os
from os import path
# has no effect, presumably because this needs to be set before python starts
os.environ['LD_LIBRARY_PATH'] = path.abspath(path.dirname(__file__))  

import prog
prog.pyhelloworld()
  1. 设置环境变量export LDFLAGS=-Wl,-rpath=.
  2. 设置环境变量export NPY_DISTUTILS_APPEND_FLAGS=1
  3. numpy 升级到 1.16.0 或更高

尽管您不能在 f2py 中从命令行传递链接器标志,但它会读取 LDFLAGS 环境变量。但是,默认 behavior for numpy is to overwrite the flags used in compiling rather than appending them which will cause failure in compiling if the required flags are not present in LDFLAGS. Support was added in numpy version 1.16.0 通过设置环境变量 NPY_DISTUTILS_APPEND_FLAGS=1

可选择附加这些链接器标志
>>> unset LD_LIBRARY_FLAGS   # just in case was set before
>>> export LDFLAGS=-Wl,-rpath=.
>>> export NPY_DISTUTILS_APPEND_FLAGS=1
>>> python3 -m numpy.f2py -c progpy.f lib.so -m prog
>>> python3 test.py
    hello world