2013-10-11 554 views
6

我正在尝试使用f2py来将我的python程序与我的Fortran模块进行接口。f2py与英特尔Fortran编译器

我在Win7平台上。

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

我的Fortran编译器是最新的英特尔Fortran编译器64(版本14.0.0.103 Build 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”)。

现在,我试图查看f2py和distutils代码,但还没有想出如何在命令输出中追加/链接。我甚至无法找到产生这个输出的地方。

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

谢谢您的时间

+1

我遇到像这些问题,但不幸的是我无法找到解决方法;我最终制作了一个将所有东西拼凑在一起的Makefile。这里是Makefile:http://pastebin.com/ChSxLzSb。 – bdforbes

+0

感谢您的文件!今天我才有机会看到这一点。由于大量的路径摆弄和各种文件的获取,最终导致它成为一个巨大的痛苦。但是,最终我能够做到我想要的。我认为提出最终答案非常棘手,因为它似乎高度依赖于安装的平台和工具链。 – Tesla

+0

那么你最后的做法是什么?你有没有设法破解distutils提交? – bdforbes

回答

0

库路径被指定使用/不LIBPATH/L

+0

谢谢。对于迟到的反馈,抱歉,我没有注意到二月的评论......这并没有真正回答这个问题。事实上,对于ifort,它将是/ libdir。 真正的问题是“你如何改变dist-utils生成编译器参数列表的方式?”。目前,bdforbes使用makefile的解决方案很有效,但如果f2py可以处理整个事情,那就好了。 – Tesla

3

我前一段时间遇到了类似的问题,我自己的代码。如果我正确理解了这些注释,那么您已经使用了适用于我的方法,所以这仅仅是对所有与f2py和依赖关系相关的人的澄清和总结:

f2py似乎在解决对外部源文件。如果外部依赖作为已编译的目标文件传递给f2py,链接工作正常,并且python库的构建没有问题。

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

  1. 编译所有依赖于目标文件(*。O)使用您喜欢的编译器和编译器设置
  2. 通所有的目标文件f2py,连同你的主要的子程序/功能/模块的源文件/...
  3. 使用产生的Python库预期

一个简单的Python skript可能看起来像这样(pycompile.py):

#!python.exe 
# -*- coding: UTF-8 -*- 
import os 
import platform 
'''Uses f2py to compile needed library''' 
# build command-strings 
# command for compling *.o and *.mod files 
fortran_exe = "gfortran " 
# fortran compiler settings 
fortran_flags = "<some_gfortran_flags> " 
# add path to source code 
fortran_source = ("./relative/path/to/source_1.f90 " 
        "C:/absolut/path/to/source_2.f90 "     
        "...") 
# assemble fortran command 
fortran_cmd = fortran_exe + fortran_flags + fortran_source 

# command for compiling main source file using f2py 
f2py_exe = "f2py -c " 
# special compiler-options for Linux/ Windows 
if (platform.system() == 'Linux'): 
    f2py_flags = "--compiler=unix --fcompiler=gnu95 " 
elif (platform.system() == 'Windows'): 
    f2py_flags = "--compiler=mingw32 --fcompiler=gnu95 " 
# add path to source code/ dependencies 
f2py_source = ("-m for_to_py_lib " 
       "./path/to/main_source.f90 " 
       "source_1.o " 
       "source_2.o " 
       "... " 
       ) 
# assemble f2py command 
f2py_cmd = f2py_exe + f2py_flags + f2py_source 

# compile .o and .mod files 
print "compiling object- and module-files..." 
print 
print fortran_cmd 
os.system(fortran_cmd) 
# compile main_source.f90 with f2py 
print "================================================================" 
print "start f2py..." 
print 
print f2py_cmd 
os.system(f2py_cmd) 

为l一个更灵活的解决方案ARGE项目可以通过生成文件来提供,如由@bdforbes在评论(for reference)或自定义的CMake用户命令在结合上述skript dicussed:

############################################################################### 
# 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) 

具有修饰pycompile:

#!python.exe 
# -*- coding: UTF-8 -*- 
... 
fortran_source = ("@[email protected]/source_1.f90 " 
        "@[email protected]/source_2.f90 "     
        "...") 
... 
# add path to source code/ dependencies 
f2py_source = ("-m for_to_py_lib " 
       "@[email protected]/for_to_py.f90 " 
       "source_1.o " 
       "source_2.o " 
       "... " 
       ) 
... 

# compile .o and .mod files 
... 
相关问题