当前位置: 首页 > 知识库问答 >
问题:

使用setuptools将f2py生成的*.so文件链接到python包中

楚嘉玉
2023-03-14

我希望使用SetupTools将一个包部署到PyPi。但是,包的核心部分实际上是用Fortran编写的,我正在使用f2py用Python包装。基本上,项目的结构如下所示:

    null

myfunc.py模块导入hello.so(importmy_project.hello),然后myfunc.py中的函数可以使用该模块。这在我的机器上很好用。

然后我在我的Ubuntu上尝试了标准的setuptools安装:sudopython3setup.py install,结果安装得很好。但不幸的是,在导入时,它抛出modulenotfounderror:No module name'hello'

现在,据我所知,在基于Linux的系统上,对于python,共享库*.so存储在/usr/lib/python3/dist-packages/中。所以我在那里手动复制了这个hello.So,我得到了一个工作包!但当然这只在局部起作用。我想做的是告诉setuptools在python-egg中包含hello.so并自动执行复制等操作,这样当用户使用pip3 install my_package时,他们就可以自动访问这个共享库。我可以看到numpy以某种方式实现了这一点,但即使在查看了他们的代码后,我也无法解码他们是如何做到这一点的。有人能帮我一下吗?提前道谢。

共有1个答案

夏谦
2023-03-14

这里是一种基于F2PY文档的方法(这里的示例包括构建多个F2PY模块,每个模块包含多个源文件),使用支持Fortran源文件的numpy.distutils

具有多个F2PY扩展模块的最小示例的结构基于src目录布局。它不是必需的/必需的,但其优点是除非包已经安装成功,否则测试例程无法运行。

my_project
|
+-- src
|   |
|   +-- my_project
|       |
|       +-- __init__.py
|       +-- mod1.py
|       +-- funcs_m.f90
|       +-- two
|           |
|           +-- pluss2.f90
|           +-- times2.f90
|
+-- test_my_project.py
+-- setup.py

  • setup.py
from setuptools import find_packages

from numpy.distutils.core import setup, Extension

ext1 = Extension(name='my_project.modf90',
                 sources=['src/my_project/funcs_m.f90'],
                 f2py_options=['--quiet'],
                )

ext2 = Extension(name='my_project.oldf90',
                 sources=['src/my_project/two/plus2.f90', 'src/my_project/two/times2.f90'],
                 f2py_options=['--quiet'],
                )

setup(name="my_project",
      version="0.0.1",
      package_dir={"": "src"},
      packages=find_packages(where="src"),
      ext_modules=[ext1, ext2])
  • __init__.py

__init__.py文件为空。(如有需要,可在此处导入F2PY模块)

  • mod1.py
def add(a, b):
  """ add inputs a and b, and return """
  return a + b
  • 函数_m.f90
module funcs_m
  implicit none
  contains
    subroutine add(a, b, c)
      integer, intent(in)  :: a
      integer, intent(in)  :: b
      integer, intent(out) :: c
      c = a + b
    end subroutine add
end module funcs_m
  • plus2.f90
subroutine plus2(x, y)
  integer, intent(in)   :: x
  integer, intent(out)  :: y
  y = x + 2
end subroutine plus2
  • 乘以2.f90
subroutine times2(x, y)
  integer, intent(in)   :: x
  integer, intent(out)  :: y
  y = x * 2
end subroutine times2
  • test_my_project.py
import my_project.mod1
import my_project.oldf90
import my_project.modf90

print("mod1.add:            1 + 2 = ", my_project.mod1.add(1, 2))
print("modf90.funcs_m.add:  1 + 2 = ", my_project.modf90.funcs_m.add(1, 2))
x = 1
x = my_project.oldf90.plus2(x)
print("oldf90.plus2:        1 + 2 = ", x)
x = my_project.oldf90.times2(x)
print("oldf90.plus2:        3 * 2 = ", x)

现在,可以使用pip安装包。与setup.py install相比,使用pip有几个优点(包括易于升级或卸载)(但仍可用于构建用于分发的包!)。从包含setup.py的目录:

> python -m pip install .

然后,测试刚安装的软件包

> python test_my_project.py
mod1.add:            1 + 2 =  3
modf90.funcs_m.add:  1 + 2 =  3
oldf90.plus2:        1 + 2 =  3
oldf90.plus2:        3 * 2 =  6

此设置已在Windows 10(带有ifort)、Ubuntu 18.04(带有gfortran)和MacOS High Sierra(带有gfortran)上测试成功,所有这些都带有Python 3.6.3。

 类似资料:
  • 问题内容: 我正在尝试让一个库在我的c 项目中工作,并且对于不习惯c 的人没有明确的说明 以下链接是我最近来的 它指出以下 还有以下线程指出以下内容 现在从我可以看到的命令是+ ,例如我的文件名是,这是正确的,有人可以澄清一下吗 我目前正在使用以下命令来编译我的文件,但是想包含一个名为.so的文件,例如 问题答案: 现在从我所看到的命令,例如我的文件名是这将是 不,那是不正确的。应该是,即您用来将

  • 我正在为初级操作系统Luna上的Scratch文本编辑器应用程序编写一个扩展。但是对于扩展的创建,文档实际上是不存在的,我不知道在编写了扩展的主要代码之后如何继续。 我已经写了扩展名。我还不能使用或测试它,因为它需要“安装”。我花了几个小时寻找文档,但它们不存在。然而,我在scratchlaunchpad页面上找到了一条评论 通常,您必须生成一个pluginname.so文件,并将其与plugin

  • 问题内容: 我一直在尝试安装配置了以下设置的软件包: 但是,它从PyPi安装XHTML2PDF软件包,而不使用指定的链接。根据输出(我使用进行安装),它要么无法从链接中解析版本(在代码中),要么我没有指定正确的项目名称(在代码中): 如果我在两者中都将版本号添加到程序包()中,它会找到Git链接并且不抱怨它们,但仍从PyPi安装。 我一直在寻找答案已有一段时间,但一直没有找到解决方案。我需要Git

  • 我在AS中有一个带有本机库的项目。我正在尝试使用实验插件(gradle实验:0.6.0-alpha5)来获取. so文件(稍后在System.loadLibrary()中使用它)。但是我不能生成它们。我真的不明白,为什么? 我用这个指令编写了build.gradle。这是: 尝试运行应用程序时出现的错误: java.lang.无法从加载器加载ImageProcdalvik.system.PathC

  • 下面是我的cmakelists.txt文件 cmake_minimum_required(版本3.4.1) find_library(log-lib日志) target_link_libraries(native-lib${log-lib}) 我在中指定了,,因为我想要一个共享的对象库。 但它没有给我so文件。 我错过了什么?

  • 一直以来不会使用C++一直是我心头痛,不过学习Go从某种意义上补偿了我这个遗憾。 比如生成dll一直以来几乎就是C和C++的专利,现在我可以用Go轻松的实现这一点。 下面我使用一个实例来做到这一点,这个是我写的判断jpeg图是不是正向的一个Go的函数 package main import "C" import ( "fmt" "os" SunnyUtil "githu