diff --git a/modules/find/FindPETSC.cmake b/modules/find/FindPETSC.cmake deleted file mode 100644 index cd1e3b93f8900588e3175485a15416ee91f29b67..0000000000000000000000000000000000000000 --- a/modules/find/FindPETSC.cmake +++ /dev/null @@ -1,210 +0,0 @@ -# - Try to find PETSc -# Once done this will define -# -# PETSC_FOUND - system has PETSc -# PETSC_INCLUDE_DIRS - include directories for PETSc -# PETSC_LIBRARY_DIRS - library directories for PETSc -# PETSC_LIBRARIES - libraries for PETSc -# PETSC_STATIC_LIBRARIES - libraries for PETSc (static linking, undefined if not required) -# PETSC_VERSION - version for PETSc -# PETSC_VERSION_MAJOR - First number in PETSC_VERSION -# PETSC_VERSION_MINOR - Second number in PETSC_VERSION -# PETSC_VERSION_SUBMINOR - Third number in PETSC_VERSION -# PETSC_INT_SIZE - sizeof(PetscInt) -# -#============================================================================= -# Copyright (C) 2010-2016 Garth N. Wells, Anders Logg and Johannes Ring -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -#============================================================================= - -# Outline: -# 1. Get flags from PETSc-generated pkg-config file -# 2. Test compile and run program using shared library linking -# 3. If shared library linking fails, test with static library linking - -# Load pkg-config module (provided by CMake) -find_package(PkgConfig REQUIRED) - -# Find PETSc pkg-config file. Note: craypetsc_real is on Cray systems -set(ENV{PKG_CONFIG_PATH} "$ENV{CRAY_PETSC_PREFIX_DIR}/lib/pkgconfig:$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib/pkgconfig:$ENV{PETSC_DIR}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}") -pkg_search_module(PETSC craypetsc_real PETSc) - -# Extract major, minor, etc from version string -if (PETSC_VERSION) - string(REPLACE "." ";" VERSION_LIST ${PETSC_VERSION}) - list(GET VERSION_LIST 0 PETSC_VERSION_MAJOR) - list(GET VERSION_LIST 1 PETSC_VERSION_MINOR) - list(GET VERSION_LIST 2 PETSC_VERSION_SUBMINOR) -endif() - -# Configure PETSc IMPORT (this involves creating an 'imported' target -# and attaching 'properties') -if (PETSC_FOUND AND NOT TARGET PETSC::petsc) - add_library(PETSC::petsc INTERFACE IMPORTED) - - # Add include paths - set_property(TARGET PETSC::petsc PROPERTY - INTERFACE_INCLUDE_DIRECTORIES ${PETSC_INCLUDE_DIRS}) - - # Add libraries - unset(_libs) - foreach (lib ${PETSC_LIBRARIES}) - find_library(LIB_${lib} NAMES ${lib} PATHS ${PETSC_LIBRARY_DIRS} NO_DEFAULT_PATH) - list(APPEND _libs ${LIB_${lib}}) - endforeach() - set_property(TARGET PETSC::petsc PROPERTY INTERFACE_LINK_LIBRARIES "${_libs}") -endif() - -# Configure PETSc 'static' IMPORT (this involves creating an -# 'imported' target and attaching 'properties') -if (PETSC_FOUND AND NOT TARGET PETSC::petsc_static) - add_library(PETSC::petsc_static INTERFACE IMPORTED) - - # Add libraries (static) - unset(_libs) - foreach (lib ${PETSC_STATIC_LIBRARIES}) - find_library(LIB_${lib} ${lib} HINTS ${PETSC_STATIC_LIBRARY_DIRS}) - list(APPEND _libs ${LIB_${lib}}) - endforeach() - set_property(TARGET PETSC::petsc_static PROPERTY INTERFACE_LINK_LIBRARIES "${_libs}") -endif() - -# Attempt to build and run PETSc test program -if (DOLFIN_SKIP_BUILD_TESTS) - - # Assume PETSc works - set(PETSC_TEST_RUNS TRUE) - -elseif (PETSC_FOUND) - - # Create PETSc test program - set(PETSC_TEST_LIB_CPP - "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/petsc_test_lib.cpp") - file(WRITE ${PETSC_TEST_LIB_CPP} " -#include \"petscts.h\" -#include \"petsc.h\" -int main() -{ - PetscErrorCode ierr; - TS ts; - int argc = 0; - char** argv = NULL; - ierr = PetscInitialize(&argc, &argv, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr); - ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); - ierr = TSSetFromOptions(ts);CHKERRQ(ierr); - ierr = TSDestroy(&ts);CHKERRQ(ierr); - ierr = PetscFinalize();CHKERRQ(ierr); - return 0; -} -") - - # Add MPI variables if MPI has been found - if (MPI_C_FOUND) - set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${MPI_C_INCLUDE_PATH}) - set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${MPI_C_LIBRARIES}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${MPI_C_COMPILE_FLAGS}") - endif() - - # Try to run test program (shared linking) - try_run( - PETSC_TEST_LIB_EXITCODE - PETSC_TEST_LIB_COMPILED - ${CMAKE_CURRENT_BINARY_DIR} - ${PETSC_TEST_LIB_CPP} - CMAKE_FLAGS - "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}" - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}" - LINK_LIBRARIES PETSC::petsc - COMPILE_OUTPUT_VARIABLE PETSC_TEST_LIB_COMPILE_OUTPUT - RUN_OUTPUT_VARIABLE PETSC_TEST_LIB_OUTPUT) - - # Check program output - if (PETSC_TEST_LIB_COMPILED AND PETSC_TEST_LIB_EXITCODE EQUAL 0) - - message(STATUS "Test PETSC_TEST_RUNS with shared library linking - Success") - set(PETSC_TEST_RUNS TRUE) - - # Static libraries not required, so unset - set_property(TARGET PETSC::petsc_static PROPERTY INTERFACE_LINK_LIBRARIES) - - else() - - message(STATUS "Test PETSC_TEST_RUNS with shared library linking - Failed") - - # Add MPI variables if MPI has been found - if (MPI_C_FOUND) - set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${MPI_C_INCLUDE_PATH}) - set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${MPI_C_LIBRARIES}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${MPI_C_COMPILE_FLAGS}") - endif() - - # Try to run test program (static linking) - try_run( - PETSC_TEST_LIB_EXITCODE - PETSC_TEST_LIB_COMPILED - ${CMAKE_CURRENT_BINARY_DIR} - ${PETSC_TEST_LIB_CPP} - CMAKE_FLAGS - "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}" - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}" - LINK_LIBRARIES PETSC::petsc PETSC::petsc_static - COMPILE_OUTPUT_VARIABLE PETSC_TEST_LIB_COMPILE_OUTPUT - RUN_OUTPUT_VARIABLE PETSC_TEST_LIB_OUTPUT) - - if (PETSC_TEST_LIB_COMPILED AND PETSC_TEST_LIB_EXITCODE EQUAL 0) - message(STATUS "Test PETSC_TEST_RUNS static linking - Success") - set(PETSC_TEST_RUNS TRUE) - else() - message(STATUS "Test PETSC_TEST_RUNS static linking - Failed") - set(PETSC_TEST_RUNS FALSE) - endif() - - endif() -endif() - -# Check sizeof(PetscInt) -if (PETSC_INCLUDE_DIRS) - include(CheckTypeSize) - set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${PETSC_INCLUDE_DIRS}) - set(CMAKE_EXTRA_INCLUDE_FILES petscsys.h) - check_type_size("PetscInt" PETSC_INT_SIZE) - - unset(CMAKE_EXTRA_INCLUDE_FILES) - unset(CMAKE_REQUIRED_INCLUDES) -endif() - -# Standard package handling -include(FindPackageHandleStandardArgs) -if (PETSC_FOUND) - find_package_handle_standard_args(PETSc - REQUIRED_VARS PETSC_FOUND PETSC_TEST_RUNS VERSION_VAR PETSC_VERSION - FAIL_MESSAGE "PETSc could not be configured.") -else() - find_package_handle_standard_args(PETSc - REQUIRED_VARS PETSC_FOUND - FAIL_MESSAGE "PETSc could not be found. Be sure to set PETSC_DIR.") -endif() diff --git a/modules/find/FindPETSc.cmake b/modules/find/FindPETSc.cmake new file mode 100644 index 0000000000000000000000000000000000000000..c38f253f16b2654e22e32a01338a4bf42f24359d --- /dev/null +++ b/modules/find/FindPETSc.cmake @@ -0,0 +1,204 @@ +# +# @copyright (c) 2018 Inria. All rights reserved. +# +# Marc Fuentes +# Florent Pruvost +# +# https://gitlab.inria.fr/sed-bso/findPetsc +# +# INPUT +# ----- +# +# PETSc is not installed in a standard way on Unix systems so that +# this module requires hints to know where PETSc is installed. Please +# give the installation directory (contains ./include/petsc.h, ./lib/, etc): +# 1. by setting the PETSC_DIR variable +# a. as an environment variable, e.g. +# $ export PETSC_DIR=/usr/lib/petscdir/3.6.2/x86_64-linux-gnu-real +# b. or as an CMake variable, e.g. +# $ cmake .. -DPETSC_DIR==/usr/lib/petscdir/3.6.2/x86_64-linux-gnu-real +# 2. or by using the pkg-config mechanism, e.g. +# $ export PKG_CONFIG_PATH=/usr/lib/petscdir/3.6.2/x86_64-linux-gnu-real/lib/pkgconfig:$PKG_CONFIG_PATH +# +# OUTPUT +# ------- +# PETSC_INCLUDE_DIRS - the PETSc include directories +# PETSC_LIBRARIES - Link these to use PETSc +# PETSC_LIBRARY_DIRS - Link these to use PETSc +# PETSC_MPIEXEC - Executable for running MPI programs +# +# if pkg-config is used i.e. pkgconfig installed, PETSc.pc file path +# in the PKG_CONFIG_PATH environment variable and PETSC_DIR not set +# then the following variables are set (or empty) +# +# PETSC_VERSION ... version of the module +# PETSC_PREFIX ... prefix-directory of the module +# PETSC_INCLUDEDIR ... include-dir of the module +# PETSC_LIBDIR ... lib-dir of the module +# +# <PREFIX>_FOUND ... set to 1 if module(s) exist +# <PREFIX>_LIBRARIES ... only the libraries (w/o the '-l') +# <PREFIX>_LIBRARY_DIRS ... the paths of the libraries (w/o the '-L') +# <PREFIX>_LDFLAGS ... all required linker flags +# <PREFIX>_LDFLAGS_OTHER ... all other linker flags +# <PREFIX>_INCLUDE_DIRS ... the '-I' preprocessor flags (w/o the '-I') +# <PREFIX>_CFLAGS ... all required cflags +# <PREFIX>_CFLAGS_OTHER ... the other compiler flags +# +# <PREFIX> = PETSC for common case +# <PREFIX> = PETSC_STATIC for static linking +# +# find_package(PETSc [QUIET] [REQUIRED]) +# +# Setting these changes the behavior of the search +# PETSC_DIR - directory in which PETSc is installed +# PETSC_ARCH - build architecture + +# create a cmake cache variable +set(PETSC_DIR "" CACHE PATH "Installation directory of PETSC library") +if (NOT PETSc_FIND_QUIETLY AND NOT PETSC_DIR) + message(STATUS "A cache variable, namely PETSC_DIR, has been set + to specify a custom installation directory of PETSC") +endif() + +# Use pkg-config to detect include/library dirs (if pkg-config is available) +# ------------------------------------------------------------------------------------- +include(FindPkgConfig) +find_package(PkgConfig QUIET) +if( PKG_CONFIG_EXECUTABLE AND NOT PETSC_DIR ) + pkg_search_module(PETSC PETSc) + if (NOT PETSc_FIND_QUIETLY) + if (PETSC_FOUND AND PETSC_LIBRARIES) + message(STATUS "Looking for PETSC - found using PkgConfig") + else() + message(STATUS "Looking for PETSC - not found using PkgConfig." + "\n Perhaps you should add the directory containing PETSc.pc to" + "\n the PKG_CONFIG_PATH environment variable.") + endif() + endif() + set(PETSC_DIR "${PETSC_PREFIX}") +endif() + +# consider using the env. var. PETSC_DIR if not directly given through the CMake cache var. +if (NOT PETSC_DIR AND DEFINED ENV{PETSC_DIR}) + set(PETSC_DIR "$ENV{PETSC_DIR}") +endif() + +if (PETSC_DIR) + if (EXISTS ${PETSC_DIR}) + if (EXISTS ${PETSC_DIR}/include/petsc.h) + if (NOT PETSc_FIND_QUIETLY) + message(STATUS "PETSC_DIR = ${PETSC_DIR} contains include/petsc.h") + endif() + else() + if (PETSc_FIND_REQUIRED) + message(FATAL_ERROR "include/petsc.h not found in PETSC_DIR = ${PETSC_DIR}") + endif() + endif() + else() + if (PETSc_FIND_REQUIRED) + message(FATAL_ERROR "PETSC_DIR defined, but ${PETSC_DIR} does not exist") + endif() + endif() +else() + if (PETSc_FIND_REQUIRED) + message(FATAL_ERROR "\ +PETSc is not installed in a standard way on Unix systems so that +this module requires hints to know where PETSc is installed. Please +give the installation directory (contains ./include/petsc.h, ./lib/, etc): +1. by setting the PETSC_DIR variable + a. as an environment variable, e.g. + $ export PETSC_DIR=/usr/lib/petscdir/3.6.2/x86_64-linux-gnu-real + b. or as an CMake variable, e.g. + $ cmake .. -DPETSC_DIR==/usr/lib/petscdir/3.6.2/x86_64-linux-gnu-real +2. or by using the pkg-config mechanism, e.g. + $ export PKG_CONFIG_PATH=/usr/lib/petscdir/3.6.2/x86_64-linux-gnu-real/lib/pkgconfig:$PKG_CONFIG_PATH\ + ") + endif() +endif() + +find_file(petscconf NAMES petscconf.h HINTS ${PETSC_DIR}/include) +if (petscconf) + if (NOT PETSc_FIND_QUIETLY) + message(STATUS "petscconf.h is located ad ${petscconf}") + endif() +else() + if (PETSc_FIND_REQUIRED) + message(FATAL_ERROR "\petscconf.h not found + we must find it into PETSC_DIR/include/") + endif() +endif() + +if (NOT PETSC_ARCH) + if (petscconf) + file(READ ${petscconf} contents) + string(REGEX MATCHALL "#define *PETSC_ARCH *\".+\" *\n" foundArch ${contents}) + string(REGEX REPLACE "#define *PETSC_ARCH *\"(.+)\" *\n" "\\1" archFromFile ${foundArch}) + if (NOT PETSc_FIND_QUIETLY) + message(STATUS "PETSC_ARCH taken from petscconf.h = ${archFromFile}") + endif() + if(archFromFile) + set(PETSC_ARCH ${archFromFile}) + endif(archFromFile) + endif(petscconf) +endif (NOT PETSC_ARCH) +if (NOT PETSc_FIND_QUIETLY) + message(STATUS "PETSC_ARCH = ${PETSC_ARCH}") +endif() + +find_file(petscvariables NAMES petscvariables HINTS ${PETSC_DIR}/lib/petsc/conf/ ${PETSC_DIR}/conf) +if (petscvariables) + if (NOT PETSc_FIND_QUIETLY) + message(STATUS "petscvariables = ${petscvariables}") + endif() +else() + if (PETSc_FIND_REQUIRED) + message(FATAL_ERROR "petscvariables not found") + endif() +endif() + +# function extracting the value of variable defined in a file under the form +# NAME_VAR = VARIABLE_CONTENT +# note that VARIABLE_CONTENT is assumed not to contain ";" +function(get_variable var filename out) + if (NOT EXISTS ${filename}) + message(FATAL_ERROR "${filename} does not exist") + endif() + file(READ ${filename} contents) + string(REGEX REPLACE "\n" ";" contents "${contents}") # we divide line by lines because it did work without doing that + foreach(Line ${contents}) + string(REGEX MATCHALL "^${var} = .*" foundVar ${Line}) + if (foundVar) + string(REGEX REPLACE "^${var} = (.+)" "\\1" value ${foundVar}) + break() + endif() + endforeach() + if(foundVar) + set(${out} "${value}" PARENT_SCOPE) + else() + message(FATAL_ERROR "${var} not found in ${filename}") + endif() +endfunction(get_variable) + +get_variable(PETSC_WITH_EXTERNAL_LIB ${petscvariables} PETSC_LIBRARIES_RAW) +get_variable(MPIEXEC ${petscvariables} PETSC_MPIEXEC) +get_variable(PETSC_CC_INCLUDES ${petscvariables} PETSC_INCLUDES_RAW) + +# extract include paths from petscvariables +string(REGEX REPLACE "-I" "" PETSC_INCLUDES_RAW ${PETSC_INCLUDES_RAW} ) +string(REGEX REPLACE " " ";" PETSC_INCLUDE_DIRS ${PETSC_INCLUDES_RAW} ) + +# extract libraries from petscvariables +string(REGEX MATCHALL " -l([^ ]+) " foundLibs ${PETSC_LIBRARIES_RAW}) +string(REGEX REPLACE " -l" "" PETSC_LIBRARIES ${foundLibs}) +string(REGEX REPLACE " " ";" PETSC_LIBRARIES ${PETSC_LIBRARIES}) + +# extract library directories from petscvariables +string(REGEX MATCHALL " -L([^ ]+) " foundLibPaths ${PETSC_LIBRARIES_RAW}) +string(REGEX REPLACE " -L" "" PETSC_LIBRARY_DIRS ${foundLibPaths}) +string(REGEX REPLACE " " ";" PETSC_LIBRARY_DIRS ${PETSC_LIBRARY_DIRS}) + +include (FindPackageHandleStandardArgs) +find_package_handle_standard_args (PETSc + "PETSc could not be found. Be sure to set PETSC_DIR." + PETSC_MPIEXEC PETSC_INCLUDE_DIRS PETSC_LIBRARIES PETSC_LIBRARY_DIRS) diff --git a/modules/find/tests/CMakeLists.txt b/modules/find/tests/CMakeLists.txt index 9a72b24b475cb312b551fb27ac96ea4aff5ed978..f7c1d22ed6b21466f3564cc92e8caec774989f01 100644 --- a/modules/find/tests/CMakeLists.txt +++ b/modules/find/tests/CMakeLists.txt @@ -91,7 +91,7 @@ if (ENABLE_CTEST) PARMETIS PARSEC PASTIX - PETSC + PETSc PTSCOTCH QUARK SCALAPACK