Skip to content
This repository was archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
Merge branch 'CMAKE'
Browse files Browse the repository at this point in the history
  • Loading branch information
cwishard committed Oct 31, 2022
2 parents 9ff0bc0 + 325b379 commit cd6ceb0
Show file tree
Hide file tree
Showing 101 changed files with 5,644 additions and 298 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
# whitelist only the files that ever need to be tracked
!*.f90
!*.sh
!CMakeLists.txt
!*.cmake
!CHANGELOG
!README.md
!paper/paper.md
Expand Down Expand Up @@ -77,3 +79,6 @@ python/swiftest/tests/convert_code_type/swifter2swiftest/pl.swifter2swiftest.in
python/swiftest/tests/convert_code_type/swifter2swiftest/tp.swifter2swiftest.in

!python/swiftest/requirements.txt

bin/
build/*
64 changes: 64 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# CMake project file for FOO

##################################################
# Define the project and the depencies that it has
##################################################

CMAKE_MINIMUM_REQUIRED(VERSION 2.8.5...3.20.1)
PROJECT(Swiftest Fortran)

# Set the Swiftest version
SET(VERSION 1.0.0)

# Add our local modlues to the module path
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/")

# Uncomment if it is required that Fortran 90 is supported
IF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90)
MESSAGE(FATAL_ERROR "Fortran compiler does not support F90")
ENDIF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90)

# Set some options the user may choose
# Uncomment the below if you want the user to choose a parallelization library
OPTION(USE_MPI "Use the MPI library for parallelization" OFF)
OPTION(USE_OPENMP "Use OpenMP for parallelization" OFF)

# This INCLUDE statement executes code that sets the compile flags for DEBUG,
# RELEASE, and TESTING. You should review this file and make sure the flags
# are to your liking.
INCLUDE(${CMAKE_MODULE_PATH}/SetFortranFlags.cmake)
# Locate and set parallelization libraries. There are some CMake peculiarities
# taken care of here, such as the fact that the FindOpenMP routine doesn't know
# about Fortran.
INCLUDE(${CMAKE_MODULE_PATH}/SetParallelizationLibrary.cmake)

INCLUDE(${CMAKE_MODULE_PATH}/SetUpNetCDF.cmake)

# There is an error in CMAKE with this flag for pgf90. Unset it
GET_FILENAME_COMPONENT(FCNAME ${CMAKE_Fortran_COMPILER} NAME)
IF(FCNAME STREQUAL "pgf90")
UNSET(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS)
ENDIF(FCNAME STREQUAL "pgf90")

############################################################
# Define the actual files and folders that make up the build
############################################################

# Define the executable name
SET(FOOEXE swiftest_driver)

# Define some directories
SET(SRC ${CMAKE_SOURCE_DIR}/src)
SET(LIB ${CMAKE_SOURCE_DIR}/lib)
SET(BIN ${CMAKE_SOURCE_DIR}/bin)

# Have the .mod files placed in the lib folder
SET(CMAKE_Fortran_MODULE_DIRECTORY ${LIB})

# The source for the FOO binary and have it placed in the bin folder
ADD_SUBDIRECTORY(${SRC} ${BIN})

# Add a distclean target to the Makefile
ADD_CUSTOM_TARGET(distclean
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/distclean.cmake
)
Empty file removed bin/.gitignore
Empty file.
9 changes: 9 additions & 0 deletions cmake/Modules/FindNETCDF.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# - Finds the NetCDF libraries
find_path(NETCDF_INCLUDE_DIR NAMES netcdf.mod HINTS ENV NETCDF_FORTRAN_HOME)
find_library(NETCDF_LIBRARY NAMES netcdf HINTS ENV NETCDF_FORTRAN_HOME)
find_library(NETCDF_FORTRAN_LIBRARY NAMES netcdff HINTS ENV NETCDF_FORTRAN_HOME)

set(NETCDF_FOUND TRUE)
set(NETCDF_INCLUDE_DIRS ${NETCDF_INCLUDE_DIR})
set(NETCDF_LIBRARIES ${NETCDF_LIBRARY} ${NETCDF_FORTRAN_LIBRARY})
mark_as_advanced(NETCDF_LIBRARY NETCDF_FORTRAN_LIBRARY NETCDF_INCLUDE_DIR)
104 changes: 104 additions & 0 deletions cmake/Modules/FindOpenMP_Fortran.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# - Finds OpenMP support
# This module can be used to detect OpenMP support in a compiler.
# If the compiler supports OpenMP, the flags required to compile with
# openmp support are set.
#
# This module was modified from the standard FindOpenMP module to find Fortran
# flags.
#
# The following variables are set:
# OpenMP_Fortran_FLAGS - flags to add to the Fortran compiler for OpenMP
# support. In general, you must use these at both
# compile- and link-time.
# OMP_NUM_PROCS - the max number of processors available to OpenMP

#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2008-2009 André Rigland Brodtkorb <Andre.Brodtkorb@ifi.uio.no>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)

INCLUDE (${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)

SET (OpenMP_Fortran_FLAG_CANDIDATES
#Microsoft Visual Studio
"/openmp"
#Intel windows
"/Qopenmp"
#Intel
"-qopenmp"
#Gnu
"-fopenmp"
#Empty, if compiler automatically accepts openmp
" "
#Sun
"-xopenmp"
#HP
"+Oopenmp"
#IBM XL C/c++
"-qsmp"
#Portland Group
"-mp"
)

IF (DEFINED OpenMP_Fortran_FLAGS)
SET (OpenMP_Fortran_FLAG_CANDIDATES)
ENDIF (DEFINED OpenMP_Fortran_FLAGS)

# check fortran compiler. also determine number of processors
FOREACH (FLAG ${OpenMP_Fortran_FLAG_CANDIDATES})
SET (SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET (CMAKE_REQUIRED_FLAGS "${FLAG}")
UNSET (OpenMP_FLAG_DETECTED CACHE)
MESSAGE (STATUS "Try OpenMP Fortran flag = [${FLAG}]")
FILE (WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranOpenMP.f90"
"
program TestOpenMP
use omp_lib
write(*,'(I2)',ADVANCE='NO') omp_get_num_procs()
end program TestOpenMP
")
SET (MACRO_CHECK_FUNCTION_DEFINITIONS
"-DOpenMP_FLAG_DETECTED ${CMAKE_REQUIRED_FLAGS}")
TRY_RUN (OpenMP_RUN_FAILED OpenMP_FLAG_DETECTED ${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranOpenMP.f90
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
COMPILE_OUTPUT_VARIABLE OUTPUT
RUN_OUTPUT_VARIABLE OMP_NUM_PROCS_INTERNAL)
IF (OpenMP_FLAG_DETECTED)
FILE (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Fortran compiler supports OpenMP passed with "
"the following output:\n${OUTPUT}\n\n")
SET (OpenMP_FLAG_DETECTED 1)
IF (OpenMP_RUN_FAILED)
MESSAGE (FATAL_ERROR "OpenMP found, but test code did not run")
ENDIF (OpenMP_RUN_FAILED)
SET (OMP_NUM_PROCS ${OMP_NUM_PROCS_INTERNAL} CACHE
STRING "Number of processors OpenMP may use" FORCE)
SET (OpenMP_Fortran_FLAGS_INTERNAL "${FLAG}")
BREAK ()
ELSE ()
FILE (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Fortran compiler supports OpenMP failed with "
"the following output:\n${OUTPUT}\n\n")
SET (OpenMP_FLAG_DETECTED 0)
ENDIF (OpenMP_FLAG_DETECTED)
ENDFOREACH (FLAG ${OpenMP_Fortran_FLAG_CANDIDATES})

SET (OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_INTERNAL}"
CACHE STRING "Fortran compiler flags for OpenMP parallization")

# handle the standard arguments for FIND_PACKAGE
FIND_PACKAGE_HANDLE_STANDARD_ARGS (OpenMP_Fortran DEFAULT_MSG
OpenMP_Fortran_FLAGS)

MARK_AS_ADVANCED(OpenMP_Fortran_FLAGS)
112 changes: 112 additions & 0 deletions cmake/Modules/SetCompileFlag.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#############################################################################
# Given a list of flags, this function will try each, one at a time,
# and choose the first flag that works. If no flags work, then nothing
# will be set, unless the REQUIRED key is given, in which case an error
# will be given.
#
# Call is:
# SET_COMPILE_FLAG(FLAGVAR FLAGVAL (Fortran|C|CXX) <REQUIRED> flag1 flag2...)
#
# For example, if you have the flag CMAKE_C_FLAGS and you want to add
# warnings and want to fail if this is not possible, you might call this
# function in this manner:
# SET_COMPILE_FLAGS(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" C REQUIRED
# "-Wall" # GNU
# "-warn all" # Intel
# )
# The optin "-Wall" will be checked first, and if it works, will be
# appended to the CMAKE_C_FLAGS variable. If it doesn't work, then
# "-warn all" will be tried. If this doesn't work then checking will
# terminate because REQUIRED was given.
#
# The reasong that the variable must be given twice (first as the name then
# as the value in quotes) is because of the way CMAKE handles the passing
# of variables in functions; it is difficult to extract a variable's
# contents and assign new values to it from within a function.
#############################################################################

INCLUDE(${CMAKE_ROOT}/Modules/CheckCCompilerFlag.cmake)
INCLUDE(${CMAKE_ROOT}/Modules/CheckCXXCompilerFlag.cmake)

FUNCTION(SET_COMPILE_FLAG FLAGVAR FLAGVAL LANG)

# Do some up front setup if Fortran
IF(LANG STREQUAL "Fortran")
# Create a list of error messages from compilers
SET(FAIL_REGEX
"ignoring unknown option" # Intel
"invalid argument" # Intel
"unrecognized .*option" # GNU
"[Uu]nknown switch" # Portland Group
"ignoring unknown option" # MSVC
"warning D9002" # MSVC, any lang
"[Uu]nknown option" # HP
"[Ww]arning: [Oo]ption" # SunPro
"command option .* is not recognized" # XL
)
ENDIF(LANG STREQUAL "Fortran")

# Make a variable holding the flags. Filter out REQUIRED if it is there
SET(FLAG_REQUIRED FALSE)
SET(FLAG_FOUND FALSE)
UNSET(FLAGLIST)
FOREACH (var ${ARGN})
STRING(TOUPPER "${var}" UP)
IF(UP STREQUAL "REQUIRED")
SET(FLAG_REQUIRED TRUE)
ELSE()
SET(FLAGLIST ${FLAGLIST} "${var}")
ENDIF(UP STREQUAL "REQUIRED")
ENDFOREACH (var ${ARGN})

# Now, loop over each flag
FOREACH(flag ${FLAGLIST})

UNSET(FLAG_WORKS)
# Check the flag for the given language
IF(LANG STREQUAL "C")
CHECK_C_COMPILER_FLAG("${flag}" FLAG_WORKS)
ELSEIF(LANG STREQUAL "CXX")
CHECK_CXX_COMPILER_FLAG("${flag}" FLAG_WORKS)
ELSEIF(LANG STREQUAL "Fortran")
# There is no nice function to do this for FORTRAN, so we must manually
# create a test program and check if it compiles with a given flag.
SET(TESTFILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}")
SET(TESTFILE "${TESTFILE}/CMakeTmp/testFortranFlags.f90")
FILE(WRITE "${TESTFILE}"
"
program dummyprog
i = 5
end program dummyprog
")
TRY_COMPILE(FLAG_WORKS ${CMAKE_BINARY_DIR} ${TESTFILE}
COMPILE_DEFINITIONS "${flag}" OUTPUT_VARIABLE OUTPUT)

# Check that the output message doesn't match any errors
FOREACH(rx ${FAIL_REGEX})
IF("${OUTPUT}" MATCHES "${rx}")
SET(FLAG_WORKS FALSE)
ENDIF("${OUTPUT}" MATCHES "${rx}")
ENDFOREACH(rx ${FAIL_REGEX})

ELSE()
MESSAGE(FATAL_ERROR "Unknown language in SET_COMPILE_FLAGS: ${LANG}")
ENDIF(LANG STREQUAL "C")

# If this worked, use these flags, otherwise use other flags
IF(FLAG_WORKS)
# Append this flag to the end of the list that already exists
SET(${FLAGVAR} "${FLAGVAL} ${flag}" CACHE STRING
"Set the ${FLAGVAR} flags" FORCE)
SET(FLAG_FOUND TRUE)
BREAK() # We found something that works, so exit
ENDIF(FLAG_WORKS)

ENDFOREACH(flag ${FLAGLIST})

# Raise an error if no flag was found
IF(FLAG_REQUIRED AND NOT FLAG_FOUND)
MESSAGE(FATAL_ERROR "No compile flags were found")
ENDIF(FLAG_REQUIRED AND NOT FLAG_FOUND)

ENDFUNCTION()
Loading

0 comments on commit cd6ceb0

Please sign in to comment.