From bffa4b9ac6e877bf603ad2afe924b0ff4a89b84a Mon Sep 17 00:00:00 2001 From: Wenqing Wang <wenqing.wang@ufz.de> Date: Fri, 22 Nov 2013 16:35:08 +0100 Subject: [PATCH] cmake changes for PETSc --- CMakeLists.txt | 37 +- MathLib/CMakeLists.txt | 12 + Tests/CMakeLists.txt | 3 + scripts/cmake/ExternalProjectBoost.cmake | 2 + scripts/cmake/Find.cmake | 4 +- scripts/cmake/findPETSC/FindPETSc.cmake | 317 ++++++++++++++++++ .../FindPackageHandleStandardArgs.cmake | 63 ++++ .../findPETSC/FindPackageMultipass.cmake | 92 +++++ scripts/cmake/findPETSC/README.txt | 4 + .../findPETSC/ResolveCompilerPaths.cmake | 95 ++++++ 10 files changed, 624 insertions(+), 5 deletions(-) mode change 100644 => 100755 CMakeLists.txt mode change 100644 => 100755 MathLib/CMakeLists.txt mode change 100644 => 100755 Tests/CMakeLists.txt mode change 100644 => 100755 scripts/cmake/ExternalProjectBoost.cmake mode change 100644 => 100755 scripts/cmake/Find.cmake create mode 100755 scripts/cmake/findPETSC/FindPETSc.cmake create mode 100755 scripts/cmake/findPETSC/FindPackageHandleStandardArgs.cmake create mode 100755 scripts/cmake/findPETSC/FindPackageMultipass.cmake create mode 100755 scripts/cmake/findPETSC/README.txt create mode 100755 scripts/cmake/findPETSC/ResolveCompilerPaths.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100644 new mode 100755 index 960c8c8512d..69124cff7e8 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,13 @@ SET (OGS_VERSION "${OGS_VERSION_MAJOR}.${OGS_VERSION_MINOR}.${OGS_VERSION_PATCH} SET (OGS_VERSION_AND_PERSONS "${OGS_VERSION} (${OGS_RELEASE_PERSONS})") SET (OGS_DATE "2012-08-20") + +########################### +### Preliminary Options ### +########################### +OPTION(EXTERNAL_BOOST_DOWNLOAD "Should download boost?" OFF) + + ### CMake includes ### INCLUDE(scripts/cmake/CheckTypeSizes.cmake) INCLUDE(scripts/cmake/FindIncludeHeader.cmake) @@ -34,9 +41,9 @@ IF(OGS_COVERAGE AND NOT IS_SUBPROJECT) INCLUDE(scripts/cmake/Coverage.cmake) ENDIF() -############### -### Options ### -############### +#################### +### More Options ### +#################### # Profiling IF((CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) AND GPROF_PATH) @@ -55,6 +62,7 @@ OPTION(OGS_NO_EXTERNAL_LIBS "Builds OGS without any external dependencies." OFF) # Linear solvers OPTION(OGS_USE_LIS "Use Lis" OFF) +OPTION(OGS_USE_PETSC "Use PETSc routines" OFF) # Eigen OPTION(OGS_USE_EIGEN "Use EIGEN for local matrix and vector" ON) @@ -112,6 +120,29 @@ IF(OGS_USE_LIS) ADD_DEFINITIONS(-DUSE_LIS) ENDIF() +IF(OGS_USE_PETSC) + MESSAGE (STATUS "Configuring for PETSc" ) + + SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/scripts/cmake/findPETSC) + FIND_PACKAGE(PETSc REQUIRED) + + include_directories( + ${PETSC_INCLUDES} + ) + + FIND_PACKAGE(MPI) + IF(MPI_FOUND) + SET(CMAKE_C_COMPILER ${MPI_COMPILER}) + SET(CMAKE_CXX_COMPILER ${MPI_COMPILER}) + ELSE(MPI_FOUND) + MESSAGE (FATAL_ERROR "Aborting: MPI implementation is not found!") + ENDIF(MPI_FOUND) + + ADD_DEFINITIONS(-DUSE_PETSC) +ENDIF() + + + IF(OGS_USE_EIGEN) # ADD_DEFINITIONS(-DEIGEN_DEFAULT_DENSE_INDEX_TYPE=std::size_t) ADD_DEFINITIONS(-DEIGEN_INITIALIZE_MATRICES_BY_ZERO) diff --git a/MathLib/CMakeLists.txt b/MathLib/CMakeLists.txt old mode 100644 new mode 100755 index 462cbf3c7a0..bc6255a62f2 --- a/MathLib/CMakeLists.txt +++ b/MathLib/CMakeLists.txt @@ -28,6 +28,11 @@ IF (OGS_USE_LIS) SET ( SOURCES ${SOURCES} ${SOURCES_LINALG_LIS}) ENDIF () +IF (OGS_USE_PETSC) + GET_SOURCE_FILES(SOURCES_LINALG_PETSC LinAlg/PETSc) + SET ( SOURCES ${SOURCES} ${SOURCES_LINALG_PETSC}) +ENDIF () + IF (METIS_FOUND) GET_SOURCE_FILES(SOURCES_LINALG_SPARSE_NESTEDDISSECTION LinAlg/Sparse/NestedDissectionPermutation) SET ( SOURCES ${SOURCES} ${SOURCES_LINALG_SPARSE_NESTEDDISSECTION}) @@ -49,6 +54,13 @@ IF (LIS_FOUND) INCLUDE_DIRECTORIES(${LIS_INCLUDE_DIR}) ENDIF() +IF (OGS_USE_PETSC) + INCLUDE_DIRECTORIES ( LinAlg/PETS ) + + GET_SOURCE_FILES(SOURCES_LINALG_PETSC LinAlg/PETSc) + SET ( SOURCES ${SOURCES} ${SOURCES_LINALG_PETSC}) +ENDIF () + # Create the library ADD_LIBRARY( MathLib STATIC ${SOURCES} ) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt old mode 100644 new mode 100755 index 2194c3e9523..ea63ddac5d7 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -54,6 +54,9 @@ TARGET_LINK_LIBRARIES(testrunner ${BOOST_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) +IF (OGS_USE_PETSC) + TARGET_LINK_LIBRARIES( testrunner ${PETSC_LIBRARIES}) +ENDIF (OGS_USE_PETSC) IF(OGS_BUILD_GUI) INCLUDE(${VTK_USE_FILE}) diff --git a/scripts/cmake/ExternalProjectBoost.cmake b/scripts/cmake/ExternalProjectBoost.cmake old mode 100644 new mode 100755 index 6b6218ad8c3..aa105882310 --- a/scripts/cmake/ExternalProjectBoost.cmake +++ b/scripts/cmake/ExternalProjectBoost.cmake @@ -101,6 +101,7 @@ IF(WIN32) ENDIF() ENDIF() +if(EXTERNAL_BOOST_DOWNLOAD) # Set archive sources SET(BOOST_ARCHIVE_EXT "tar.bz2") SET(BOOST_ARCHIVE_MD5 3a855e0f919107e0ca4de4d84ad3f750) @@ -131,3 +132,4 @@ IF(NOT Boost_INCLUDE_DIRS) ENDIF() LINK_DIRECTORIES( ${source_dir}/stage/lib/ ) +endif(EXTERNAL_BOOST_DOWNLOAD) diff --git a/scripts/cmake/Find.cmake b/scripts/cmake/Find.cmake old mode 100644 new mode 100755 index e6f31ab9ace..0cfd843cfdd --- a/scripts/cmake/Find.cmake +++ b/scripts/cmake/Find.cmake @@ -32,9 +32,9 @@ FIND_PACKAGE(GitHub) FIND_PROGRAM(GIT_TOOL_PATH git HINTS ${GITHUB_BIN_DIR} DOC "The git command line interface") IF(NOT GIT_TOOL_PATH) IF(WIN32) - MESSAGE(FATAL_ERROR "Git not found! Please install GitHub for Windows or Git!") + MESSAGE(STATUS "Git not found! Please install GitHub for Windows or Git!") ELSE() - MESSAGE(FATAL_ERROR "Git not found but is required!") + MESSAGE(STATUS "Git not found but is required!") ENDIF() ENDIF() diff --git a/scripts/cmake/findPETSC/FindPETSc.cmake b/scripts/cmake/findPETSC/FindPETSc.cmake new file mode 100755 index 00000000000..80b1275c65c --- /dev/null +++ b/scripts/cmake/findPETSC/FindPETSc.cmake @@ -0,0 +1,317 @@ +# - Try to find PETSc +# Once done this will define +# +# PETSC_FOUND - system has PETSc +# PETSC_INCLUDES - the PETSc include directories +# PETSC_LIBRARIES - Link these to use PETSc +# PETSC_COMPILER - Compiler used by PETSc, helpful to find a compatible MPI +# PETSC_DEFINITIONS - Compiler switches for using PETSc +# PETSC_MPIEXEC - Executable for running MPI programs +# PETSC_VERSION - Version string (MAJOR.MINOR.SUBMINOR) +# +# Hack: PETSC_VERSION currently decides on the version based on the +# layout. Otherwise we need to run C code to determine the version. +# +# Setting these changes the behavior of the search +# PETSC_DIR - directory in which PETSc resides +# PETSC_ARCH - build architecture +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + + + + +function (petsc_get_version) + if (EXISTS "${PETSC_DIR}/include/petscversion.h") + file (STRINGS "${PETSC_DIR}/include/petscversion.h" vstrings REGEX "#define PETSC_VERSION_(MAJOR|MINOR|SUBMINOR) ") + + + + + foreach (line ${vstrings}) + string (REGEX REPLACE " +" ";" fields ${line}) # break line into three fields (the first is always "#define") + list (GET fields 1 var) + list (GET fields 2 val) + set (${var} ${val} PARENT_SCOPE) + set (${var} ${val}) # Also in local scope so we have access below + endforeach () + if (PETSC_VERSION_RELEASE) + set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}p${PETSC_VERSION_PATCH}" PARENT_SCOPE) + else () + # make dev version compare higher than any patch level of a released version +# set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}.99" PARENT_SCOPE) + set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}" PARENT_SCOPE) + + endif () + else () + message (SEND_ERROR "PETSC_DIR can not be used, ${PETSC_DIR}/include/petscversion.h does not exist") + endif () +endfunction () + + + + + + +find_path (PETSC_DIR include/petsc.h + HINTS ENV PETSC_DIR + PATHS +# /usr/lib/petscdir/3.1 /usr/lib/petscdir/3.0.0 /usr/lib/petscdir/2.3.3 /usr/lib/petscdir/2.3.2 # Debian + /opt/petsc + $ENV{HOME}/petsc + DOC "PETSc Directory") + +find_program (MAKE_EXECUTABLE NAMES make gmake) + + + + +if (PETSC_DIR AND NOT PETSC_ARCH) + set (_petsc_arches + $ENV{PETSC_ARCH} # If set, use environment variable first + linux-gnu-c-debug linux-gnu-c-opt # Debian defaults + x86_64-unknown-linux-gnu i386-unknown-linux-gnu arch-linux2-c-debug ) + set (petscconf "NOTFOUND" CACHE FILEPATH "Cleared" FORCE) + foreach (arch ${_petsc_arches}) + if (NOT PETSC_ARCH) + find_path (petscconf petscconf.h +HINTS ${PETSC_DIR} +PATH_SUFFIXES ${arch}/include bmake/${arch} +NO_DEFAULT_PATH) + if (petscconf) +set (PETSC_ARCH "${arch}" CACHE STRING "PETSc build architecture") + endif (petscconf) + endif (NOT PETSC_ARCH) + endforeach (arch) + set (petscconf "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE) +endif (PETSC_DIR AND NOT PETSC_ARCH) + + + + + + + +set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARIES_KSP LIBRARIES_SNES LIBRARIES_TS + INCLUDE_DIR INCLUDE_CONF) +include (FindPackageMultipass) +find_package_multipass (PETSc petsc_config_current + STATES DIR ARCH + DEPENDENTS INCLUDES LIBRARIES COMPILER MPIEXEC ${petsc_slaves}) + + + + + +# Determine whether the PETSc layout is old-style (through 2.3.3) or +# new-style (>= 3.0.0) +if (EXISTS "${PETSC_DIR}/${PETSC_ARCH}/include/petscconf.h") # > 2.3.3 + set (petsc_conf_rules "${PETSC_DIR}/conf/rules") + set (petsc_conf_variables "${PETSC_DIR}/conf/variables") + +elseif (EXISTS "${PETSC_DIR}/bmake/${PETSC_ARCH}/petscconf.h") # <= 2.3.3 + set (petsc_conf_rules "${PETSC_DIR}/bmake/common/rules") + set (petsc_conf_variables "${PETSC_DIR}/bmake/common/variables") +elseif (PETSC_DIR) + message (SEND_ERROR "The pair PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} do not specify a valid PETSc installation") +endif () + +if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current) + + + + + + petsc_get_version() + + + + # Put variables into environment since they are needed to get + # configuration (petscvariables) in the PETSc makefile + set (ENV{PETSC_DIR} "${PETSC_DIR}") + set (ENV{PETSC_ARCH} "${PETSC_ARCH}") + + # A temporary makefile to probe the PETSc configuration + set (petsc_config_makefile "${PROJECT_BINARY_DIR}/Makefile.petsc") + file (WRITE "${petsc_config_makefile}" +"## This file was autogenerated by FindPETSc.cmake + PETSC_DIR = ${PETSC_DIR} + PETSC_ARCH = ${PETSC_ARCH} +include ${petsc_conf_rules} +include ${petsc_conf_variables} +show: + -@echo -n \${\${VARIABLE}} +") + + + + + + macro (PETSC_GET_VARIABLE name var) + set (${var} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) + execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} show VARIABLE=${name} + OUTPUT_VARIABLE ${var} + RESULT_VARIABLE petsc_return) + endmacro (PETSC_GET_VARIABLE) + petsc_get_variable (PETSC_LIB_DIR petsc_lib_dir) + petsc_get_variable (PETSC_EXTERNAL_LIB_BASIC petsc_libs_external) + petsc_get_variable (PETSC_CCPPFLAGS petsc_cpp_line) + petsc_get_variable (PETSC_INCLUDE petsc_include) + petsc_get_variable (PCC petsc_cc) + petsc_get_variable (MPIEXEC petsc_mpiexec) + # We are done with the temporary Makefile, calling PETSC_GET_VARIABLE after this point is invalid! + file (REMOVE ${petsc_config_makefile}) + + include (ResolveCompilerPaths) + # Extract include paths and libraries from compile command line + resolve_includes (petsc_includes_all "${petsc_cpp_line}") + + + macro (PETSC_FIND_LIBRARY suffix name) + set (PETSC_LIBRARY_${suffix} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) # Clear any stale value, if we got here, we need to find it again + find_library (PETSC_LIBRARY_${suffix} NAMES ${name} HINTS ${petsc_lib_dir} NO_DEFAULT_PATH) + set (PETSC_LIBRARIES_${suffix} "${PETSC_LIBRARY_${suffix}}") + mark_as_advanced (PETSC_LIBRARY_${suffix}) + endmacro (PETSC_FIND_LIBRARY suffix name) + + # Look for petscvec first, if it doesn't exist, we must be using single-library + petsc_find_library (VEC petscvec) + if (PETSC_LIBRARY_VEC) + petsc_find_library (SYS "petscsys;petsc") # libpetscsys is called libpetsc prior to 3.1 (when single-library was introduced) + petsc_find_library (MAT petscmat) + petsc_find_library (DM petscdm) + petsc_find_library (KSP petscksp) + petsc_find_library (SNES petscsnes) + petsc_find_library (TS petscts) + macro (PETSC_JOIN libs deps) + list (APPEND PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${deps}}) + endmacro (PETSC_JOIN libs deps) + petsc_join (VEC SYS) + petsc_join (MAT VEC) + petsc_join (DM MAT) + petsc_join (KSP DM) + petsc_join (SNES KSP) + petsc_join (TS SNES) + petsc_join (ALL TS) + else () + set (PETSC_LIBRARY_VEC "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) # There is no libpetscvec + petsc_find_library (SINGLE petsc) + foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) + set (PETSC_LIBRARIES_${pkg} "${PETSC_LIBRARY_SINGLE}") + endforeach () + endif () + if (PETSC_LIBRARY_TS) + message (STATUS "Recognized PETSc install with separate libraries for each package") + else () + message (STATUS "Recognized PETSc install with single library for all packages") + endif () + + + + + include (CheckCSourceRuns) + macro (PETSC_TEST_RUNS includes libraries runs) + if (PETSC_VERSION VERSION_GREATER 3.1) + set (_PETSC_TSDestroy "TSDestroy(&ts)") + else () + set (_PETSC_TSDestroy "TSDestroy(ts)") + endif () + multipass_c_source_runs ("${includes}" "${libraries}" " +static const char help[] = \"PETSc test program.\"; +#include <petscts.h> +int main(int argc,char *argv[]) { +PetscErrorCode ierr; +TS ts; + +ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); +ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); +ierr = TSSetFromOptions(ts);CHKERRQ(ierr); +ierr = ${_PETSC_TSDestroy};CHKERRQ(ierr); +ierr = PetscFinalize();CHKERRQ(ierr); + +return 0; +} +" ${runs}) + if (${${runs}}) + set (PETSC_EXECUTABLE_RUNS "YES" CACHE BOOL +"Can the system successfully run a PETSc executable? This variable can be manually set to \"YES\" to force CMake to accept a given PETSc configuration, but this will almost always result in a broken build. If you change PETSC_DIR, PETSC_ARCH, or PETSC_CURRENT you would have to reset this variable." FORCE) + endif (${${runs}}) + endmacro (PETSC_TEST_RUNS) + + find_path (PETSC_INCLUDE_DIR petscts.h HINTS "${PETSC_DIR}" PATH_SUFFIXES include NO_DEFAULT_PATH) + find_path (PETSC_INCLUDE_CONF petscconf.h HINTS "${PETSC_DIR}" PATH_SUFFIXES "${PETSC_ARCH}/include" "bmake/${PETSC_ARCH}" NO_DEFAULT_PATH) + mark_as_advanced (PETSC_INCLUDE_DIR PETSC_INCLUDE_CONF) + set (petsc_includes_minimal ${PETSC_INCLUDE_CONF} ${PETSC_INCLUDE_DIR}) + + + + petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_minimal) + + + if (petsc_works_minimal) + message (STATUS "Minimal PETSc includes and libraries work. This probably means we are building with shared libs.") + set (petsc_includes_needed "${petsc_includes_minimal}") + else (petsc_works_minimal) # Minimal includes fail, see if just adding full includes fixes it + petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_allincludes) + if (petsc_works_allincludes) # It does, we just need all the includes ( + message (STATUS "PETSc requires extra include paths, but links correctly with only interface libraries. This is an unexpected configuration (but it seems to work fine).") + set (petsc_includes_needed ${petsc_includes_all}) + else (petsc_works_allincludes) # We are going to need to link the external libs explicitly + resolve_libraries (petsc_libraries_external "${petsc_libs_external}") + foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) +list (APPEND PETSC_LIBRARIES_${pkg} ${petsc_libraries_external}) + endforeach (pkg) + + + + + petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_alllibraries) + if (petsc_works_alllibraries) +message (STATUS "PETSc only need minimal includes, but requires explicit linking to all dependencies. This is expected when PETSc is built with static libraries.") +set (petsc_includes_needed ${petsc_includes_minimal}) + else (petsc_works_alllibraries) +# It looks like we really need everything, should have listened to Matt +set (petsc_includes_needed ${petsc_includes_all}) +petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_all) +if (petsc_works_all) # We fail anyways +message (STATUS "PETSc requires extra include paths and explicit linking to all dependencies. This probably means you have static libraries and something unexpected in PETSc headers.") +else (petsc_works_all) # We fail anyways +message (STATUS "PETSc could not be used, maybe the install is broken.") +endif (petsc_works_all) + endif (petsc_works_alllibraries) + endif (petsc_works_allincludes) + endif (petsc_works_minimal) + + # We do an out-of-source build so __FILE__ will be an absolute path, hence __INSDIR__ is superfluous + if (${PETSC_VERSION} VERSION_LESS 3.1) + set (PETSC_DEFINITIONS "-D__SDIR__=\"\"" CACHE STRING "PETSc definitions" FORCE) + else () + set (PETSC_DEFINITIONS "-D__INSDIR__=" CACHE STRING "PETSc definitions" FORCE) + endif () + # Sometimes this can be used to assist FindMPI.cmake + set (PETSC_MPIEXEC ${petsc_mpiexec} CACHE FILEPATH "Executable for running PETSc MPI programs" FORCE) + set (PETSC_INCLUDES ${petsc_includes_needed} CACHE STRING "PETSc include path" FORCE) + set (PETSC_LIBRARIES ${PETSC_LIBRARIES_ALL} CACHE STRING "PETSc libraries" FORCE) + set (PETSC_COMPILER ${petsc_cc} CACHE FILEPATH "PETSc compiler" FORCE) + # Note that we have forced values for all these choices. If you + # change these, you are telling the system to trust you that they + # work. It is likely that you will end up with a broken build. + mark_as_advanced (PETSC_INCLUDES PETSC_LIBRARIES PETSC_COMPILER PETSC_DEFINITIONS PETSC_MPIEXEC PETSC_EXECUTABLE_RUNS) +endif () + + + # message (STATUS "dddd---${PETSC_INCLUDES}--${PETSC_LIBRARIES}-- ${petsc_includes_minimal} ") +# message (STATUS "dddd---${PETSC_EXECUTABLE_RUNS} ggggg ${PETSC_DEFINITIONS}") + + set (PETSC_EXECUTABLE_RUNS "YES" CACHE BOOL +"Can the system successfully run a PETSc executable? This variable can be manually set to \"YES\" to force CMake to accept a given PETSc configuration, but this will almost always result in a broken build. If you change PETSC_DIR, PETSC_ARCH, or PETSC_CURRENT you would have to reset this variable." FORCE) + + + +include (FindPackageHandleStandardArgs) +find_package_handle_standard_args (PETSc + "PETSc could not be found. Be sure to set PETSC_DIR and PETSC_ARCH." + PETSC_INCLUDES PETSC_LIBRARIES PETSC_EXECUTABLE_RUNS) + diff --git a/scripts/cmake/findPETSC/FindPackageHandleStandardArgs.cmake b/scripts/cmake/findPETSC/FindPackageHandleStandardArgs.cmake new file mode 100755 index 00000000000..fb5ccb0c943 --- /dev/null +++ b/scripts/cmake/findPETSC/FindPackageHandleStandardArgs.cmake @@ -0,0 +1,63 @@ +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME (DEFAULT_MSG|"Custom failure message") VAR1 ... ) +# This macro is intended to be used in FindXXX.cmake modules files. +# It handles the REQUIRED and QUIET argument to FIND_PACKAGE() and +# it also sets the <UPPERCASED_NAME>_FOUND variable. +# The package is found if all variables listed are TRUE. +# Example: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) +# +# LibXml2 is considered to be found, if both LIBXML2_LIBRARIES and +# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. +# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, +# independent whether QUIET was used or not. +# If it is found, the location is reported using the VAR1 argument, so +# here a message "Found LibXml2: /usr/lib/libxml2.so" will be printed out. +# If the second argument is DEFAULT_MSG, the message in the failure case will +# be "Could NOT find LibXml2", if you don't like this message you can specify +# your own custom failure message there. + +MACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FAIL_MSG _VAR1 ) + + IF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + IF (${_NAME}_FIND_REQUIRED) + SET(_FAIL_MESSAGE "Could not find REQUIRED package ${_NAME}") + ELSE (${_NAME}_FIND_REQUIRED) + SET(_FAIL_MESSAGE "Could not find OPTIONAL package ${_NAME}") + ENDIF (${_NAME}_FIND_REQUIRED) + ELSE("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + SET(_FAIL_MESSAGE "${_FAIL_MSG}") + ENDIF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + + + +#MESSAGE (STATUS "PETSc dir...." ${DEFAULT_MSG}) + + + STRING(TOUPPER ${_NAME} _NAME_UPPER) + + SET(${_NAME_UPPER}_FOUND TRUE) + IF(NOT ${_VAR1}) + SET(${_NAME_UPPER}_FOUND FALSE) + ENDIF(NOT ${_VAR1}) + + FOREACH(_CURRENT_VAR ${ARGN}) + IF(NOT ${_CURRENT_VAR}) + SET(${_NAME_UPPER}_FOUND FALSE) + ENDIF(NOT ${_CURRENT_VAR}) + ENDFOREACH(_CURRENT_VAR) + + IF (${_NAME_UPPER}_FOUND) + IF (NOT ${_NAME}_FIND_QUIETLY) + MESSAGE(STATUS "Found ${_NAME}: ${${_VAR1}}") + ENDIF (NOT ${_NAME}_FIND_QUIETLY) + ELSE (${_NAME_UPPER}_FOUND) + IF (${_NAME}_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "${_FAIL_MESSAGE}") + ELSE (${_NAME}_FIND_REQUIRED) + IF (NOT ${_NAME}_FIND_QUIETLY) + MESSAGE(STATUS "${_FAIL_MESSAGE}") + ENDIF (NOT ${_NAME}_FIND_QUIETLY) + ENDIF (${_NAME}_FIND_REQUIRED) + ENDIF (${_NAME_UPPER}_FOUND) +ENDMACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS) diff --git a/scripts/cmake/findPETSC/FindPackageMultipass.cmake b/scripts/cmake/findPETSC/FindPackageMultipass.cmake new file mode 100755 index 00000000000..db3cdee9f40 --- /dev/null +++ b/scripts/cmake/findPETSC/FindPackageMultipass.cmake @@ -0,0 +1,92 @@ +# PackageMultipass - this module defines two macros +# +# FIND_PACKAGE_MULTIPASS (Name CURRENT +# STATES VAR0 VAR1 ... +# DEPENDENTS DEP0 DEP1 ...) +# +# This function creates a cache entry <UPPERCASED-Name>_CURRENT which +# the user can set to "NO" to trigger a reconfiguration of the package. +# The first time this function is called, the values of +# <UPPERCASED-Name>_VAR0, ... are saved. If <UPPERCASED-Name>_CURRENT +# is false or if any STATE has changed since the last time +# FIND_PACKAGE_MULTIPASS() was called, then CURRENT will be set to "NO", +# otherwise CURRENT will be "YES". IF not CURRENT, then +# <UPPERCASED-Name>_DEP0, ... will be FORCED to NOTFOUND. +# Example: +# find_path (FOO_DIR include/foo.h) +# FIND_PACKAGE_MULTIPASS (Foo foo_current +# STATES DIR +# DEPENDENTS INCLUDES LIBRARIES) +# if (NOT foo_current) +# # Make temporary files, run programs, etc, to determine FOO_INCLUDES and FOO_LIBRARIES +# endif (NOT foo_current) +# +# MULTIPASS_C_SOURCE_RUNS (Name INCLUDES LIBRARIES SOURCE RUNS) +# Always runs the given test, use this when you need to re-run tests +# because parent variables have made old cache entries stale. + +macro (FIND_PACKAGE_MULTIPASS _name _current) + string (TOUPPER ${_name} _NAME) + set (_args ${ARGV}) + list (REMOVE_AT _args 0 1) + + set (_states_current "YES") + list (GET _args 0 _cmd) + if (_cmd STREQUAL "STATES") + list (REMOVE_AT _args 0) + list (GET _args 0 _state) + while (_state AND NOT _state STREQUAL "DEPENDENTS") + # The name of the stored value for the given state + set (_stored_var PACKAGE_MULTIPASS_${_NAME}_${_state}) + if (NOT "${${_stored_var}}" STREQUAL "${${_NAME}_${_state}}") +set (_states_current "NO") + endif (NOT "${${_stored_var}}" STREQUAL "${${_NAME}_${_state}}") + set (${_stored_var} "${${_NAME}_${_state}}" CACHE INTERNAL "Stored state for ${_name}." FORCE) + list (REMOVE_AT _args 0) + list (GET _args 0 _state) + endwhile (_state AND NOT _state STREQUAL "DEPENDENTS") + endif (_cmd STREQUAL "STATES") + + set (_stored ${_NAME}_CURRENT) + if (NOT ${_stored}) + set (${_stored} "YES" CACHE BOOL "Is the configuration for ${_name} current? Set to \"NO\" to reconfigure." FORCE) + set (_states_current "NO") + endif (NOT ${_stored}) + + set (${_current} ${_states_current}) + if (NOT ${_current} AND PACKAGE_MULTIPASS_${_name}_CALLED) + message (STATUS "Clearing ${_name} dependent variables") + # Clear all the dependent variables so that the module can reset them + list (GET _args 0 _cmd) + if (_cmd STREQUAL "DEPENDENTS") + list (REMOVE_AT _args 0) + foreach (dep ${_args}) +set (${_NAME}_${dep} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) + endforeach (dep) + endif (_cmd STREQUAL "DEPENDENTS") + set (${_NAME}_FOUND "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) + endif () + set (PACKAGE_MULTIPASS_${name}_CALLED YES CACHE INTERNAL "Private" FORCE) +endmacro (FIND_PACKAGE_MULTIPASS) + + +macro (MULTIPASS_C_SOURCE_RUNS includes libraries source runs) + include (CheckCSourceRuns) + # This is a ridiculous hack. CHECK_C_SOURCE_* thinks that if the + # *name* of the return variable doesn't change, then the test does + # not need to be re-run. We keep an internal count which we + # increment to guarantee that every test name is unique. If we've + # gotten here, then the configuration has changed enough that the + # test *needs* to be rerun. + if (NOT MULTIPASS_TEST_COUNT) + set (MULTIPASS_TEST_COUNT 00) + endif (NOT MULTIPASS_TEST_COUNT) + math (EXPR _tmp "${MULTIPASS_TEST_COUNT} + 1") # Why can't I add to a cache variable? + set (MULTIPASS_TEST_COUNT ${_tmp} CACHE INTERNAL "Unique test ID") + set (testname MULTIPASS_TEST_${MULTIPASS_TEST_COUNT}_${runs}) + set (CMAKE_REQUIRED_INCLUDES ${includes}) + set (CMAKE_REQUIRED_LIBRARIES ${libraries}) + check_c_source_runs ("${source}" ${testname}) + set (${runs} "${${testname}}") +endmacro (MULTIPASS_C_SOURCE_RUNS) + diff --git a/scripts/cmake/findPETSC/README.txt b/scripts/cmake/findPETSC/README.txt new file mode 100755 index 00000000000..f398e0bf621 --- /dev/null +++ b/scripts/cmake/findPETSC/README.txt @@ -0,0 +1,4 @@ +findPETSC package is created by Jed Brown +https://github.com/jedbrown/cmake-modules/blob/master/FindPETSc.cmake + +Minor changes are applied. diff --git a/scripts/cmake/findPETSC/ResolveCompilerPaths.cmake b/scripts/cmake/findPETSC/ResolveCompilerPaths.cmake new file mode 100755 index 00000000000..d7c86ca1f2a --- /dev/null +++ b/scripts/cmake/findPETSC/ResolveCompilerPaths.cmake @@ -0,0 +1,95 @@ +# ResolveCompilerPaths - this module defines two macros +# +# RESOLVE_LIBRARIES (XXX_LIBRARIES LINK_LINE) +# This macro is intended to be used by FindXXX.cmake modules. +# It parses a compiler link line and resolves all libraries +# (-lfoo) using the library path contexts (-L/path) in scope. +# The result in XXX_LIBRARIES is the list of fully resolved libs. +# Example: +# +# RESOLVE_LIBRARIES (FOO_LIBRARIES "-L/A -la -L/B -lb -lc -ld") +# +# will be resolved to +# +# FOO_LIBRARIES:STRING="/A/liba.so;/B/libb.so;/A/libc.so;/usr/lib/libd.so" +# +# if the filesystem looks like +# +# /A: liba.so libc.so +# /B: liba.so libb.so +# /usr/lib: liba.so libb.so libc.so libd.so +# +# and /usr/lib is a system directory. +# +# Note: If RESOLVE_LIBRARIES() resolves a link line differently from +# the native linker, there is a bug in this macro (please report it). +# +# RESOLVE_INCLUDES (XXX_INCLUDES INCLUDE_LINE) +# This macro is intended to be used by FindXXX.cmake modules. +# It parses a compile line and resolves all includes +# (-I/path/to/include) to a list of directories. Other flags are ignored. +# Example: +# +# RESOLVE_INCLUDES (FOO_INCLUDES "-I/A -DBAR='\"irrelevant -I/string here\"' -I/B") +# +# will be resolved to +# +# FOO_INCLUDES:STRING="/A;/B" +# +# assuming both directories exist. +# Note: as currently implemented, the -I/string will be picked up mistakenly (cry, cry) + +macro (RESOLVE_LIBRARIES LIBS LINK_LINE) + string (REGEX MATCHALL "((-L|-l|-Wl)([^\" ]+|\"[^\"]+\")|/[^\" ]+(a|so|dll))" _all_tokens "${LINK_LINE}") + set (_libs_found) + set (_directory_list) + foreach (token ${_all_tokens}) + if (token MATCHES "-L([^\" ]+|\"[^\"]+\")") + # If it's a library path, add it to the list + string (REGEX REPLACE "^-L" "" token ${token}) + string (REGEX REPLACE "//" "/" token ${token}) + list (APPEND _directory_list ${token}) + elseif (token MATCHES "^(-l([^\" ]+|\"[^\"]+\")|/[^\" ]+(a|so|dll))") + # It's a library, resolve the path by looking in the list and then (by default) in system directories + string (REGEX REPLACE "^-l" "" token ${token}) + set (_root) + if (token MATCHES "^/") # We have an absolute path, add root to the search path + set (_root "/") + endif (token MATCHES "^/") + set (_lib "NOTFOUND" CACHE FILEPATH "Cleared" FORCE) + find_library (_lib ${token} HINTS ${_directory_list} ${_root}) + if (_lib) + string (REPLACE "//" "/" _lib ${_lib}) + list (APPEND _libs_found ${_lib}) + else (_lib) + message (STATUS "Unable to find library ${token}") + endif (_lib) + endif (token MATCHES "-L([^\" ]+|\"[^\"]+\")") + endforeach (token) + set (_lib "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE) + # only the LAST occurence of each library is required since there should be no circular dependencies + if (_libs_found) + list (REVERSE _libs_found) + list (REMOVE_DUPLICATES _libs_found) + list (REVERSE _libs_found) + endif (_libs_found) + set (${LIBS} "${_libs_found}") +endmacro (RESOLVE_LIBRARIES) + +macro (RESOLVE_INCLUDES INCS COMPILE_LINE) + string (REGEX MATCHALL "-I([^\" ]+|\"[^\"]+\")" _all_tokens "${COMPILE_LINE}") + set (_incs_found) + foreach (token ${_all_tokens}) + string (REGEX REPLACE "^-I" "" token ${token}) + string (REGEX REPLACE "//" "/" token ${token}) + if (EXISTS ${token}) + list (APPEND _incs_found ${token}) + else (EXISTS ${token}) + message (STATUS "Include directory ${token} does not exist") + endif (EXISTS ${token}) + endforeach (token) + list (REMOVE_DUPLICATES _incs_found) + set (${INCS} "${_incs_found}") +endmacro (RESOLVE_INCLUDES) + + -- GitLab