I am creating a Python wrapper around a C and Fortran library. I would like the code from this C/Fortran library to be compiled by pip, so the user isn't required to install the library themselves before running pip. I currently achieve this using Numpy Distutils, with a setup.py similar to this:
#!/usr/bin/env python
def configuration(parent_package='', top_path=None):
from numpy.distutils.misc_util import Configuration
config = Configuration('name', parent_package, top_path)
f90_src = [<list of .f90 files>]
c_src = [<list of .c files>]
src = c_src + f90_src
config.add_library('libname', sources=src,
extra_f90_compile_args=['-pthread', '-fno-underscoring'])
config.add_extension(name='wrapper_name', sources=['wrapper_name.f90'],
extra_f90_compile_args=['-pthread'], libraries=['libname'],
module_dirs=['build/temp.linux-x86_64-3.7/'])
return config
if __name__ == "__main__":
from numpy.distutils.core import setup
setup(configuration=configuration)
The library contains Fortran modules, so when compiling my wrapper that calls the library (and uses its modules), I need to tell the compiler where to find the modules. That is the module_dirs option. The problem is that I had to hard-code this. Is there a portable and robust way to find the path to this directory instead?
Note that I have to compile the code that I am wrapping using add_library rather than putting it in the sources of add_extension as if I do the latter f2py will try to wrap all of the interfaces in that code, but it uses some features of Fortran that f2py does not support and so compilation fails.
One workaround may be to change the code to use interfaces rather than modules, but the code that I am wrapping is large and it is not feasible to make any such large modifications to it.
The config.get_build_temp_dir() function sounds promising, but raises an error if called in the place where it is needed (saying it has not yet been initialized).