Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows support #755

Merged
merged 18 commits into from
May 7, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 83 additions & 118 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.19)

cmake_policy(VERSION 3.10...3.14)
cmake_policy(VERSION 3.19...3.23)

if(DEFINED ENV{SOURCE_DATE_EPOCH})
set(SOURCE_DATE_EPOCH "$ENV{SOURCE_DATE_EPOCH}")
Expand Down Expand Up @@ -139,6 +139,9 @@ endif()
if(NOT CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS "")
endif()
if(NOT CMAKE_REQUIRED_DEFINITIONS)
set(CMAKE_REQUIRED_DEFINITIONS "")
endif()
if(NOT CMAKE_REQUIRED_LIBRARIES)
set(CMAKE_REQUIRED_LIBRARIES "")
endif()
Expand Down Expand Up @@ -278,93 +281,61 @@ if (C_COMPILER_NAME MATCHES "^[mM][pP][iI]")
endif()

if(WIN32) # Only support building with GCC & GFortran using Intel MPI (OneAPI)
# Here we assume Intel ONEAPI and the environment is loaded
cmake_path(SET MPI_ROOT NORMALIZE "$ENV{I_MPI_ROOT}")
set (IMPI_INCLUDES "${MPI_ROOT}/include")
set (IMPI_LIB_DIR "${MPI_ROOT}/lib/${IMPI_BUILD}")
set (IMPI_DLL_DIR "${MPI_ROOT}/bin/${IMPI_BUILD}")
set (IMPI_BIN_DIR "${MPI_ROOT}/bin")

find_library(IMPI_LIB
"impi.lib"
HINTS "${IMPI_LIB_DIR}"
DOC "Location of the Intel MPI impi.lib file"
REQUIRED
NO_DEFAULT_PATH)

set(MPI_impi_LIBRARY "${IMPI_LIB}")
set(MPI_impicxx_LIBRARY "${IMPI_LIB_DIR}/impicxx.lib")

find_file(IMPI_DLL
"impi.dll"
HINTS "${IMPI_DLL_DIR}"
DOC "Location of the Intel MPI impi.dll file"
REQUIRED
NO_DEFAULT_PATH)


add_library(IMPI::MPI SHARED IMPORTED)
set_target_properties(IMPI::MPI
PROPERTIES
IMPORTED_IMPLIB "${IMPI_LIB}"
IMPORTED_LOCATION "${IMPI_DLL}")
target_include_directories(IMPI::MPI
INTERFACE "${IMPI_INCLUDES}")

set(MPI_C_INCLUDE_DIRS "${IMPI_INCLUDES}")
set(MPI_C_INCLUDE_PATH "${IMPI_INCLUDES}")
set(MPI_C_HEADER_DIR "${IMPI_INCLUDES}")
set(MPI_Fortran_COMPILER_INCLUDE_DIRS "${IMPI_INCLUDES}")
set(MPI_Fortran_F77_HEADER_DIR "${IMPI_INCLUDES}")
set(MPI_Fortran_INCLUDE_PATH "${IMPI_INCLUDES}")

set(MPI_C_LIB_NAMES impi;impicxx)
set(MPI_C_LIBRARIES "${IMPI_LIB}")
set(MPI_Fortran_LIB_NAMES impi)
set(MPI_Fortran_LIBRARIES "${IMPI_LIB}")

set(MPI_Fortran_HAVE_F90_MODULE FALSE)
set(MPI_Fortran_HAVE_F08_MODULE FALSE)

find_program(MPIEXEC_EXECUTABLE
mpiexec
HINTS "${IMPI_BIN_DIR}"
DOC "Location of Intel MPI implementations mpiexec launcher program"
REQUIRED
NO_DEFAULT_PATH)
set(MPIEXEC "${MPIEXEC_EXECUTABLE}")
set(MPI_EXEC_NUMPROC_FLAG -n)
set(MPI_EXEC_PREFLAGS -print-all-exitcodes)

set(MPI_C_FOUND TRUE)
set(MPI_Fortran_FOUND TRUE)

else()
find_package( MPI )

if ( (NOT MPI_C_FOUND) OR (NOT MPI_Fortran_FOUND) OR (NOT MPIEXEC_EXECUTABLE))
# Get default install location of MPICH from install.sh
message(WARNING "Could not find all MPI components!")
message(WARNING "
# Here we assume Intel ONEAPI and the environment is loaded
set( MPI_ASSUME_NO_BUILTIN_MPI TRUE )
set( MPI_CXX_SKIP_MPICXX TRUE )
cmake_path(SET MPI_ROOT NORMALIZE "$ENV{I_MPI_ROOT}")
set (IMPI_LIB_DIR "${MPI_ROOT}/lib/${IMPI_BUILD}")
set (IMPI_DLL_DIR "${MPI_ROOT}/bin/${IMPI_BUILD}")

find_library(IMPI_LIB
"impi.lib"
HINTS "${IMPI_LIB_DIR}"
DOC "Location of the Intel MPI impi.lib file"
REQUIRED
NO_DEFAULT_PATH)

find_file(IMPI_DLL
"impi.dll"
HINTS "${IMPI_DLL_DIR}"
DOC "Location of the Intel MPI impi.dll file"
REQUIRED
NO_DEFAULT_PATH)


set( MPI_C_LIBRARIES ${IMPI_LIB};${IMPI_DLL} CACHE FILEPATH "MPI C libs to link" )
set( MPI_C_LIB_NAMES impi CACHE FILEPATH "MPI lib names" )
set( MPI_Fortran_LIBRARIES ${IMPI_LIB};${IMPI_DLL} CACHE FILEPATH "MPI Fortran libs to link" )
set( MPI_Fortran_LIB_NAMES impi CACHE FILEPATH "MPI Fortran lib names" )
set( MPI_impi_LIBRARY ${IMPI_LIB} CACHE FILEPATH "MPI lib to link" )

set(MPI_Fortran_HAVE_F90_MODULE FALSE)
set(MPI_Fortran_HAVE_F08_MODULE FALSE)

endif()
find_package( MPI )

if ( (NOT MPI_C_FOUND) OR (NOT MPI_Fortran_FOUND) OR (NOT MPIEXEC_EXECUTABLE))
# Get default install location of MPICH from install.sh
message(WARNING "Could not find all MPI components!")
message(WARNING "
MPI_C_FOUND = ${MPI_C_FOUND}
MPI_Fortran_FOUND = ${MPI_Fortran_FOUND}
MPIEXEC = ${MPIEXEC_EXECUTABLE}
MPIEXEC_EXECUTABLE = ${MPIEXEC_EXECUTABLE}
")
execute_process( COMMAND "./install.sh" -P mpich
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE DEFAULT_MPICH_INSTALL_LOC
OUTPUT_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
find_program (MY_MPI_EXEC NAMES mpirun mpiexec lamexec srun
PATHS "${DEFAULT_MPICH_INSTALL_LOC}" ENV PATH
HINTS "${FTN_COMPILER_DIR}" "${C_COMPILER_DIR}"
PATH_SUFFIXES bin)
set ( MPI_HOME "${MPI_HOME}" "${MY_MPI_EXEC}" "${MY_MPI_EXEC}/.." )
find_package( MPI REQUIRED )
endif()
endif()
list(REMOVE_DUPLICATES MPI_Fortran_INCLUDE_PATH)
execute_process( COMMAND "./install.sh" -P mpich
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE DEFAULT_MPICH_INSTALL_LOC
OUTPUT_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
find_program (MY_MPI_EXEC NAMES mpirun mpiexec lamexec srun
PATHS "${DEFAULT_MPICH_INSTALL_LOC}" ENV PATH
HINTS "${FTN_COMPILER_DIR}" "${C_COMPILER_DIR}"
PATH_SUFFIXES bin)
set ( MPI_HOME "${MPI_HOME}" "${MY_MPI_EXEC}" "${MY_MPI_EXEC}/.." )
find_package( MPI REQUIRED )
endif()
list(REMOVE_DUPLICATES MPI_Fortran_INCLUDE_DIRS)

# Test for consistent MPI environment but not on windows
if (NOT MPIEXEC_EXECUTABLE)
Expand All @@ -376,7 +347,7 @@ else()
add_definitions(-DHAVE_MPI)
endif()
if(NOT WIN32)
get_filename_component(MPIEXEC_RELATIVE_LOC "${MPIEXEC}"
get_filename_component(MPIEXEC_RELATIVE_LOC "${MPIEXEC_EXECUTABLE}"
PROGRAM)
get_filename_component(MPIEXEC_ABS_LOC "${MPIEXEC_RELATIVE_LOC}"
REALPATH)
Expand Down Expand Up @@ -435,7 +406,9 @@ endif()
# Make sure a simple "hello world" C mpi program compiles
#--------------------------------------------------------
set(OLD_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS ${MPI_C_COMPILE_OPTIONS} ${MPI_C_COMPILE_DEFINITIONS} ${MPI_C_LINK_FLAGS})
set(CMAKE_REQUIRED_FLAGS ${MPI_C_COMPILE_OPTIONS} ${MPI_C_LINK_FLAGS})
set(OLD_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS})
set(CMAKE_REQUIRED_DEFINITIONS ${MPI_C_COMPILE_DEFINITIONS})
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_REQUIRED_INCLUDES ${MPI_C_INCLUDE_DIRS})
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
Expand All @@ -459,6 +432,7 @@ int main(int argc, char** argv) {
}"
MPI_C_COMPILES)
set(CMAKE_REQUIRED_FLAGS ${OLD_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_DEFINITIONS ${OLD_REQUIRED_DEFINITIONS})
set(CMAKE_REQUIRED_INCLUDES ${OLD_INCLUDES})
set(CMAKE_REQUIRED_LIBRARIES ${OLD_LIBRARIES})
unset(OLD_REQUIRED_FLAGS)
Expand All @@ -478,9 +452,11 @@ endif()
# Try using mpi.mod first then fall back on includ 'mpif.h'
#--------------------------------------------------------------
set(OLD_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "-ffree-form" ${MPI_Fortran_COMPILE_OPTIONS} ${MPI_Fortran_COMPILE_DEFINITIONS} ${MPI_Fortran_LINK_FLAGS})
set(CMAKE_REQUIRED_FLAGS "-ffree-form" ${MPI_Fortran_COMPILE_OPTIONS} ${MPI_Fortran_LINK_FLAGS})
set(OLD_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS})
set(CMAKE_REQUIRED_DEFINITIONS ${MPI_Fortran_COMPILE_DEFINITIONS})
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_PATH})
set(CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_DIRS})
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${MPI_Fortran_LIBRARIES})
include (CheckFortranSourceCompiles)
Expand All @@ -500,6 +476,7 @@ end program
"
MPI_Fortran_MODULE_COMPILES)
set(CMAKE_REQUIRED_FLAGS ${OLD_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_DEFINITIONS ${OLD_REQUIRED_DEFINITIONS})
set(CMAKE_REQUIRED_INCLUDES ${OLD_INCLUDES})
set(CMAKE_REQUIRED_LIBRARIES ${OLD_LIBRARIES})
unset(OLD_REQUIRED_FLAGS)
Expand All @@ -510,9 +487,11 @@ unset(OLD_LIBRARIES)
# If that failed try using mpif.h
#--------------------------------
set(OLD_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "-ffree-form" ${MPI_Fortran_COMPILE_OPTIONS} ${MPI_Fortra_COMPILE_DEFINITIONS} ${MPI_Fortran_LINK_FLAGS})
set(CMAKE_REQUIRED_FLAGS "-ffree-form" ${MPI_Fortran_COMPILE_OPTIONS} ${MPI_Fortran_LINK_FLAGS})
set(OLD_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS})
set(CMAKE_REQUIRED_DEFINITIONS ${MPI_Fortra_COMPILE_DEFINITIONS})
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_PATH})
set(CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_DIRS})
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${MPI_Fortran_LIBRARIES})
include (CheckFortranSourceCompiles)
Expand All @@ -532,6 +511,7 @@ end program
"
MPI_Fortran_INCLUDE_COMPILES)
set(CMAKE_REQUIRED_FLAGS ${OLD_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_DEFINITIONS ${OLD_REQUIRED_DEFINITIONS})
set(CMAKE_REQUIRED_INCLUDES ${OLD_INCLUDES})
set(CMAKE_REQUIRED_LIBRARIES ${OLD_LIBRARIES})
unset(OLD_REQUIRED_FLAGS)
Expand All @@ -556,26 +536,6 @@ else()
)
endif()

#----------------
# Setup MPI flags
#----------------
if(NOT CMAKE_C_COMPILE_FLAGS)
set(CMAKE_C_COMPILE_FLAGS "")
endif()
if(NOT CMAKE_C_LINK_FLAGS)
set(CMAKE_C_LINK_FLAGS "")
endif()
if(NOT CMAKE_Fortran_COMPILE_FLAGS)
set(CMAKE_Fortran_COMPILE_FLAGS "")
endif()
if(NOT CMAKE_Fortran_LINK_FLAGS)
set(CMAKE_Fortran_LINK_FLAGS "")
endif()
set(CMAKE_C_COMPILE_FLAGS "${CMAKE_C_COMPILE_FLAGS} ${MPI_C_COMPILE_FLAGS}")
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} ${MPI_C_LINK_FLAGS}")
set(CMAKE_Fortran_COMPILE_FLAGS "${CMAKE_Fortran_COMPILE_FLAGS} ${MPI_Fortran_COMPILE_FLAGS}")
set(CMAKE_Fortran_LINK_FLAGS "${CMAKE_Fortran_LINK_FLAGS} ${MPI_Fortran_LINK_FLAGS}")

#---------------------------------------------------
# Use standardized GNU install directory conventions
#---------------------------------------------------
Expand All @@ -600,9 +560,13 @@ if(APPLE)
find_program(CODESIGN codesign)
endif()

# We need bash, even on windows, for now at least. A light version like Git-Bash works best,
# WSL dumps you into your home directory and there's nothing you can do about it.
find_program(BASH_EXECUTABLE bash
REQUIRED)
function(caf_compile_executable target main_depend)
set(includes "")
foreach(includedir ${MPI_Fortran_INCLUDE_PATH})
foreach(includedir ${MPI_Fortran_INCLUDE_DIRS})
list(APPEND includes "-I${includedir}")
endforeach()
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
Expand All @@ -613,7 +577,7 @@ function(caf_compile_executable target main_depend)
list(APPEND localDefs "-D${d}")
endforeach()
add_custom_command(OUTPUT "${target}"
COMMAND "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/caf"
COMMAND "${BASH_EXECUTABLE}" "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/caf"
${includes} ${localDefs} ${config_Fortran_flags}
-o "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${target}"
"${CMAKE_CURRENT_SOURCE_DIR}/${main_depend}"
Expand Down Expand Up @@ -657,10 +621,11 @@ endfunction()
#-----------------------------------------------

find_program(style_pl style.pl "${CMAKE_SOURCE_DIR}/developer-scripts/")
find_package(Perl)
function(check_script_style script_full_path)
if(style_pl)
if(style_pl AND PERL_FOUND)
add_test(NAME "style:${script_full_path}"
COMMAND "${style_pl}" "${script_full_path}")
COMMAND "${PERL_EXECUTABLE}" "${style_pl}" "${script_full_path}")
endif()
endfunction()

Expand Down Expand Up @@ -772,9 +737,9 @@ function(add_caf_test name num_caf_img test_target)
endif()
set(test_parameters -np ${num_caf_img} ${test_parameters})
if(DEFINED ARGN)
add_test(NAME ${name} COMMAND "bash" "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/cafrun" ${test_parameters} "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test_target}" ${ARGN})
add_test(NAME ${name} COMMAND "${BASH_EXECUTABLE}" "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/cafrun" ${test_parameters} "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test_target}" ${ARGN})
else()
add_test(NAME ${name} COMMAND "bash" "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/cafrun" ${test_parameters} "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test_target}")
add_test(NAME ${name} COMMAND "${BASH_EXECUTABLE}" "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/cafrun" ${test_parameters} "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test_target}")
endif()
set_property(TEST ${name} PROPERTY PASS_REGULAR_EXPRESSION "Test passed.")
endfunction(add_caf_test)
Expand Down
Loading