Skip to content

Commit

Permalink
Merge pull request #62 from GEOS-ESM/feature/mathomp4/f2py-and-latex-…
Browse files Browse the repository at this point in the history
…cmake-fixes

Fixes for f2py and imagemagick
  • Loading branch information
mathomp4 authored Mar 25, 2020
2 parents df6e079 + c07c9f9 commit d8ae41e
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 29 deletions.
75 changes: 75 additions & 0 deletions FindF2PY.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# MAT This code is based, loosely, on the FindF2PY.cmake file from scikit
#.rst:
#
# The purpose of the F2PY –Fortran to Python interface generator– project is to provide a
# connection between Python and Fortran languages.
#
# F2PY is a Python package (with a command line tool f2py and a module f2py2e) that facilitates
# creating/building Python C/API extension modules that make it possible to call Fortran 77/90/95
# external subroutines and Fortran 90/95 module subroutines as well as C functions; to access Fortran
# 77 COMMON blocks and Fortran 90/95 module data, including allocatable arrays from Python.
#
# For more information on the F2PY project, see http://www.f2py.com/.
#
# The following variables are defined:
#
# ::
#
# F2PY_EXECUTABLE - absolute path to the F2PY executable
#
# ::
#
# F2PY_VERSION_STRING - the version of F2PY found
# F2PY_VERSION_MAJOR - the F2PY major version
# F2PY_VERSION_MINOR - the F2PY minor version
# F2PY_VERSION_PATCH - the F2PY patch version
#
#
# .. note::
#
# By default, the module finds the F2PY program associated with the installed NumPy package.
#

# Path to the f2py executable
find_package(Python COMPONENTS Interpreter)

find_program(F2PY_EXECUTABLE NAMES "f2py${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}"
"f2py-${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}"
"f2py${Python_VERSION_MAJOR}"
"f2py"
)

if(F2PY_EXECUTABLE)
# extract the version string
execute_process(COMMAND "${F2PY_EXECUTABLE}" -v
OUTPUT_VARIABLE F2PY_VERSION_STRING
OUTPUT_STRIP_TRAILING_WHITESPACE)
if("${F2PY_VERSION_STRING}" MATCHES "^([0-9]+)(.([0-9+]))?(.([0-9+]))?$")
set(F2PY_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(F2PY_VERSION_MINOR "${CMAKE_MATCH_3}")
set(F2PY_VERSION_PATCH "${CMAKE_MATCH_5}")
endif()

# Now we need to test if we can actually use f2py and what its suffix is

include(try_f2py_compile)
try_f2py_compile(
${CMAKE_CURRENT_LIST_DIR}/check_compiler_support/test.F90
DETECT_F2PY_SUFFIX
)

endif ()

# handle the QUIET and REQUIRED arguments and set F2PY_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(F2PY
REQUIRED_VARS F2PY_EXECUTABLE F2PY_SUFFIX
VERSION_VAR F2PY_VERSION_STRING
)

mark_as_advanced(F2PY_EXECUTABLE F2PY_SUFFIX)

if (F2PY_FOUND)
include(UseF2Py)
endif ()
29 changes: 3 additions & 26 deletions UseF2Py.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,6 @@
# | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
# +-----------------------------------------------------------------------------+

find_package(PythonInterp REQUIRED)

if (NOT F2PY_SUFFIX)
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX') or sysconfig.get_config_var('SO'))"
OUTPUT_VARIABLE PYTHON_EXT_SUFFIX
RESULT_VARIABLE FOUND_PYTHON_EXT_SUFFIX
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (NOT FOUND_PYTHON_EXT_SUFFIX EQUAL 0)
set (F2PY_SUFFIX "" CACHE STRING "Suffix added by F2Py to the module name to get the output file name." )
message(FATAL_ERROR "Unable to determine file extension of compiled Python modules - specify it with F2PY_SUFFIX")
endif (NOT FOUND_PYTHON_EXT_SUFFIX EQUAL 0)

set (F2PY_SUFFIX "${PYTHON_EXT_SUFFIX}" CACHE INTERNAL "f2py suffix")
message(STATUS "Setting F2PY_SUFFIX to ${F2PY_SUFFIX}")
endif (NOT F2PY_SUFFIX)

## Path to the f2py executable
find_program(F2PY_EXECUTABLE NAMES "f2py${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}"
"f2py-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}"
"f2py${PYTHON_VERSION_MAJOR}"
"f2py"
REQUIRED)

## -----------------------------------------------------------------------------
## Macro to generate a Python interface module from one or more Fortran sources
##
Expand Down Expand Up @@ -153,18 +130,18 @@ macro (add_f2py_module _name)
add_custom_command(OUTPUT "${_name}${F2PY_SUFFIX}"
COMMAND ${F2PY_EXECUTABLE} --quiet -m ${_name}
--build-dir "${CMAKE_CURRENT_BINARY_DIR}/f2py-${_name}"
${_fcompiler_opts} ${_inc_opts} -c ${_abs_srcs}
${_fcompiler_opts} ${_inc_opts} -c ${_abs_srcs} &> /dev/null
DEPENDS ${add_f2py_module_SOURCES}
COMMENT "[F2PY] Building Fortran to Python interface module ${_name}")
else ( "${add_f2py_module_SOURCES}" MATCHES "^[^;]*\\.pyf;" )
add_custom_command(OUTPUT "${_name}${F2PY_SUFFIX}"
COMMAND ${F2PY_EXECUTABLE} --quiet -m ${_name} -h ${_name}.pyf
--build-dir "${CMAKE_CURRENT_BINARY_DIR}/f2py-${_name}"
--include-paths ${_inc_paths} --overwrite-signature ${_abs_srcs}
--include-paths ${_inc_paths} --overwrite-signature ${_abs_srcs} &> /dev/null
COMMAND ${F2PY_EXECUTABLE} --quiet -m ${_name}
--build-dir "${CMAKE_CURRENT_BINARY_DIR}/f2py-${_name}"
-c "${CMAKE_CURRENT_BINARY_DIR}/f2py-${_name}/${_name}.pyf"
${_fcompiler_opts} ${_inc_opts} ${_lib_opts} ${_abs_srcs} ${_lib_opts}
${_fcompiler_opts} ${_inc_opts} ${_lib_opts} ${_abs_srcs} ${_lib_opts} &> /dev/null
DEPENDS ${add_f2py_module_SOURCES}
COMMENT "[F2PY] Building Fortran to Python interface module ${_name}")
endif ( "${add_f2py_module_SOURCES}" MATCHES "^[^;]*\\.pyf;" )
Expand Down
3 changes: 3 additions & 0 deletions check_compiler_support/test.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
subroutine test
real x
end subroutine test
39 changes: 39 additions & 0 deletions check_compiler_support/try_f2py_compile.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Used to determine whether compiler is able to compile and/or run a
# given snippet of source. Useful for compiler bug workarounds and
# unsupported features.

macro (try_f2py_compile file var)

if (NOT CMAKE_REQUIRED_QUIET)
message (STATUS "Performing Test ${var}")
endif ()

set( _f2py_check_bindir "${CMAKE_BINARY_DIR}/f2py_tmp")
file(MAKE_DIRECTORY ${_f2py_check_bindir})

execute_process(
COMMAND ${F2PY_EXECUTABLE} -m test_ -c ${file}
WORKING_DIRECTORY ${_f2py_check_bindir}
RESULT_VARIABLE result
OUTPUT_QUIET
ERROR_QUIET
)

if (result EQUAL 0)
file(GLOB F2PY_TEST_OUTPUT_FILE ${_f2py_check_bindir}/*.so)

get_filename_component(F2PY_FOUND_EXTENSION ${F2PY_TEST_OUTPUT_FILE} EXT)

set(F2PY_SUFFIX ${F2PY_FOUND_EXTENSION} CACHE STRING "f2py suffix")
message(STATUS "Setting F2PY_SUFFIX to ${F2PY_SUFFIX}")
if (NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Performing Test ${var}: SUCCESS")
endif ()
else ()
if (NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Performing Test ${var}: FAILURE")
endif ()
message(WARNING "Test f2py compile using ${F2PY_EXECUTABLE} failed. F2PY modules will not be built. This usually indicates an incomplete Python/numpy installation.")
endif ()

endmacro (try_f2py_compile)
18 changes: 15 additions & 3 deletions esma.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,20 @@ include (esma_generate_automatic_code)
include (esma_create_stub_component)
include (esma_fortran_generator_list)

find_package(ImageMagick)
if (NOT ImageMagick_FOUND)
message(STATUS "NOTE: ImageMagick was not found. This will prevent using LaTeX and some postprocessing utilities from running, but does not affect the build")
endif ()

find_package(LATEX)
# These are all the bits of LaTeX that UseLatex needs. As it's confusing how LATEX_FOUND from
# find_package(LATEX) is set, we test all the bits that UseLatex requires
if (LATEX_FOUND AND LATEX_PDFLATEX_FOUND AND LATEX_BIBTEX_FOUND AND LATEX_MAKEINDEX_FOUND)
# These are all the bits of LaTeX that UseLatex needs. As it's confusing
# how LATEX_FOUND from find_package(LATEX) is set, we test all the bits
# that UseLatex requires
#
# Also, UseLatex assumes ImageMagick is installed. While this is always
# nice (and technically required to generate plots with GEOS plotting
# utilities, it's not necessary to *build*
if (LATEX_FOUND AND LATEX_PDFLATEX_FOUND AND LATEX_BIBTEX_FOUND AND LATEX_MAKEINDEX_FOUND AND ImageMagick_FOUND)
# If they are all found, set LATEX_FOUND to TRUE...
set (LATEX_FOUND TRUE)

Expand Down Expand Up @@ -94,3 +104,5 @@ macro (esma)
endmacro ()

find_package(GitInfo)

find_package(F2PY)

0 comments on commit d8ae41e

Please sign in to comment.