F2py With Intel Fortran Compiler
Solution 1:
I encountered similar problems with my own code some time ago. If I understand the comments correctly you already used the approach that worked for me, so this is just meant as clarification and summary for all those that struggle with f2py and dependencies:
f2py seems to have problems resolving dependecies on external source files. If the external dependencies get passed to f2py as already compiled object files though, the linking works fine and the python library gets build without problems.
The easiest solution therefore seems to be:
- compile all dependencies to object files (*.o) using your prefered compiler and compiler settings
- pass all object files to f2py, together with the source file of your main subroutine/ function/ module/ ...
- use generated python library as expected
A simple python skript could look like this (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/ Windowsif (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 filesprint"compiling object- and module-files..."printprint fortran_cmd
os.system(fortran_cmd)
# compile main_source.f90 with f2pyprint"================================================================"print"start f2py..."printprint f2py_cmd
os.system(f2py_cmd)
A more flexible solution for large projects could be provided via Makefile, as dicussed by @bdforbes in the comments (for reference) or a custom CMake User Command in combination with the above skript:
################################################################################ General project properties################################################################################# Set Project Name
project (for_to_py_lib)
# Set Version Numberset (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 folderset(source_root ${CMAKE_CURRENT_LIST_DIR}/SOURCE) # save top level source dir for later useset(lib_root ${CMAKE_CURRENT_LIST_DIR}/LIBRARIES) # save top level lib dir for later use# relative to BUILD folderset(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 endingif (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)
with modified 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
...
Solution 2:
The library path is specified using /LIBPATH not /L
Post a Comment for "F2py With Intel Fortran Compiler"