Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python软件包setup:setup.py,可自定义以处理封装的fortran_Python_Pip_Fortran_Distutils_Setup.py - Fatal编程技术网

Python软件包setup:setup.py,可自定义以处理封装的fortran

Python软件包setup:setup.py,可自定义以处理封装的fortran,python,pip,fortran,distutils,setup.py,Python,Pip,Fortran,Distutils,Setup.py,我有一个python包要分发。我有软件包设置,可以下载tarball,解压并使用以下工具安装: python setup.py install 这很好用 我还想将这个包上传到PyPi,并使用pip安装它 但是,该包包含f2py包装的fortran,需要在生成时编译它,并将生成的.so文件移动到最终安装文件夹。我不知道如何使用以下方法进行此操作: python3 setup.py sdist 其次是: pip3 install pkg_name_here.tar.gz 原因是当我跑步的时候

我有一个python包要分发。我有软件包设置,可以下载tarball,解压并使用以下工具安装:

python setup.py install
这很好用

我还想将这个包上传到PyPi,并使用pip安装它

但是,该包包含f2py包装的fortran,需要在生成时编译它,并将生成的.so文件移动到最终安装文件夹。我不知道如何使用以下方法进行此操作:

python3 setup.py sdist
其次是:

pip3 install pkg_name_here.tar.gz
原因是当我跑步的时候

python3 setup.py sdist
正在运行自定义命令,其中一部分命令试图将已编译的*so文件移动到尚未创建的安装文件夹中。我使用的代码大纲示例如下:

在我的实例中,custom_command()编译和包装fortran,并将lib文件复制到安装文件夹中

我想知道的是,是否有一种方法可以在安装pip时只运行这些自定义命令?i、 e避免在打包期间运行自定义_命令(),而仅在安装期间运行

更新 根据Pierre de Buyl的建议,我已经取得了一些进展,但仍然没有取得进展

setup.py文件当前看起来像:

 def setup_f90_ext(parent_package='',top_path=''):
    from numpy.distutils.misc_util import Configuration
    from os.path import join

    config = Configuration('',parent_package,top_path)

    tort_src = [join('PackageName/','tort.f90')]
    config.add_library('tort', sources=tort_src,
                          extra_f90_compile_args=['-fopenmp -lgomp -O3'],
                          extra_link_args=['-lgomp'])

    sources = [join('PackageName','f90wrap_tort.f90')]

    config.add_extension(name='',
                          sources=sources,
                          extra_f90_compile_args=['-fopenmp -lgomp -O3'],
                          libraries=['tort'],
                          extra_link_args=['-lgomp'],
                          include_dirs=['build/temp*/'])

    return config

if __name__ == '__main__':

    from numpy.distutils.core import setup
    import subprocess
    import os
    import sys

    version_file = open(os.getcwd()+'/PackageName/'+ 'VERSION')
    __version__ = version_file.read().strip()


    subprocess.call(cmd, shell=True)

    config = {'name':'PackageName',
              'version':__version__,
              'project_description':'Package description',
              'description':'Description',
              'long_description': open('README.txt').read(),#read('README.txt'),
}
    config2 = dict(config,**setup_f90_ext(parent_package='PackageName',top_path='').todict())
    setup(**config2)   
其中,f90wrap_侵权行为.f90是f90wrapped fortran文件,而侵权行为.f90是原始fortran文件

如果我运行该命令两次,该文件将与python setup.py install一起使用

第一次运行
python setup.py install
时,出现以下错误:

    gfortran:f90: ./PackageName/f90wrap_tort.f90
f951: Warning: Nonexistent include directory ‘build/temp*/’ [-Wmissing-include-dirs]
./PackageName/f90wrap_tort.f90:4:8:

     use tort_mod, only: test_node
        1
Fatal Error: Can't open module file ‘tort_mod.mod’ for reading at (1): No such file or directory
compilation terminated.
f951: Warning: Nonexistent include directory ‘build/temp*/’ [-Wmissing-include-dirs]
./PackageName/f90wrap_tort.f90:4:8:

     use tort_mod, only: test_node
        1
Fatal Error: Can't open module file ‘tort_mod.mod’ for reading at (1): No such file or directory
我之所以将
include_dirs=['build/temp*/']
参数放在扩展中,是因为我在运行
python setup.py install
后注意到第一次在那里构建并存储
include_mod

我不明白的是如何正确链接,以便一步完成所有操作


有人能看到我遗漏了什么吗?

在谷歌搜索了一下之后,我建议如下:

  • 使用NumPy的distutils
  • 对普通Fortran文件使用
    add_库
    关键字(见)。这会将Fortran文件构建为库,但不会尝试使用f2py与它们进行接口
  • 使用f90wrap预构建f90包装,将其包含在包存档中,并在扩展中指定这些文件作为源文件
  • 我没有测试整个解决方案,因为它有点费时,但这是SciPy为他们的一些模块所做的,请参阅

    NumPy的文档中有一项已结束

    编辑1:在使用
    include_dirs=['build/temp.linux-x86_64-2.7'])
    config构建之后,我在第一次构建尝试时获得了这个目录结构

    build/lib.linux-x86_64-2.7
    ├── crystal_torture
    │   ├── cluster.py
    │   ├── dist.f90
    │   ├── f90wrap_tort.f90
    │   ├── graph.py
    │   ├── __init__.py
    │   ├── minimal_cluster.py
    │   ├── node.py
    │   ├── node.pyc
    │   ├── pymatgen_doping.py
    │   ├── pymatgen_interface.py
    │   ├── tort.f90
    │   ├── tort.py
    │   └── tort.pyc
    └── crystal_torture.so
    

    您使用什么工具绑定Fortran代码?(f2py、iso_c_binding、其他?)您是否知道NumPy为此目的进行的distutils修改?我使用f2py和f2py-f90wrap。不幸的是,据我所知,Distils扩展无法处理f90wrap部件。路径
    build/temp*
    不是实际路径。如果只有一个这样的临时目录,请从glob import glob添加
    ,然后改用
    include_dirs=glob('build/temp*/')
    。尝试过这个方法后,Pierre也不起作用。如果上面的代码不够清晰,可以从中删除完整的包。仍然不知道如何让它工作……我用
    include\u dirs=['build/temp.linux-x86\u 64-2.7'])构建了它。
    您现在有什么错误?感谢您的发现-看起来很有希望,但我似乎无法让它正常工作。我我更新了帖子,加入了你的建议。太棒了,你说得对。现在我只需要设置一个函数,来计算出任何机器上这个文件夹的名称,我应该很乐意去做。万分感谢!
    build/lib.linux-x86_64-2.7
    ├── crystal_torture
    │   ├── cluster.py
    │   ├── dist.f90
    │   ├── f90wrap_tort.f90
    │   ├── graph.py
    │   ├── __init__.py
    │   ├── minimal_cluster.py
    │   ├── node.py
    │   ├── node.pyc
    │   ├── pymatgen_doping.py
    │   ├── pymatgen_interface.py
    │   ├── tort.f90
    │   ├── tort.py
    │   └── tort.pyc
    └── crystal_torture.so