Skip to content
Snippets Groups Projects
Commit baa8c5a4 authored by Franck Pérignon's avatar Franck Pérignon
Browse files

CMake for MPI fortran compilers

parent db599f8d
No related branches found
No related tags found
No related merge requests found
# - Message Passing Interface (MPI) module for Fortran
#
# This module will set the following variables:
# MPI_Fortran_FOUND TRUE if we have found MPI
# MPI_Fortran_COMPILE_FLAGS Compilation flags for MPI programs
# MPI_Fortran_INCLUDE_PATH Include path(s) for MPI header
# MPI_Fortran_LINK_FLAGS Linking flags for MPI programs
# MPI_Fortran_LIBRARY First MPI library to link against (cached)
# MPI_Fortran_EXTRA_LIBRARY Extra MPI libraries to link against (cached)
# MPI_Fortran_LIBRARIES All libraries to link MPI programs against
#
# F. Pérignon - LJK, Grenoble - march 2011.
# Inspired from original Kitware FindMPI.cmake (only for C/C++ MPI)
#
# If mpiexec is not set, that means MPI has not been searched. Forced it
if(NOT MPIEXEC)
find_package(MPI REQUIRED)
message(STATUS "search MPI ...")
endif(NOT MPIEXEC)
set(_MPI_PREFIX_PATH)
if(WIN32)
list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/..")
list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]")
endif()
foreach(SystemPrefixDir ${CMAKE_SYSTEM_PREFIX_PATH})
foreach(MpiPackageDir ${_MPI_PREFIX_PATH})
if(EXISTS ${SystemPrefixDir}/${MpiPackageDir})
list(APPEND _MPI_PREFIX_PATH "${SystemPrefixDir}/${MpiPackageDir}")
endif()
endforeach(MpiPackageDir)
endforeach(SystemPrefixDir)
# call get_filename_component twice to remove mpiexec and the directory it exists in (typically bin).
# This gives us a fairly reliable base directory to search for /bin /lib and /include from.
get_filename_component(_MPI_BASE_DIR "${MPIEXEC}" PATH)
get_filename_component(_MPI_BASE_DIR "${_MPI_BASE_DIR}" PATH)
# If there is an mpi compiler find it and interogate (farther below) it for the include
# and lib dirs otherwise we will continue to search from ${_MPI_BASE_DIR}.
find_program(MPI_Fortran_COMPILER
NAMES mpif90 mpif77
HINTS "${_MPI_BASE_DIR}"
PATH_SUFFIXES bin
DOC "MPI compiler. Used only to detect MPI compilation flags.")
mark_as_advanced(MPI_COMPILER)
if (MPI_Fortran_INCLUDE_PATH AND MPI_Fortran_LIBRARY)
# Do nothing: we already have MPI_Fortran_INCLUDE_PATH and MPI_Fortran_LIBRARY in
# the cache, and we don't want to override those settings.
elseif (MPI_Fortran_COMPILER)
# Check whether the -showme:compile option works. This indicates
# that we have either Open MPI or a newer version of LAM-MPI, and
# implies that -showme:link will also work.
# Note that Windows distros do not have an mpi compiler to interogate.
exec_program(${MPI_Fortran_COMPILER}
ARGS -showme:compile
OUTPUT_VARIABLE MPI_Fortran_COMPILE_CMDLINE
RETURN_VALUE MPI_Fortran_COMPILER_RETURN)
if (MPI_Fortran_COMPILER_RETURN EQUAL 0)
# If we appear to have -showme:compile, then we should also have
# -showme:link. Try it.
exec_program(${MPI_Fortran_COMPILER}
ARGS -showme:link
OUTPUT_VARIABLE MPI_Fortran_LINK_CMDLINE
RETURN_VALUE MPI_Fortran_COMPILER_RETURN)
# Note that we probably have -showme:incdirs and -showme:libdirs
# as well.
set(MPI_Fortran_COMPILER_MAY_HAVE_INCLIBDIRS TRUE)
endif (MPI_Fortran_COMPILER_RETURN EQUAL 0)
if (MPI_Fortran_COMPILER_RETURN EQUAL 0)
# Do nothing: we have our command lines now
else (MPI_Fortran_COMPILER_RETURN EQUAL 0)
# Older versions of LAM-MPI have "-showme". Try it.
exec_program(${MPI_Fortran_COMPILER}
ARGS -showme
OUTPUT_VARIABLE MPI_Fortran_COMPILE_CMDLINE
RETURN_VALUE MPI_Fortran_COMPILER_RETURN)
endif (MPI_Fortran_COMPILER_RETURN EQUAL 0)
if (MPI_Fortran_COMPILER_RETURN EQUAL 0)
# Do nothing: we have our command lines now
else (MPI_Fortran_COMPILER_RETURN EQUAL 0)
# MPICH uses "-show". Try it.
exec_program(${MPI_Fortran_COMPILER}
ARGS -show
OUTPUT_VARIABLE MPI_Fortran_COMPILE_CMDLINE
RETURN_VALUE MPI_Fortran_COMPILER_RETURN)
endif (MPI_Fortran_COMPILER_RETURN EQUAL 0)
if (MPI_Fortran_COMPILER_RETURN EQUAL 0)
# We have our command lines, but we might need to copy
# MPI_COMPILE_CMDLINE into MPI_LINK_CMDLINE, if the underlying
if (NOT MPI_Fortran_LINK_CMDLINE)
SET(MPI_Fortran_LINK_CMDLINE ${MPI_Fortran_COMPILE_CMDLINE})
endif (NOT MPI_Fortran_LINK_CMDLINE)
else (MPI_Fortran_COMPILER_RETURN EQUAL 0)
message(STATUS "Unable to determine MPI Fortran from MPI driver ${MPI_Fortran_COMPILER}")
endif (MPI_Fortran_COMPILER_RETURN EQUAL 0)
endif (MPI_Fortran_INCLUDE_PATH AND MPI_Fortran_LIBRARY)
if (MPI_Fortran_INCLUDE_PATH AND MPI_Fortran_LIBRARY)
# Do nothing: we already have MPI_Fortran_INCLUDE_PATH and MPI_Fortran_LIBRARY in
# the cache, and we don't want to override those settings.
elseif (MPI_Fortran_COMPILE_CMDLINE)
# Extract compile flags from the compile command line.
string(REGEX MATCHALL "-D([^\" ]+|\"[^\"]+\")" MPI_Fortran_ALL_COMPILE_FLAGS "${MPI_Fortran_COMPILE_CMDLINE}")
set(MPI_Fortran_COMPILE_FLAGS_WORK)
foreach(FLAG ${MPI_Fortran_ALL_COMPILE_FLAGS})
if (MPI_Fortran_COMPILE_FLAGS_WORK)
set(MPI_Fortran_COMPILE_FLAGS_WORK "${MPI_Fortran_COMPILE_FLAGS_WORK} ${FLAG}")
else(MPI_Fortran_COMPILE_FLAGS_WORK)
set(MPI_Fortran_COMPILE_FLAGS_WORK ${FLAG})
endif(MPI_Fortran_COMPILE_FLAGS_WORK)
endforeach(FLAG)
# Extract include paths from compile command line
string(REGEX MATCHALL "-I([^\" ]+|\"[^\"]+\")" MPI_Fortran_ALL_INCLUDE_PATHS "${MPI_Fortran_COMPILE_CMDLINE}")
set(MPI_Fortran_INCLUDE_PATH_WORK)
foreach(IPATH ${MPI_Fortran_ALL_INCLUDE_PATHS})
string(REGEX REPLACE "^-I" "" IPATH ${IPATH})
string(REGEX REPLACE "//" "/" IPATH ${IPATH})
list(APPEND MPI_Fortran_INCLUDE_PATH_WORK ${IPATH})
endforeach(IPATH)
if (NOT MPI_Fortran_INCLUDE_PATH_WORK)
if (MPI_Fortran_COMPILER_MAY_HAVE_INCLIBDIRS)
# The compile command line didn't have any include paths on it,
# but we may have -showme:incdirs. Use it.
exec_program(${MPI_Fortran_COMPILER}
ARGS -showme:incdirs
OUTPUT_VARIABLE MPI_Fortran_INCLUDE_PATH_WORK
RETURN_VALUE MPI_Fortran_COMPILER_RETURN)
separate_arguments(MPI_Fortran_INCLUDE_PATH_WORK)
endif (MPI_Fortran_COMPILER_MAY_HAVE_INCLIBDIRS)
endif (NOT MPI_Fortran_INCLUDE_PATH_WORK)
if (NOT MPI_Fortran_INCLUDE_PATH_WORK)
# If all else fails, just search for mpi.mod in the normal include
# paths.
find_path(MPI_Fortran_INCLUDE_PATH mpi.mod
HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
PATH_SUFFIXES include lib
)
set(MPI_Fortran_INCLUDE_PATH_WORK ${MPI_Fortran_INCLUDE_PATH})
endif (NOT MPI_Fortran_INCLUDE_PATH_WORK)
# Extract linker paths from the link command line
string(REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" MPI_Fortran_ALL_LINK_PATHS "${MPI_Fortran_LINK_CMDLINE}")
set(MPI_Fortran_LINK_PATH)
foreach(LPATH ${MPI_Fortran_ALL_LINK_PATHS})
string(REGEX REPLACE "^-L" "" LPATH ${LPATH})
string(REGEX REPLACE "//" "/" LPATH ${LPATH})
list(APPEND MPI_Fortran_LINK_PATH ${LPATH})
endforeach(LPATH)
if (NOT MPI_Fortran_LINK_PATH)
if (MPI_Fortran_COMPILER_MAY_HAVE_INCLIBDIRS)
# The compile command line didn't have any linking paths on it,
# but we may have -showme:libdirs. Use it.
exec_program(${MPI_Fortran_COMPILER}
ARGS -showme:libdirs
OUTPUT_VARIABLE MPI_Fortran_LINK_PATH
RETURN_VALUE MPI_Fortran_COMPILER_RETURN)
separate_arguments(MPI_Fortran_LINK_PATH)
endif (MPI_Fortran_COMPILER_MAY_HAVE_INCLIBDIRS)
endif (NOT MPI_Fortran_LINK_PATH)
# Extract linker flags from the link command line
string(REGEX MATCHALL "-Wl,([^\" ]+|\"[^\"]+\")" MPI_Fortran_ALL_LINK_FLAGS "${MPI_Fortran_LINK_CMDLINE}")
set(MPI_Fortran_LINK_FLAGS_WORK)
foreach(FLAG ${MPI_Fortran_ALL_LINK_FLAGS})
if (MPI_Fortran_LINK_FLAGS_WORK)
set(MPI_Fortran_LINK_FLAGS_WORK "${MPI_Fortran_LINK_FLAGS_WORK} ${FLAG}")
else(MPI_Fortran_LINK_FLAGS_WORK)
set(MPI_Fortran_LINK_FLAGS_WORK ${FLAG})
endif(MPI_Fortran_LINK_FLAGS_WORK)
endforeach(FLAG)
# Extract the set of libraries to link against from the link command
# line
string(REGEX MATCHALL "-l([^\" ]+|\"[^\"]+\")" MPI_Fortran_LIBNAMES "${MPI_Fortran_LINK_CMDLINE}")
# Determine full path names for all of the libraries that one needs
# to link against in an MPI program
set(MPI_Fortran_LIBRARIES)
foreach(LIB ${MPI_Fortran_LIBNAMES})
string(REGEX REPLACE "^-l" "" LIB ${LIB})
set(MPI_Fortran_LIB "MPI_Fortran_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
find_library(MPI_Fortran_LIB ${LIB} HINTS ${MPI_Fortran_LINK_PATH})
if (MPI_Fortran_LIB)
list(APPEND MPI_Fortran_LIBRARIES ${MPI_Fortran_LIB})
else (MPI_LIB)
message(SEND_ERROR "Unable to find MPI library ${LIB}")
endif (MPI_Fortran_LIB)
endforeach(LIB)
set(MPI_Fortran_LIB "MPI_LIB-NOTFOUND" CACHE INTERNAL "Scratch variable for MPI detection" FORCE)
# Chop MPI_LIBRARIES into the old-style MPI_LIBRARY and
# MPI_EXTRA_LIBRARY.
list(LENGTH MPI_Fortran_LIBRARIES MPI_Fortran_NUMLIBS)
list(LENGTH MPI_Fortran_LIBNAMES MPI_Fortran_NUMLIBS_EXPECTED)
if (MPI_Fortran_NUMLIBS EQUAL MPI_Fortran_NUMLIBS_EXPECTED)
list(GET MPI_Fortran_LIBRARIES 0 MPI_Fortran_LIBRARY_WORK)
set(MPI_Fortran_LIBRARY ${MPI_Fortran_LIBRARY_WORK} CACHE FILEPATH "MPI library to link against" FORCE)
else (MPI_Fortran_NUMLIBS EQUAL MPI_Fortran_NUMLIBS_EXPECTED)
set(MPI_Fortran_LIBRARY "MPI_Fortran_LIBRARY-NOTFOUND" CACHE FILEPATH "MPI library to link against" FORCE)
endif (MPI_Fortran_NUMLIBS EQUAL MPI_Fortran_NUMLIBS_EXPECTED)
if (MPI_Fortran_NUMLIBS GREATER 1)
set(MPI_Fortran_EXTRA_LIBRARY_WORK ${MPI_Fortran_LIBRARIES})
list(REMOVE_AT MPI_Fortran_EXTRA_LIBRARY_WORK 0)
set(MPI_Fortran_EXTRA_LIBRARY ${MPI_Fortran_EXTRA_LIBRARY_WORK} CACHE STRING "Extra MPI_Fortran libraries to link against" FORCE)
else (MPI_Fortran_NUMLIBS GREATER 1)
set(MPI_Fortran_EXTRA_LIBRARY "MPI_Fortran_EXTRA_LIBRARY-NOTFOUND" CACHE STRING "Extra MPI_Fortran libraries to link against" FORCE)
endif (MPI_Fortran_NUMLIBS GREATER 1)
# Set up all of the appropriate cache entries
set(MPI_Fortran_COMPILE_FLAGS ${MPI_Fortran_COMPILE_FLAGS_WORK} CACHE STRING "MPI_Fortranc compilation flags" FORCE)
set(MPI_Fortran_INCLUDE_PATH ${MPI_Fortran_INCLUDE_PATH_WORK} CACHE STRING "MPI_Fortran include path" FORCE)
set(MPI_Fortran_LINK_FLAGS ${MPI_Fortran_LINK_FLAGS_WORK} CACHE STRING "MPI linking flags" FORCE)
else (MPI_Fortran_COMPILE_CMDLINE)
# No MPI compiler to interogate so attempt to find everything with find functions.
find_path(MPI_Fortran_INCLUDE_PATH mpi.mod
HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
PATH_SUFFIXES include lib
)
find_library(MPI_Fortran_LIBRARY
NAMES mpi mpich msmpi
HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR}
)
find_library(MPI_Fortran_EXTRA_LIBRARY
NAMES mpif90 mpif77
HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
PATH_SUFFIXES lib
DOC "Extra MPI Fortran libraries to link against.")
set(MPI_Fortran_COMPILE_FLAGS "" CACHE STRING "MPI_Fortran compilation flags")
set(MPI_Fortran_LINK_FLAGS "" CACHE STRING "MPI_Fortran linking flags")
endif (MPI_Fortran_INCLUDE_PATH AND MPI_Fortran_LIBRARY)
# Set up extra variables to conform to
if (MPI_Fortran_EXTRA_LIBRARY)
set(MPI_Fortran_LIBRARIES ${MPI_Fortran_LIBRARY} ${MPI_Fortran_EXTRA_LIBRARY})
else (MPI_Fortran_EXTRA_LIBRARY)
set(MPI_Fortran_LIBRARIES ${MPI_Fortran_LIBRARY})
endif (MPI_Fortran_EXTRA_LIBRARY)
if (MPI_Fortran_INCLUDE_PATH AND MPI_Fortran_LIBRARY)
set(MPI_Fortran_FOUND TRUE)
else (MPI_Fortran_INCLUDE_PATH AND MPI_Fortran_LIBRARY)
set(MPI_Fortran_FOUND FALSE)
endif (MPI_Fortran_INCLUDE_PATH AND MPI_Fortran_LIBRARY)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments
find_package_handle_standard_args(MPI_Fortran DEFAULT_MSG MPI_Fortran_LIBRARY MPI_Fortran_INCLUDE_PATH)
mark_as_advanced(MPI_Fortran_INCLUDE_PATH MPI_Fortran_COMPILE_FLAGS MPI_Fortran_LINK_FLAGS MPI_Fortran_LIBRARY
MPI_Fortran_EXTRA_LIBRARY)
# unset to cleanup namespace
unset(_MPI_Fortran_PACKAGE_DIR)
unset(_MPI_PREFIX_PATH)
unset(_MPI_BASE_DIR)
...@@ -67,16 +67,30 @@ include_directories(${Boost_INCLUDE_DIRS}) ...@@ -67,16 +67,30 @@ include_directories(${Boost_INCLUDE_DIRS})
# MPI # MPI
if(WITH_MPI) if(WITH_MPI)
# Find MPI for C++ and fortran.
find_package(MPI REQUIRED) find_package(MPI REQUIRED)
# -I find_package(MPI_Fortran REQUIRED)
include_directories(${MPI_INCLUDE_PATH}) if(MPI_COMPILER)
# -l set(CMAKE_CXX_COMPILER mpic++)
set(LIBS ${LIBS} ${MPI_LIBRARIES}) elseif(MPI_COMPILER)
# Add compilatin flags, if required # -I
append_cxx_flags(${MPI_COMPILE_FLAGS}) include_directories(${MPI_INCLUDE_PATH})
append_Fortran_flags(${MPI_COMPILE_FLAGS}) # Add compilation flags
set(${PROJECT_NAME}_LINK_FLAGS ${${PROJECT_NAME}_LINK_FLAGS} ${MPI_LINK_FLAGS}) append_cxx_flags(${MPI_COMPILE_FLAGS})
set(${PROJECT_NAME}_LINK_FLAGS ${${PROJECT_NAME}_LINK_FLAGS} ${MPI_LINK_FLAGS})
endif(MPI_COMPILER)
if(MPI_Fortran_COMPILER)
set(CMAKE_Fortran_COMPILER mpif90)
elseif(MPI_Fortran_COMPILER)
# -I
include_directories(${MPI_Fortran_INCLUDE_PATH})
# Add compilation flags
append_Fortran_flags(${MPI_Fortran_COMPILE_FLAGS})
set(${PROJECT_NAME}_LINK_FLAGS ${${PROJECT_NAME}_LINK_FLAGS} ${MPI_Fortran_LINK_FLAGS})
endif(MPI_Fortran_COMPILER)
set(LIBS ${LIBS} ${MPI_LIBRARIES} ${MPI_Fortran_LIBRARIES} )
# for ParmesConfig.hpp # for ParmesConfig.hpp
#set(WITH_MPI 1) #set(WITH_MPI 1)
endif(WITH_MPI) endif(WITH_MPI)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment