cmake_minimum_required (VERSION 3.5.2) project (PIOF Fortran) include (CheckFunctionExists) include (ExternalProject) include (LibCheck) #============================================================================== # DEFINE THE TARGET #============================================================================== set (PIO_Fortran_SRCS pio_nf.F90 pio.F90 pio_kinds.F90 pio_types.F90 piolib_mod.F90 pio_support.F90) set (PIO_GenF90_SRCS pionfatt_mod.F90 pionfput_mod.F90 pionfget_mod.F90 piodarray.F90) set (PIO_Fortran_MODS ${CMAKE_CURRENT_BINARY_DIR}/pio.mod ${CMAKE_CURRENT_BINARY_DIR}/pio_nf.mod ${CMAKE_CURRENT_BINARY_DIR}/pio_types.mod ${CMAKE_CURRENT_BINARY_DIR}/piolib_mod.mod ${CMAKE_CURRENT_BINARY_DIR}/pionfget_mod.mod ${CMAKE_CURRENT_BINARY_DIR}/pio_kinds.mod ${CMAKE_CURRENT_BINARY_DIR}/pio_support.mod ${CMAKE_CURRENT_BINARY_DIR}/piodarray.mod ${CMAKE_CURRENT_BINARY_DIR}/pionfatt_mod.mod ${CMAKE_CURRENT_BINARY_DIR}/pionfput_mod.mod) if (NETCDF_INTEGRATION) set (PIO_Fortran_SRCS ${PIO_Fortran_SRCS} ncint_mod.F90) set (PIO_Fortran_MODS ${PIO_Fortran_MODS} ${CMAKE_CURRENT_BINARY_DIR}/ncint_mod.mod) endif () set(CMAKE_POSITION_INDEPENDENT_CODE ON) add_library (piof ${PIO_Fortran_SRCS} ${PIO_GenF90_SRCS}) # Always use -fPIC set_property(TARGET piof PROPERTY POSITION_INDEPENDENT_CODE ON) if (NOT PIO_ENABLE_FORTRAN) set_target_properties(piof PROPERTIES EXCLUDE_FROM_ALL TRUE) endif () # Include flib source and binary directories (for Fortran modules) target_include_directories (piof PUBLIC $ PUBLIC $ PUBLIC $) # System and compiler CPP directives target_compile_definitions (piof PUBLIC ${CMAKE_SYSTEM_DIRECTIVE}) target_compile_definitions (piof PUBLIC ${CMAKE_Fortran_COMPILER_DIRECTIVE}) # Compiler-specific compile options if ("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "GNU") target_compile_options (piof PRIVATE -ffree-line-length-none) elseif (CMAKE_Fortran_COMPILER_ID STREQUAL "NAG") set ( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -mismatch_all " ) # target_compile_options (piof # PRIVATE -mismatch_all) elseif (CMAKE_Fortran_COMPILER_ID STREQUAL "Cray") set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ef") elseif (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -debug minimal") endif() if (CMAKE_BUILD_TYPE STREQUAL "DEBUG") set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g") endif() # Look for c_sizeof capability check_macro (Fortran_CSIZEOF NAME TryCSizeOf.f90 HINTS ${CMAKE_MODULE_PATH} COMMENT "whether Fortran compiler supports c_sizeof") if (NOT Fortran_CSIZEOF) target_compile_definitions (piof PUBLIC NO_C_SIZEOF) endif() # Look for filesystem hints if (PIO_FILESYSTEM_HINTS) if (PIO_FILESYSTEM_HINTS STREQUAL lustre) message (STATUS "PIO will use lustre filesystem hints") target_compile_definitions (piof PUBLIC PIO_LUSTRE_HINTS) elseif (PIO_FILESYSTEM_HINTS STREQUAL gpfs) message (STATUS "PIO will use gpfs filesystem hints") target_compile_definitions (piof PUBLIC PIO_GPFS_HINTS) else () message (WARNING "${PIO_FILESYSTEM_HINTS} not valid option for PIO_FILESYSTEM_HINTS; use gpfs or lustre.") endif () endif () #============================================================================== # DEFINE THE INSTALL #============================================================================== set_target_properties (piof PROPERTIES EXPORT_NAME PIO_Fortran) # Library install (TARGETS piof EXPORT PIOFortranTargets DESTINATION lib INCLUDES DESTINATION include) # Fortran Modules install (FILES ${PIO_Fortran_MODS} DESTINATION include) install(EXPORT PIOFortranTargets FILE PIOFortranTargets.cmake NAMESPACE PIO:: DESTINATION lib/cmake/PIO) #============================================================================== # DEFINE THE DEPENDENCIES #============================================================================== #===== pioc ===== target_link_libraries(piof PUBLIC pioc) #===== genf90 ===== if (DEFINED GENF90_PATH) add_custom_target(genf90 DEPENDS ${GENF90_PATH}/genf90.pl) else () ExternalProject_Add (genf90 PREFIX ${CMAKE_CURRENT_BINARY_DIR}/genf90 GIT_REPOSITORY https://github.com/PARALLELIO/genf90 GIT_TAG genf90_200608 UPDATE_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "") ExternalProject_Get_Property (genf90 SOURCE_DIR) set (GENF90_PATH ${SOURCE_DIR}) unset (SOURCE_DIR) endif () add_dependencies (piof genf90) #===== Fortran Source Generation with GenF90 ===== foreach (SRC_FILE IN LISTS PIO_GenF90_SRCS) add_custom_command (OUTPUT ${SRC_FILE} COMMAND ${GENF90_PATH}/genf90.pl ${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FILE}.in > ${SRC_FILE} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FILE}.in genf90) endforeach () #===== MPI ===== if (PIO_USE_MPISERIAL) if (MPISERIAL_Fortran_FOUND) target_compile_definitions (piof PRIVATE _MPISERIAL) target_include_directories (piof PUBLIC ${MPISERIAL_Fortran_INCLUDE_DIRS}) target_link_libraries (piof PUBLIC ${MPISERIAL_Fortran_LIBRARIES}) set (WITH_PNETCDF FALSE) set (MPI_Fortran_INCLUDE_PATH ${MPISERIAL_Fortran_INCLUDE_DIRS}) endif () endif () # Check MPI I/O capabilities find_path(MPIF_H_PATH NAMES mpif.h PATHS ${MPI_Fortran_INCLUDE_PATH} NO_DEFAULT_PATH) if (MPIF_H_PATH) check_macro (MPI_HAS_MPIIO NAME TryMPIIO.f90 HINTS ${CMAKE_MODULE_PATH} DEFINITIONS -I${MPIF_H_PATH} COMMENT "whether MPIIO is supported") if (${MPI_HAS_MPIIO}) message (STATUS "MPIIO verified and enabled.") target_compile_definitions (piof PUBLIC USEMPIIO) else () message (STATUS "MPIIO failed verification and therefore disabled.") endif () else () message (STATUS "MPIIO not detected and therefore disabled.") endif () # Check for MPI Fortran module find_path(MPIMOD_PATH NAMES mpi.mod MPI.mod HINTS ${MPI_Fortran_INCLUDE_PATH}) check_macro (MPI_HAS_Fortran_MOD NAME TryMPIMod.f90 HINTS ${CMAKE_MODULE_PATH} DEFINITIONS -I${MPIMOD_PATH} COMMENT "whether MPI Fortran module is supported") if (${MPI_HAS_Fortran_MOD}) message (STATUS "MPI Fortran module verified and enabled.") else () message (STATUS "MPI Fortran module failed verification and therefore disabled.") if (PIO_ENABLE_TIMING AND NOT GPTL_Fortran_Perf_FOUND) target_compile_definitions (gptl PUBLIC NO_MPIMOD) endif() target_compile_definitions (piof PUBLIC NO_MPIMOD) endif () #===== GPTL ===== if (PIO_ENABLE_TIMING) if (GPTL_Fortran_Perf_FOUND) message (STATUS "Found GPTL Fortran Perf: ${GPTL_Fortran_Perf_LIBRARIES}") target_include_directories (piof PUBLIC ${GPTL_Fortran_INCLUDE_DIRS}) target_link_libraries (piof PUBLIC ${GPTL_Fortran_LIBRARIES}) else () message (STATUS "Using internal GPTL Fortran library for timing") target_link_libraries (piof PUBLIC gptl) endif () endif () #===== NetCDF-Fortran ===== if (NetCDF_Fortran_FOUND) target_include_directories (piof PUBLIC ${NetCDF_Fortran_INCLUDE_DIRS}) target_link_libraries (piof PUBLIC ${NetCDF_Fortran_LIBRARIES}) endif () #===== PnetCDF ===== if (PnetCDF_Fortran_FOUND) target_include_directories (piof PUBLIC ${PnetCDF_Fortran_INCLUDE_DIRS}) target_link_libraries (piof PUBLIC ${PnetCDF_Fortran_LIBRARIES}) # Check library for varn functions set (CMAKE_REQUIRED_LIBRARIES ${PnetCDF_Fortran_LIBRARY}) endif () #===== Add EXTRAs ===== target_include_directories (piof PUBLIC $) target_link_libraries (piof PUBLIC ${PIO_Fortran_EXTRA_LIBRARIES}) target_compile_options (piof PRIVATE ${PIO_Fortran_EXTRA_COMPILE_OPTIONS}) target_compile_definitions (piof PUBLIC ${PIO_Fortran_EXTRA_COMPILE_DEFINITIONS}) if (PIO_Fortran_EXTRA_LINK_FLAGS) set_target_properties(piof PROPERTIES LINK_FLAGS ${PIO_Fortran_EXTRA_LINK_FLAGS}) endif () #===== Check for necessities ===== if (NOT PnetCDF_Fortran_FOUND AND NOT NetCDF_Fortran_FOUND) message (FATAL_ERROR "Must have PnetCDF and/or NetCDF Fortran libraries") endif () set(FFLAGS ${CMAKE_Fortran_FLAGS} PARENT_SCOPE) get_target_property(fppdefs piof COMPILE_DEFINITIONS) get_target_property(fincludes piof INCLUDE_DIRECTORIES) foreach(x IN LISTS fppdefs) string(APPEND FPPFLAGS " -D${x}") endforeach() foreach(x IN LISTS fincludes) if (x) string(APPEND FPPFLAGS " -I${x}") endif() endforeach() set(FPPFLAGS ${FPPFLAGS} PARENT_SCOPE)