######################################################################################## # Compiler options for building DAMASK cmake_minimum_required (VERSION 3.10.0 FATAL_ERROR) #--------------------------------------------------------------------------------------- # Find PETSc from system environment set(PETSC_DIR $ENV{PETSC_DIR}) if (PETSC_DIR STREQUAL "") message (FATAL_ERROR "PETSc location (PETSC_DIR) is not defined") endif () set (petsc_conf_variables "${PETSC_DIR}/lib/petsc/conf/variables") set (petsc_conf_rules "${PETSC_DIR}/lib/petsc/conf/rules" ) # Use existing variables from PETSc # https://github.com/jedbrown/cmake-modules/blob/master/FindPETSc.cmake # Generate a temporary makefile to probe the PETSc configuration # This file will be deleted once the settings from PETSc are parsed into CMake exec_program (mktemp ARGS -d OUTPUT_VARIABLE TEMPDIR) set (petsc_config_makefile "${TEMPDIR}/Makefile.petsc") file (WRITE "${petsc_config_makefile}" "## This file was auto generated by CMake # PETSC_DIR = ${PETSC_DIR} SHELL = /bin/sh include ${petsc_conf_rules} include ${petsc_conf_variables} INCLUDE_DIRS := \${PETSC_FC_INCLUDES} LIBRARIES := \${PETSC_WITH_EXTERNAL_LIB} COMPILERF := \${FC} COMPILERC := \${CC} LINKERNAME := \${FLINKER} includes: \t@echo \${INCLUDE_DIRS} extlibs: \t@echo \${LIBRARIES} compilerf: \t@echo \${COMPILERF} compilerc: \t@echo \${COMPILERC} linker: \t@echo \${LINKERNAME} ") # CMake will execute each target in the ${petsc_config_makefile} # to acquire corresponding PETSc Variables. find_program (MAKE_EXECUTABLE NAMES gmake make) # Find the PETSc includes directory settings execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "includes" RESULT_VARIABLE PETSC_INCLUDES_RETURN OUTPUT_VARIABLE petsc_includes OUTPUT_STRIP_TRAILING_WHITESPACE) # Find the PETSc external linking directory settings # required for final linking, must be appended after the executable execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "extlibs" RESULT_VARIABLE PETSC_EXTERNAL_LIB_RETURN OUTPUT_VARIABLE petsc_external_lib OUTPUT_STRIP_TRAILING_WHITESPACE) # PETSc specified fortran compiler execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "compilerf" RESULT_VARIABLE PETSC_MPIFC_RETURN OUTPUT_VARIABLE PETSC_MPIFC OUTPUT_STRIP_TRAILING_WHITESPACE) # PETSc specified C compiler execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "compilerc" RESULT_VARIABLE PETSC_MPICC_RETURN OUTPUT_VARIABLE PETSC_MPICC OUTPUT_STRIP_TRAILING_WHITESPACE) # PETSc specified linker (Fortran compiler + PETSc linking flags) execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "linker" RESULT_VARIABLE PETSC_LINKER_RETURN OUTPUT_VARIABLE PETSC_LINKER OUTPUT_STRIP_TRAILING_WHITESPACE) # Remove temporary makefile, no need to keep it anymore. file (REMOVE_RECURSE ${TEMPDIR}) # Remove duplicate compiler and linker flags string (REGEX MATCHALL "-I([^\" ]+)" TMP_LIST "${petsc_includes}") list (REMOVE_DUPLICATES TMP_LIST) foreach (dir ${TMP_LIST}) set (PETSC_INCLUDES "${PETSC_INCLUDES} ${dir}") endforeach (dir) string (REGEX MATCHALL "-[lLW]([^\" ]+)" TMP_LIST "${petsc_external_lib}") list (REMOVE_DUPLICATES TMP_LIST) foreach (exlib ${TMP_LIST}) set (PETSC_EXTERNAL_LIB "${PETSC_EXTERNAL_LIB} ${exlib}") endforeach (exlib) message ("Found PETSC_DIR:\n${PETSC_DIR}\n" ) message ("Found PETSC_INCLUDES:\n${PETSC_INCLUDES}\n" ) message ("Found PETSC_EXTERNAL_LIB:\n${PETSC_EXTERNAL_LIB}\n") message ("Found PETSC_LINKER:\n${PETSC_LINKER}\n" ) message ("Found MPI Fortran Compiler:\n${PETSC_MPIFC}\n" ) message ("Found MPI C Compiler:\n${PETSC_MPICC}\n" ) # set compiler commands to match PETSc (needs to be done before defining the project) # https://cmake.org/Wiki/CMake_FAQ#How_do_I_use_a_different_compiler.3F set (CMAKE_Fortran_COMPILER "${PETSC_MPIFC}") set (CMAKE_C_COMPILER "${PETSC_MPICC}") #--------------------------------------------------------------------------------------- # Now start to care about DAMASK # DAMASK solver defines project to build string(TOLOWER ${DAMASK_SOLVER} DAMASK_SOLVER) if (DAMASK_SOLVER STREQUAL "grid") project (damask-grid Fortran C) add_definitions (-DGrid) message ("Building Grid Solver\n") elseif (DAMASK_SOLVER STREQUAL "mesh") project (damask-mesh Fortran C) add_definitions (-DMesh) message ("Building Mesh Solver\n") else () message (FATAL_ERROR "Build target (DAMASK_SOLVER) is not defined") endif () list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) if (CMAKE_BUILD_TYPE STREQUAL "") set (CMAKE_BUILD_TYPE "RELEASE") endif () # Predefined sets for OPTIMIZATION/OPENMP based on BUILD_TYPE if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "SYNTAXONLY") set (DEBUG_FLAGS "${DEBUG_FLAGS} -DDEBUG") set (PARALLEL "OFF") set (OPTI "OFF") elseif (CMAKE_BUILD_TYPE STREQUAL "RELEASE") set (PARALLEL "ON") set (OPTI "DEFENSIVE") elseif (CMAKE_BUILD_TYPE STREQUAL "PERFORMANCE") set (PARALLEL "ON") set (OPTI "AGGRESSIVE") endif () # $OPTIMIZATION takes precedence over $BUILD_TYPE defaults if (OPTIMIZATION STREQUAL "" OR NOT DEFINED OPTIMIZATION) set (OPTIMIZATION "${OPTI}") else () set (OPTIMIZATION "${OPTIMIZATION}") endif () # $OPENMP takes precedence over $BUILD_TYPE defaults if (OPENMP STREQUAL "" OR NOT DEFINED OPENMP) set (OPENMP "${PARALLEL}") else () set(OPENMP "${OPENMP}") endif () # syntax check only (mainly for pre-receive hook) if (CMAKE_BUILD_TYPE STREQUAL "SYNTAXONLY") set (BUILDCMD_POST "${BUILDCMD_POST} -fsyntax-only") endif () # Parse DAMASK version from VERSION file find_program (CAT_EXECUTABLE NAMES cat) execute_process (COMMAND ${CAT_EXECUTABLE} ${PROJECT_SOURCE_DIR}/VERSION RESULT_VARIABLE DAMASK_VERSION_RETURN OUTPUT_VARIABLE DAMASK_V OUTPUT_STRIP_TRAILING_WHITESPACE) add_definitions (-DDAMASKVERSION="${DAMASK_V}") # definition of other macros add_definitions (-DPETSc) if (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") include (Compiler-Intel) elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") include (Compiler-GNU) elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "PGI") include (Compiler-PGI) else () message (FATAL_ERROR "Compiler type (CMAKE_Fortran_COMPILER_ID) not recognized") endif () set (CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE} "${BUILDCMD_PRE} ${OPENMP_FLAGS} ${STANDARD_CHECK} ${OPTIMIZATION_FLAGS} ${COMPILE_FLAGS} ${PRECISION_FLAGS}") set (CMAKE_Fortran_LINK_EXECUTABLE "${BUILDCMD_PRE} ${PETSC_LINKER} ${OPENMP_FLAGS} ${OPTIMIZATION_FLAGS} ${LINKER_FLAGS}") if (CMAKE_BUILD_TYPE STREQUAL "DEBUG") set (CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE} "${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}} ${DEBUG_FLAGS}") set (CMAKE_Fortran_LINK_EXECUTABLE "${CMAKE_Fortran_LINK_EXECUTABLE} ${DEBUG_FLAGS}") endif () set (CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE} "${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}} ${PETSC_INCLUDES} ${BUILDCMD_POST}") set (CMAKE_Fortran_LINK_EXECUTABLE "${CMAKE_Fortran_LINK_EXECUTABLE} -o ${PETSC_EXTERNAL_LIB} ${BUILDCMD_POST}") message ("Fortran Compiler Flags:\n${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}}\n") message ("C Compiler Flags:\n${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}\n") message ("Fortran Linker Command:\n${CMAKE_Fortran_LINK_EXECUTABLE}\n") # location of code add_subdirectory (src)