I am looking for the best way to generate a setup.py
file which build my package based on Fortran routines.
Package/Module structure
.
├── CHANGES.txt
├── LICENSE.txt
├── MANIFEST.in
├── README.md
├── PKG
│ ├── __init__.py
│ ├── lib
│ │ ├── __init__.py
│ │ ├── xx.f90
│ │ ├── yy.f90
│ │ ├── gg.py
│ ├── dirA
│ │ ├── __init__.py
│ │ ├── ee.py
│ │ ├── bb.py
├── setup.py
Manual compilation of Fortran's files
In order to generate the Python wrapper and compile the Fortran files, I can do it using the following workflow (in the folder lib):
gfortran -fPIC -Wall -fcheck=all --shared xx.f90 -o xx.o
[1]
and
f2py -c -m yy yy.f90 xx.o
The previous line insures the linking between the shared library xx.o
and the library `yy.f90.
Notice that f2py -c -m xx xx.f90
does not work because of the use of some syntaxes which are not usable with f2py (use of allocatable arguments in subroutines...).
Current setup.py
(not working)
I use the Extension
module of numpy.distutils
:
import os
from numpy.distutils.core import setup, Extension
#
pkgs['PKG'] = 'PKG'
pkgs['PKG.lib'] = 'PKG/lib'
pkgs['PKG.dirA'] = 'PKG/dirA'
#
exts = list()
exts.append(
Extension(name='PKG.lib.yy',
sources=['PKG/lib/yy.f90','PKG/lib/xx.o'],
extra_compile_args=['-g','--backtrace'],
extra_link_args=[],
f2py_options=['--debug-capi']))
###
###
setup(name = 'PKG',
ext_modules = exts,
packages = list(pkgs.keys()),
package_dir = pkgs,
include_package_data=True,
zip_safe=False
)
Question
Is there any way to integrate the building of the shared library in the setup.py
? One solution could be to run manually the line [1] but if possible I want to avoid to use my own syntax in order to use the same gfortran compiler and options used by f2py
.
Finally the solution is to use library
/libraries
arguments in extension and setup:
import os
from numpy.distutils.core import setup, Extension
#
pkgs['PKG'] = 'PKG'
pkgs['PKG.lib'] = 'PKG/lib'
pkgs['PKG.dirA'] = 'PKG/dirA'
#
exts = list()
exts.append(
Extension(name='PKG.lib.yy',
sources=['PKG/lib/yy.f90'],
extra_compile_args=['-g','--backtrace'],
extra_link_args=[],
libraries=['xx'],
f2py_options=['--debug-capi']))
###
###
setup(name = 'PKG',
ext_modules = exts,
packages = list(pkgs.keys()),
package_dir = pkgs,
libraries=['xx',sources=['PKG/lib/xx.f90']],
include_package_data=True,
zip_safe=False
)
Another solution using Configuration
from numpy.distutils.core import setup
from numpy.distutils.misc_util import Configuration
config = Configuration('PKG')
config.packages=['PKG','PKG.lib']
config.add_extension('lib.yy',
sources=['PKG/lib/MeshField2D.f90'],
libraries=['xx'])
config.add_library('xx',
sources=['PKG/lib/xx.f90'])
setup(**config.todict())