简体   繁体   中英

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

system: lubuntu 18.04, running in VirtualBox

suppose I have the following directory of sources (code for these at the bottom):

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

prog.f is a simple fortran executable that will call a subroutine in the shared object compiled from lib.f .

To achieve this:

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

where the -Wl,-rpath=. option tells prog.exe to look in the current directory for its linked shared object so that I don't have worry about $LD_LIBRARY_PATH

now I want to call this same linked subroutine in python so I compile f2pyprog.f with an f2py call:

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

Now in this case, prog.cpython-blah-blah.so is a shared object, not an executable, so what I don't know is, how do call this workflow without having to worry about LD_LIBRARY_PATH but keeping the shared object in the same directory as the f2py compiled library.

calling test.py fails:

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

setting LD_LIBRARY_PATH first succeeds:

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

The Main Question:

Is it possible to build this (or any) f2py extension with a shared object linked in the current directory using something like the -rpath linker option and not having to worry about the $LD_LIBRARY_PATH environment variable?

Sources:

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. set env variable export LDFLAGS=-Wl,-rpath=.
  2. set env variable export NPY_DISTUTILS_APPEND_FLAGS=1
  3. upgrade numpy to 1.16.0 or greater

Although you cannot pass linker flags from the command line in f2py, it will read the LDFLAGS environment variable. However, the default 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 for optionally appending these linker flags by setting the environment variable 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM