Python 2.7 带有英特尔Fortran编译器的f2py

Python 2.7 带有英特尔Fortran编译器的f2py,python-2.7,fortran,distutils,intel-fortran,f2py,Python 2.7,Fortran,Distutils,Intel Fortran,F2py,我正在尝试使用f2py将python程序与Fortran模块连接起来 我在Win7平台上 我使用最新的anaconda64(1.7)作为Python+NumPy堆栈 我的Fortran编译器是最新的英特尔Fortran编译器64(版本14.0.0.103构建20130728) 在执行f2py-c-m PyModule FortranModule.f90--fcompiler=intelvem 最后一个,我似乎无法理清的是,传递给编译器的标志f2py/distutils序列似乎与ifort期望的不

我正在尝试使用f2py将python程序与Fortran模块连接起来

我在Win7平台上

我使用最新的anaconda64(1.7)作为Python+NumPy堆栈

我的Fortran编译器是最新的英特尔Fortran编译器64(版本14.0.0.103构建20130728)

在执行
f2py-c-m PyModule FortranModule.f90--fcompiler=intelvem

最后一个,我似乎无法理清的是,传递给编译器的标志f2py/distutils序列似乎与ifort期望的不匹配

当调用ifort时,我会收到一系列关于未知选项的警告消息

ifort: command line warning #10006: ignoring unknown option '/LC:\Anaconda\libs'
ifort: command line warning #10006: ignoring unknown option'/LC:\Anaconda\PCbuild\amd64'
ifort: command line warning #10006: ignoring unknown option '/lpython27'
我怀疑这与我最后从链接器得到的错误有关

error LNK2019: unresolved external symbol __imp_PyImport_ImportModule referenced in function _import_array
error LNK2019... and so forth (there are about 30-40 lines like that, with different python modules missing)
它以一个简单的结尾

fatal error LNK1120: 42 unresolved externals
我猜这是因为选项序列中缺少/link标志。因此,/l/l选项不会传递给链接器,编译器认为这些选项是针对链接器的

f2py生成的ifort命令如下所示:

ifort.exe -dll -dll Pymodule.o fortranobject.o FortranModule.o module-f2pywrappers2.o -LC:\Anaconda\libs -LC:\Anaconda\PCbuild\amd64 -lPython27
我不知道为什么“-dll”会重复两次(我不得不将该标志从原来的“-shared”更改为“shared”)

现在,我已经尝试研究了f2py和distutils代码,但还没有找到如何在命令输出中添加一个额外的/链接。我甚至无法找到这个输出是在哪里生成的

如果有人在过去遇到过这个问题和/或可能有一些建议,我将非常感谢


感谢您抽出时间

库路径是使用/LIBPATH而不是/L指定的

我不久前在自己的代码中遇到了类似的问题。如果我正确理解了这些评论,您已经使用了对我有效的方法,因此这只是对所有与f2py和依赖性相关的人的澄清和总结:

f2py似乎在解决依赖外部源文件的问题时遇到问题。但是,如果外部依赖项作为已编译的对象文件传递给f2py,则链接工作正常,python库的构建不会出现问题

因此,最简单的解决方案似乎是:

  • 使用首选的编译器和编译器设置将所有依赖项编译为对象文件(*.o)
  • 将所有对象文件与主子程序/函数/模块的源文件一起传递到f2py
  • 按预期使用生成的python库
  • 一个简单的python脚本可以如下所示(pycompile.py):

    使用修改的pycompile:

    #!python.exe
    # -*- coding: UTF-8 -*-
    ...
    fortran_source = ("@source_root@/source_1.f90 "
                      "@source_root@/source_2.f90 "                 
                      "...")
    ...
    # add path to source code/ dependencies
    f2py_source = ("-m for_to_py_lib "
                   "@build_root@/for_to_py.f90 "
                   "source_1.o "
                   "source_2.o "
                   "... "
                   )
    ...
    
    # compile .o and .mod files
    ...
    

    我遇到过这样的问题,但不幸的是,我找不到解决这些问题的办法;我最终制作了一个Makefile,把所有的东西拼凑在一起。这是Makefile:。谢谢你的文件!我今天才有机会看这个。由于要获取大量路径和各种文件,要让它工作起来是一件非常痛苦的事情。但是,最终我能做我想做的事。我认为最终的答案是非常棘手的,因为它似乎高度依赖于安装的平台和工具链。那么你最终的方法是什么?你有没有设法让distutils提交?没有。破解你的makefile要容易得多。。。在接下来的几周里,我可能会再次尝试distutils。如果我发现有用的东西,我一定会告诉你的。有点晚了,但是。。。库路径是使用/LIBPATH而不是/LThanks指定的。很抱歉反馈太晚,我没有注意到2月份的评论。。。这并不能真正回答问题。事实上,对于ifort,它应该是/libdir。真正的问题是“如何更改dist utils生成编译器参数列表的方式?”。目前,bdforbes使用makefile的解决方案是可行的,但如果f2py能够处理整个问题就好了。
    ###############################################################################
    # General project properties
    ################################################################################
    # Set Project Name
    project (for_to_py_lib)
    # Set Version Number
    set (for_to_py_lib_VERSION_MAJOR 1)
    set (for_to_py_lib_VERSION_MINOR 0)
    # save folder locations for later use/ scripting (see pycompile.py)
    # relative to SOURCE folder
    set(source_root ${CMAKE_CURRENT_LIST_DIR}/SOURCE) # save top level source dir for later use
    set(lib_root ${CMAKE_CURRENT_LIST_DIR}/LIBRARIES) # save top level lib dir for later use
    # relative to BUILD folder
    set(build_root ${CMAKE_CURRENT_BINARY_DIR}) # save top level build dir for later use
    
    ###
    ### Fortran to Python library
    ###
    find_package(PythonInterp)
    if (PYTHONINTERP_FOUND)
        # copy python compile skript file to build folder and substitute CMake variables
        configure_file(${source_root}/pycompile.py ${build_root}/pycompile.py @ONLY)
        # define for_to_py library ending
        if (UNIX)
            set(CMAKE_PYTHON_LIBRARY_SUFFIX .so)
        elseif (WIN32)
            set(CMAKE_PYTHON_LIBRARY_SUFFIX .pyd)
        endif()
        # add custom target to ALL, building the for_to_py python library (using f2py)
        add_custom_target(for_to_py ALL
                          DEPENDS ${build_root}/for_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX})
        # build command for python library (execute python script pycompile.py containing the actual build commands)
        add_custom_command(OUTPUT ${build_root}/for_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX}
                           COMMAND ${PYTHON_EXECUTABLE} ${build_root}/pycompile.py
                           WORKING_DIRECTORY ${build_root}
                           DEPENDS ${build_root}/pycompile.py
                                   ${source_root}/path/to/source_1.f90
                                   ${source_root}/path/to/source_2.f90
                                   ${source_root}/INOUT/s4binout.f90
                           COMMENT "Generating fortran to python library")
        # post build command for python library (copying of generated files)
        add_custom_command(TARGET for_to_py
                           POST_BUILD
                           COMMAND ${CMAKE_COMMAND} -E copy_if_different 
                                   ${build_root}/s4_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX}
                                   ${lib_root}/for_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX}
                           COMMENT "\
    ***************************************************************************************************\n\
     copy of python library for_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX} placed in ${lib_root}/for_to_py${CMAKE_PYTHON_LIBRARY_SUFFIX} \n\
    ***************************************************************************************************"
                           )
    endif (PYTHONINTERP_FOUND)
    
    #!python.exe
    # -*- coding: UTF-8 -*-
    ...
    fortran_source = ("@source_root@/source_1.f90 "
                      "@source_root@/source_2.f90 "                 
                      "...")
    ...
    # add path to source code/ dependencies
    f2py_source = ("-m for_to_py_lib "
                   "@build_root@/for_to_py.f90 "
                   "source_1.o "
                   "source_2.o "
                   "... "
                   )
    ...
    
    # compile .o and .mod files
    ...