在Windows 10上使用f2py和Python 3.6编译fortran模块

dsh*_*les 4 mingw f2py anaconda windows-10 python-3.6

我正在尝试(并且失败)在Windows 10上使用f2py和Python 3.6 编译fortran模块(特别来自BGS的igrf12.f).使用Anaconda 4.4.10安装Python.

我的设置:

  • Python 3.6.3 | Anaconda自定义(64位)| (默认情况下,2017年10月15日,03:27:45)[MSC v.1900 64位(AMD64)]在win32上
  • Windows 10企业版(1703版)
  • NumPy 1.14.0

我按照SciPy文档中的 f2py指示和Dr.Michael Hirsch 的非常有用的指导.Dr.Hirsch创建了pyigrf12模块,但是通过pip安装失败了,这最初引起了我对f2py的兴趣.

我将概述我正在使用的一些方法.无论方法如何,我总是首先使用f2py igrf12.f -m pyigrf12 -h igrf12.pyf并适当地添加intent(in/out)属性来创建*.pyf签名文件.

  • 方法1:使用C:\ MinGW和 --compiler=mingw32
  • 方法2:使用C:\ MinGW和 --compiler=msvc
  • 方法3:使用anaconda版本的mingw和 --compiler=mingw32
  • 方法4:使用anaconda版本的mingw和 --compiler=msvc

方法1:

对于后台,我在C:\ MinGW有MinGW,我已将C:\ MinGW\bin添加到我的用户Path.不幸的是,我没有安装这个版本的MinGW(我从同事那里继承了这台电脑),所以我不知道它的来源.gcc --version和gfortran --version是5.3.0.

我跑f2py -c igrf12.pyf igrf12.f --compiler=mingw32.此失败并显示以下错误消息:

Building import library (arch=AMD64):
"C:\Users\Sholes\AppData\Local\Continuum\anaconda3\libs\libpython36.a" 
(from C:\Users\Sholes\AppData\Local\Continuum\anaconda3\python36.dll)
    objdump.exe: C:\Users\Sholes\AppData\Local\Continuum\anaconda3\python36.dll: File format not recognized

Traceback (most recent call last):
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\Scripts\\f2py.py", line 28, in <module>
    main()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\f2py\f2py2e.py", line 648, in main
    run_compile()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\f2py\f2py2e.py", line 633, in run_compile
    setup(ext_modules=[ext])
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\core.py", line 169, in setup
    return old_setup(**new_attr)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\core.py", line 148, in setup
    dist.run_commands()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 955, in run_commands
    self.run_command(cmd)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 974, in run_command
    cmd_obj.run()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\command\build.py", line 47, in run
    old_build.run(self)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\command\build.py", line 135, in run
    self.run_command(cmd_name)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\cmd.py", line 313, in run_command
    self.distribution.run_command(command)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 974, in run_command
    cmd_obj.run()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\command\build_ext.py", line 117, in run
    force=self.force)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\ccompiler.py", line 733, in new_compiler
    compiler = klass(None, dry_run, force)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 104, in __init__
    build_import_library()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 416, in build_import_library
    return _build_import_library_amd64()
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 472, in _build_import_library_amd64
    generate_def(dll_file, def_file)
  File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 302, in generate_def
    raise ValueError("Symbol table not found")
ValueError: Symbol table not found
Run Code Online (Sandbox Code Playgroud)

该问题似乎涉及从python36.dll构建libpython36.a.

在快速谷歌搜索之后,github论坛上关于pywafo的建议是使用msvc编译器而不是mingw32,导致方法2.

方法2: 对于后台,将从中提取与我的msvc相关的文件C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX86\x64\.不确定这是否有帮助.

我跑f2py -c igrf12.pyf igrf12.f --compiler=msvc.这会产生两个文件:

  • pyigrf12.cp36-win_amd64.pyd 在我当前的工作目录中,
  • libigrf12.BMWM6WD5Y3O3UTOEQITBXCIICXVMBEZS.gfortran-win_amd64.dll.\UNKNOWN\.libs\

当我尝试时import pyigrf12,首先我收到ImportError: DLL load failed: The specified module could not be found.Using Dependency Walker,我收到很多错误:

f2py依赖步行者输出

但最明显的要解决的问题是libigrf12.BMWM6WD5Y3O3UTOEQITBXCIICXVMBEZS.gfortran-win_amd64.dll.我把这个libigrf12 dll文件移到我当前的工作目录旁边pyigrf12.cp36-win_amd64.pyd.

现在,当我尝试时import pyigrf12,我收到了ImportError: DLL load failed: %1 is not a valid Win32 application..一些stackoverflow帖子似乎表明这是一个32位DLL和64位Python之间的冲突问题.谁能提供这方面的见解?经过更多的搜索,我决定尝试使用anaconda版本的mingw和libpython.

方法3:

我跑了conda install mingw libpython,它安装了mingw 4.7-1和libpython 2.1-py36_0.我运行f2py -c igrf12.pyf igrf12.f --compiler=mingw32,它失败,出现以下错误消息:

Building msvcr library: 
"C:\Users\Sholes\AppData\Local\Continuum\anaconda3\libs\libvcruntime140.a" 
(from C:\Users\Sholes\AppData\Local\Continuum\anaconda3\vcruntime140.dll)
    objdump.exe: C:\Users\Sholes\AppData\Local\Continuum\anaconda3\vcruntime140.dll: File format not recognized
    Traceback (most recent call last):
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\Scripts\\f2py.py", line 28, in <module>
        main()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\f2py\f2py2e.py", line 648, in main
        run_compile()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\f2py\f2py2e.py", line 633, in run_compile
        setup(ext_modules=[ext])
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\core.py", line 169, in setup
        return old_setup(**new_attr)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\core.py", line 148, in setup
        dist.run_commands()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 955, in run_commands
        self.run_command(cmd)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 974, in run_command
        cmd_obj.run()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\command\build.py", line 47, in run
        old_build.run(self)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\command\build.py", line 135, in run
        self.run_command(cmd_name)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\cmd.py", line 313, in run_command
        self.distribution.run_command(command)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\distutils\dist.py", line 974, in run_command
        cmd_obj.run()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\command\build_ext.py", line 117, in run
        force=self.force)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\ccompiler.py", line 733, in new_compiler
        compiler = klass(None, dry_run, force)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 107, in __init__
        msvcr_success = build_msvcr_library()
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 399, in build_msvcr_library
        generate_def(dll_file, def_file)
      File "C:\Users\Sholes\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\distutils\mingw32ccompiler.py", line 302, in generate_def
        raise ValueError("Symbol table not found")
    ValueError: Symbol table not found
Run Code Online (Sandbox Code Playgroud)

现在问题似乎与从vcruntime140.dll构建libvcruntime140.a有关.objdump.exe无法识别dll文件格式.

方法4:

我的最后一次尝试是f2py -c igrf12.pyf igrf12.f --compiler=msvc安装了anaconda版本的mingw.对于这种情况,gfortran失败了这个错误:

   C:\Users\Sholes\AppData\Local\Continuum\anaconda3\Scripts\gfortran.bat -Wall -g -Wall -g -shared 
..\..\..\AppData\Local\Temp\tmpugo__0q9\Release\igrf12.o -Lc:\users\sholes\appdata\local\continuum\anaconda3\mingw\lib\gcc\x86_64-w64-mingw32\4.7.0 -LC:\Users\Sholes\AppData\Local\Continuum\anaconda3\libs -LC:\Users\Sholes\AppData\Local\Continuum\anaconda3\PCbuild\amd64 -o C:\Users\Sholes\AppData\Local\Temp\tmpugo__0q9\Release\extra-dll\libigrf12.75XJA5DX6DTO7YIZ7X6ZHJYTRDCCYQYR.gfortran-win_amd64.dll -Wl,--allow-multiple-definition -Wl,--output-def,C:\Users\Sholes\AppData\Local\Temp\tmpugo__0q9\Release\libigrf12.75XJA5DX6DTO7YIZ7X6ZHJYTRDCCYQYR.gfortran-win_amd64.def -Wl,--export-all-symbols -Wl,--enable-auto-import -static -mlong-double-64

gfortran.exe: error: unrecognized command line option '-mlong-double-64'
Run Code Online (Sandbox Code Playgroud)

此时,我只想知道是否可以使用我的设置和f2py创建fortran扩展.我没有在Windows上编译C或Fortran扩展的任何后台,并且基于与Windows上的Python 3.6 scipy和numpy安装问题相关的所有问题,似乎这是一个没有简单解决方案的常见问题.

任何反馈或见解将不胜感激.

dsh*_*les 6

终于搞定了这个.

精简版:

确保为64位Python使用64位编译器(对mingw-w64进行三重检查).不像f2pyWindows 上的newb 那样明显.

长版:

我卸载了我现有的MinGW的(我怀疑这是一个32位版本)的副本,而是下载的特定64位编译从SourceForge的MinGW-W64 7.2.0,具体x86_64-7.2.0-release-posix-seh-rt_v5-rev1.7z.这个stackoverflow问题很有用.

我解压缩并将"mingw64"文件夹复制到我的C:驱动器(C:\mingw64)中.我添加C:\mingw64\bin到我的用户路径.

我卸载了anaconda版本的MinGW conda uninstall mingw.请注意,只有在您之前安装过MinGW时才需要这样做conda.

运行时f2py -c igrf12.pyf igrf12.f --compiler=mingw32(与igrf12.pyf在同一目录中,请参阅Scipy文档以了解如何生成*.pyf文件),pyigrf12.cp36-win_amd64.pyd创建时没有任何错误.我终于可以import pyigrf12成功访问底层的Fortran子程序(例如igrf12syn).

注意,我也可以f2py -c igrf12.pyf igrf12.f --compiler=msvc成功运行,但是我必须手动将libigrf12....gfortran-win_amd64.dll(生成的.\UNKNOWN\.libs\)复制并粘贴到同一目录中,pyigrf12.cp36-win_amd64.pyd以避免ImportError: DLL load failed: The specified module could not be found.在我的问题的方法2中提到.

重新迭代:确保 C:\mingw64\bin 添加到您的路径中!

顺便说一句,f2py在macOS Sierra和Ubuntu上对我来说是无痛的.如果上述内容仍然不适合您,我建议您尝试Linux,MacOS或Windows子系统Linux.