Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
103 changes: 87 additions & 16 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,54 +13,125 @@ project(
VERSION 0.0.0
LANGUAGES Fortran C)
set(project_name vapaa)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(GNUInstallDirs)
enable_language(Fortran)
enable_language(C)

option(VAPAA_ENABLE_TESTING "Build tests" OFF)

if(VAPAA_ENABLE_TESTING)
enable_testing()
endif()
include(ExternalProject)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)

set(CMAKE_Fortran_STANDARD 2018)
set(CMAKE_Fortran_STANDARD_REQUIRED ON)

find_package(MPI REQUIRED COMPONENTS C)

set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/source")

# Create the static library
set(vapa_lib vapa)
set(vapaa_lib vapaa)

add_library(${vapa_lib} STATIC)
add_library(${vapaa_lib} STATIC)

if(DEFINED MPI_VENDOR)
set(FLAG_MPI ${MPI_VENDOR})
message(STATUS "MPI Vendor explicitly set to: ${MPI_VENDOR}")
else()
if(MPI_Fortran_COMPILER MATCHES "openmpi|ompi")
message(STATUS "The mpi compiler is in: ${MPI_C_COMPILER}")
# the "finding" MPI really depends on the path having the name of the MPI
# cmake does not have a MPI_LIBRARY_NAME variable that will 100% give us the
# name. Additionally, these flags are set based on the Makefiles included with
# vapaa upon which this CMake is based on
if(MPI_C_COMPILER MATCHES "openmpi|ompi")
set(FLAG_MPI -DOPEN_MPI)
elseif(MPI_Fortran_COMPILER MATCHES "mpich")
elseif(MPI_C_COMPILER MATCHES "mpich")
set(FLAG_MPI -DMPICH)
elseif(MPI_Fortran_COMPILER MATCHES "intel")
elseif(MPI_C_COMPILER MATCHES "intel")
set(FLAG_MPI -DMPICH)
elseif(MPI_Fortran_COMPILER MATCHES "cray")
elseif(MPI_C_COMPILER MATCHES "cray")
# this is based on most cray machines using cray-mpich
set(FLAG_MPI -DMPICH)
else()
set(FLAG_MPI "UnknownMPI")
#set(FLAG_MPI "UnknownMPI")
set(FLAG_MPI -DOPEN_MPI)
set(WARNING "Automatic detection failed, assuming OpenMPI")
endif()
message(STATUS "Automatically detected MPI Vendor: ${FLAG_MPI}")
endif()

message(STATUS "Final MPI Vendor Flag: ${FLAG_MPI}")

target_compile_options(${vapa_lib} PRIVATE -Wall -Wextra -fPIE)
target_compile_definitions(${vapa_lib} PRIVATE -DHAVE_CFI ${FLAG_MPI})
target_link_libraries(${vapa_lib} PRIVATE MPI::MPI_C)
set(WARNFLAGS "-Wall -Wextra -fPIE")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-Wall -Wextra aren't valid for the Intel compilers AFAIK.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not add extra warning flags. People can add them if they want, or we can use them in CI, but otherwise any non-standard flags are often just causing trouble when building on strange systems. (All HPC systems are strange snowflakes.) Even -fPIE should be handled automatically by cmake if it's building a shared library.

For example, I will want to cross-build this library on a x86-64 musl host for mingw 32-bit Windows. The respective mechanisms for shared libraries are different there, but since cmake already knows how to do that, just using the standard cmake mechanisms is best.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, warn flags in CI are good. We shouldn't enable in release builds.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, I shall fix this up :) I can probably create a small CI that runs on GIthub actions too

if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -std=f2018")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "LLVMFlang")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -std=f2018")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "NAG")
# this is a hack for now
# Get the full path to the NAG Fortran compiler
get_filename_component(NAGFOR_PATH "${CMAKE_Fortran_COMPILER}" REALPATH)
# Go up two directories to reach $NAG_ROOT (assuming $NAG_ROOT/bin/nagfor)
get_filename_component(NAG_ROOT "${NAGFOR_PATH}" DIRECTORY) # bin/
get_filename_component(NAG_ROOT "${NAG_ROOT}" DIRECTORY) # $NAG_ROOT/
message(STATUS "NAG HOME is in ${NAG_ROOT}")
target_include_directories(${vapaa_lib} PRIVATE ${NAG_ROOT}/lib)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -f2018")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -stand f18")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "IntelLLVM")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -stand f18")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Cray")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g ")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "NVHPC")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g ")
else()
message(WARNING "Unknown Fortran compiler: ${CMAKE_Fortran_COMPILER_ID}")
message(WARNING "F2018 standard may not be properly set")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${WARNFLAGS} -g")
endif()

# Display final flags
message(STATUS "Fortran compiler flags: ${CMAKE_Fortran_FLAGS}")

target_compile_definitions(${vapaa_lib} PRIVATE -DHAVE_CFI ${FLAG_MPI})
target_link_libraries(${vapaa_lib} PRIVATE MPI::MPI_C)

# Set the library output and module directories
set_target_properties(
${vapa_lib}
PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/modules")
${vapaa_lib}
PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib"
Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include")

target_include_directories(${vapaa_lib}
PUBLIC
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)


add_subdirectory(source)
if(VAPAA_ENABLE_TESTING)
add_subdirectory(tests)
endif()

install(TARGETS ${vapaa_lib}
EXPORT vapaaTargets
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)

install(DIRECTORY "${PROJECT_BINARY_DIR}/include/"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)

install(EXPORT vapaaTargets
FILE vapaaTargets.cmake
NAMESPACE vapaa::
DESTINATION lib/cmake/vapaa)

6 changes: 3 additions & 3 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
file(GLOB SRC_C CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
file(GLOB SRC_FC CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.F90")

file(GLOB C_files *.c)
file(GLOB FC_files *.F90)
target_sources(${vapa_lib} PRIVATE ${C_files} ${FC_files})
target_sources(${vapaa_lib} PRIVATE ${SRC_C} ${SRC_FC})