From 4c4719ae8d7eba15bec71ea403ac7bac6e2ec94d Mon Sep 17 00:00:00 2001 From: Jan Brezina Date: Wed, 4 Sep 2013 00:10:58 -0700 Subject: [PATCH 1/6] Initial commit --- .gitignore | 5 +++++ LICENSE | 23 +++++++++++++++++++++++ README.md | 4 ++++ 3 files changed, 32 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..52540e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +CMakeCache.txt +CMakeFiles +Makefile +cmake_install.cmake +install_manifest.txt diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9f4a750 --- /dev/null +++ b/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2013, Jan Brezina +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 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. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..fd64b99 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +cmake_modules +============= + +CMake modules to detect and/or install specific libraries From c73e62a7675997a7e21e7e2cc9a837b8aa1a9954 Mon Sep 17 00:00:00 2001 From: Jan Brezina Date: Wed, 4 Sep 2013 16:54:47 +0200 Subject: [PATCH 2/6] Merge modules from Flow123d with those from Jed. FindPETSc - add support for extracting more variables from PETSc mekefiles - succed with warning if tests compiles but do not run ( e.g. on PBS systems) - more informative error messages FindPackageMultipass - add MULTIPASS_C_SOURCE_COMPILES ResolveCompilerPaths - add comments with changes possibly necessary on cygwin (needs more testing) --- FindPETSc.cmake | 206 ++++++++++++++++++++++++++++--------- FindPackageMultipass.cmake | 33 +++++- InstallPetsc.cmake | 89 ++++++++++++++++ ResolveCompilerPaths.cmake | 12 +++ 4 files changed, 289 insertions(+), 51 deletions(-) create mode 100644 InstallPetsc.cmake diff --git a/FindPETSc.cmake b/FindPETSc.cmake index 8a9ab5d..4477526 100644 --- a/FindPETSc.cmake +++ b/FindPETSc.cmake @@ -1,22 +1,35 @@ # - Try to find PETSc +# +# Accepts: +# PETSC_ADDITIONAL_LIBS +# # 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) +# 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) +# +# PETSC_EXTERNAL_LIB - CMake list of resolved (hopefully) external libraries linked by PETSC, +# in the case of static PETSC libraries this list is already included in PETSC_LIBRARIES +# PETSC_VAR_XXX - exported several variables from PETSC (to be used by other libraries) +# XXX is one of: # -# Usage: -# find_package(PETSc COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0 -# find_package(PETSc COMPONENTS C) - standard behavior of checking build using a C compiler -# find_package(PETSc) - same as above +# MPIFC_SHOW, MPICXX_SHOW,MPICC_SHOW, PCC, CC_FLAGS, PCC_FLAGS, FC_FLAGS, CPP_FLAGS +# METIS_INCLUDE, BLASLAPACK_INCLUDE, PARMETIS_INCLUDE, MUMPS_INCLUDE +# MPI_LIB, MUMPS_LIB, METIS_LIB, PARMETIS_LIB, BLASLAPACK_LIB, SCALAPACK_LIB +# +# Usage: +# find_package(PETSc COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0 +# find_package(PETSc COMPONENTS C) - standard behavior of checking build using a C compiler +# find_package(PETSc) - same as above # # Setting these changes the behavior of the search -# PETSC_DIR - directory in which PETSc resides -# PETSC_ARCH - build architecture +# 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. @@ -41,15 +54,15 @@ else() list(FIND PETSC_VALID_COMPONENTS ${component} component_location) if(${component_location} EQUAL -1) message(FATAL_ERROR "\"${component}\" is not a valid PETSc component.") - else() - list(APPEND PETSC_LANGUAGE_BINDINGS ${component}) - endif() - endforeach() +else() +list(APPEND PETSC_LANGUAGE_BINDINGS ${component}) +endif() +endforeach() endif() function (petsc_get_version) - if (EXISTS "${PETSC_DIR}/include/petscversion.h") - file (STRINGS "${PETSC_DIR}/include/petscversion.h" vstrings REGEX "#define PETSC_VERSION_(RELEASE|MAJOR|MINOR|SUBMINOR|PATCH) ") +if (EXISTS "${PETSC_DIR}/include/petscversion.h") +file (STRINGS "${PETSC_DIR}/include/petscversion.h" vstrings REGEX "#define PETSC_VERSION_(RELEASE|MAJOR|MINOR|SUBMINOR|PATCH) ") foreach (line ${vstrings}) string (REGEX REPLACE " +" ";" fields ${line}) # break line into three fields (the first is always "#define") list (GET fields 1 var) @@ -58,21 +71,30 @@ function (petsc_get_version) 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) + set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}p${PETSC_VERSION_PATCH}") + set (PETSC_VERSION "${PETSC_VERSION}" 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}p99") + set (PETSC_VERSION "${PETSC_VERSION}" PARENT_SCOPE) endif () else () message (SEND_ERROR "PETSC_DIR can not be used, ${PETSC_DIR}/include/petscversion.h does not exist") endif () + + MESSAGE(STATUS "PETSC version: ${PETSC_VERSION}") + endfunction () + + +########################################################## +# Try to find main header file. +########################################################## find_path (PETSC_DIR include/petsc.h HINTS ENV PETSC_DIR PATHS # Debian paths - /usr/lib/petscdir/3.4 /usr/lib/petscdir/3.3 /usr/lib/petscdir/3.2 /usr/lib/petscdir/3.1 /usr/lib/petscdir/3.0.0 /usr/lib/petscdir/2.3.3 /usr/lib/petscdir/2.3.2 $ENV{HOME}/petsc @@ -80,6 +102,10 @@ find_path (PETSC_DIR include/petsc.h find_program (MAKE_EXECUTABLE NAMES make gmake) + +########################################################## +# Try to find PETSC_ARCH subdirectory that contains petscconf.h file. +########################################################## if (PETSC_DIR AND NOT PETSC_ARCH) set (_petsc_arches $ENV{PETSC_ARCH} # If set, use environment variable first @@ -100,6 +126,10 @@ if (PETSC_DIR AND NOT PETSC_ARCH) set (petscconf "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE) endif (PETSC_DIR AND NOT PETSC_ARCH) + +########################################################## +# Use package multipass to alow multiple tries when search for PETSc. +########################################################## set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARIES_KSP LIBRARIES_SNES LIBRARIES_TS INCLUDE_DIR INCLUDE_CONF) include (FindPackageMultipass) @@ -107,6 +137,10 @@ find_package_multipass (PETSc petsc_config_current STATES DIR ARCH DEPENDENTS INCLUDES LIBRARIES COMPILER MPIEXEC ${petsc_slaves}) + +########################################################## +# Determine dir layout, detect 'rules' and 'variables' files, detect PETSc version +########################################################## # 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 @@ -119,6 +153,7 @@ elseif (PETSC_DIR) message (SEND_ERROR "The pair PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} do not specify a valid PETSc installation") endif () +# All remaining is under this condition except the standard variable handling at the very end if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current) petsc_get_version() @@ -127,6 +162,9 @@ if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current) set (ENV{PETSC_DIR} "${PETSC_DIR}") set (ENV{PETSC_ARCH} "${PETSC_ARCH}") + ################################################################ + # Extracting variables from PETSc configuration + ############################################################## # A temporary makefile to probe the PETSc configuration set (petsc_config_makefile "${PROJECT_BINARY_DIR}/Makefile.petsc") file (WRITE "${petsc_config_makefile}" @@ -136,24 +174,45 @@ if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current) include ${petsc_conf_rules} include ${petsc_conf_variables} show : - -@echo -n \${\${VARIABLE}} +\t-@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) + + macro(PETSC_EXPORT_VARIABLES var_list) + message(STATUS ${var_list}) + + foreach( var ${var_list} ) + petsc_get_variable(${var} PETSC_VAR_${var}) + message(STATUS "EXPORTING PETSC VARIABLE: " ${var} " as PETSC_VAR_${var} = " ${PETSC_VAR_${var}}) + endforeach(var) + endmacro(PETSC_EXPORT_VARIABLES) + 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 (PCC_FLAGS petsc_cc_flags) petsc_get_variable (MPIEXEC petsc_mpiexec) + + set(export_variable_list MPIFC_SHOW MPICXX_SHOW MPICC_SHOW CC FC CC_FLAGS PCC_FLAGS FC_FLAGS CPP_FLAGS + METIS_INCLUDE BLASLAPACK_INCLUDE PARMETIS_INCLUDE MUMPS_INCLUDE + MPI_LIB MUMPS_LIB METIS_LIB PARMETIS_LIB BLASLAPACK_LIB SCALAPACK_LIB) + + petsc_export_variables("${export_variable_list}") + + # We are done with the temporary Makefile, calling PETSC_GET_VARIABLE after this point is invalid! file (REMOVE ${petsc_config_makefile}) + # add libraries specified by user (possibly fixing wrong sequence provided by PETSc) + set(petsc_libs_external "${petsc_libs_external} ${PETSC_ADDITIONAL_LIBS}") + include (ResolveCompilerPaths) # Extract include paths and libraries from compile command line @@ -175,7 +234,7 @@ show : endforeach(flag_var) if(${using_md} MATCHES "True") message(WARNING "PETSc was built with /MT, but /MD is currently set. - See http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F") +See http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F") endif(${using_md} MATCHES "True") endif (petsc_cc_flags MATCHES "-MT") endif (WIN32) @@ -184,6 +243,9 @@ show : convert_cygwin_path(petsc_lib_dir) message (STATUS "petsc_lib_dir ${petsc_lib_dir}") + ############################################################################### + # Find PETSc libraries + ############################################################################## 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 if (WIN32) @@ -207,6 +269,7 @@ show : petsc_find_library (TS petscts) macro (PETSC_JOIN libs deps) list (APPEND PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${deps}}) + message(STATUS "PETSC_LIBRARIES_${libs}: " ${PETSC_LIBRARIES_${libs}}) endmacro (PETSC_JOIN libs deps) petsc_join (VEC SYS) petsc_join (MAT VEC) @@ -215,6 +278,7 @@ show : 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) @@ -229,7 +293,13 @@ show : endif () include(Check${PETSC_LANGUAGE_BINDINGS}SourceRuns) + include(Check${PETSC_LANGUAGE_BINDINGS}SourceCompiles) + + ######################################################################### + # Test that PETSc works + ############################################################ macro (PETSC_TEST_RUNS includes libraries runs) + if(${PETSC_LANGUAGE_BINDINGS} STREQUAL "C") set(_PETSC_ERR_FUNC "CHKERRQ(ierr)") elseif(${PETSC_LANGUAGE_BINDINGS} STREQUAL "CXX") @@ -245,22 +315,30 @@ show : static const char help[] = \"PETSc test program.\"; #include int main(int argc,char *argv[]) { - PetscErrorCode ierr; - TS ts; - - ierr = PetscInitialize(&argc,&argv,0,help);${_PETSC_ERR_FUNC}; - ierr = TSCreate(PETSC_COMM_WORLD,&ts);${_PETSC_ERR_FUNC}; - ierr = TSSetFromOptions(ts);${_PETSC_ERR_FUNC}; - ierr = ${_PETSC_TSDestroy};${_PETSC_ERR_FUNC}; - ierr = PetscFinalize();${_PETSC_ERR_FUNC}; - return 0; +PetscErrorCode ierr; +TS ts; + +ierr = PetscInitialize(&argc,&argv,0,help);${_PETSC_ERR_FUNC}; +ierr = TSCreate(PETSC_COMM_WORLD,&ts);${_PETSC_ERR_FUNC}; +ierr = TSSetFromOptions(ts);${_PETSC_ERR_FUNC}; +ierr = ${_PETSC_TSDestroy};${_PETSC_ERR_FUNC}; +ierr = PetscFinalize();${_PETSC_ERR_FUNC}; +return 0; } ") - multipass_source_runs ("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs} "${PETSC_LANGUAGE_BINDINGS}") - 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}}) + + # check if we can at least compile the source + multipass_c_source_compiles("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs}) + + if (${${runs}}) + # check if we can run the executable + multipass_c_source_runs ("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs}_runs) + + if (${${runs}_runs}) + set (PETSC_EXECUTABLE_RUNS "YES" CACHE BOOL + "Can the system successfully compile and link a PETSc executable? This variable can be manually set to \"YES\" to force CMake to accept a given PETSc configuration. If you change PETSC_DIR, PETSC_ARCH, or PETSC_CURRENT you would have to reset this variable." FORCE) + endif(${${runs}_runs}) + endif (${${runs}}) endmacro (PETSC_TEST_RUNS) @@ -269,17 +347,28 @@ int main(int argc,char *argv[]) { mark_as_advanced (PETSC_INCLUDE_DIR PETSC_INCLUDE_CONF) set (petsc_includes_minimal ${PETSC_INCLUDE_CONF} ${PETSC_INCLUDE_DIR}) + # Macro resolve_libraries comes from ResolveCompilerPaths, it tries resolve all libraries form given compiler line + # Unfortunately this only mimics compiler resolutions and occasionally can be incorrect. In such a case use PETSC_ADDITIONAL_LIBS. + message(STATUS "[FindPETSc] Try to resolve libraries from: '${petsc_libs_external}'") + resolve_libraries (petsc_libraries_external "${petsc_libs_external}") + message(STATUS "[FindPETSc] Resolved path: '${petsc_libraries_external}'") + + # Multipass_test_1 #################### 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 + else (petsc_works_minimal) # Minimal includes fail, see if just adding full includes fixes it + + # Multipass_test_2 #################### 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).") + 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}") + + # Multipass_test_3 #################### + foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) list (APPEND PETSC_LIBRARIES_${pkg} ${petsc_libraries_external}) endforeach (pkg) @@ -288,20 +377,38 @@ int main(int argc,char *argv[]) { 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) + + # Multipass_test_4 #################### # 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.") + set (petsc_includes_needed ${petsc_includes_all}) else (petsc_works_all) # We fail anyways - message (STATUS "PETSc could not be used, maybe the install is broken.") + message (STATUS " + Can not compile and link PETSc executable, probably some missing librairies. + See BUILD_DIR/CMakeFiles/CMakeError.log for reasons, check library resolution after 'MULTIPASS_TEST_*_petsc_works_allincludes'. + Try to add missing libraries through PETSC_ADDITIONAL_LIBS variable.") endif (petsc_works_all) endif (petsc_works_alllibraries) endif (petsc_works_allincludes) endif (petsc_works_minimal) + + + if (petsc_includes_needed) # this indicates PETSC_FOUND + if (${PETSC_EXECUTABLE_RUNS}) # this is optional + else() + message(STATUS " + Can compile but can not run PETSC executable. Probably problem with mpiexec or with shared libraries. + See See BUILD_DIR/CMakeFiles/CMakeError.log for reasons.") + endif(${PETSC_EXECUTABLE_RUNS}) + endif(petsc_includes_needed) + + # 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) + MESSAGE(STATUS "petsc ver: ${PETSC_VERSION}") + 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) @@ -311,13 +418,14 @@ int main(int argc,char *argv[]) { 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 + set (PETSC_EXTERNAL_LIB ${petsc_libraries_external} CACHE STRING "PETSc external libraries" 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. + # 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 () 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) + "PETSc could not be found. Be sure to set PETSC_DIR and PETSC_ARCH." + PETSC_INCLUDES PETSC_LIBRARIES PETSC_EXTERNAL_LIB) diff --git a/FindPackageMultipass.cmake b/FindPackageMultipass.cmake index fa350a9..1fb4c83 100644 --- a/FindPackageMultipass.cmake +++ b/FindPackageMultipass.cmake @@ -21,16 +21,21 @@ # # Make temporary files, run programs, etc, to determine FOO_INCLUDES and FOO_LIBRARIES # endif (NOT foo_current) # -# MULTIPASS_SOURCE_RUNS (Name INCLUDES LIBRARIES SOURCE RUNS LANGUAGE) +# MULTIPASS_SOURCE_RUNS (INCLUDES LIBRARIES SOURCE RUNS LANGUAGE) # Always runs the given test, use this when you need to re-run tests # because parent variables have made old cache entries stale. The LANGUAGE # variable is either C or CXX indicating which compiler the test should # use. -# MULTIPASS_C_SOURCE_RUNS (Name INCLUDES LIBRARIES SOURCE RUNS) +# +# MULTIPASS_C_SOURCE_RUNS (INCLUDES LIBRARIES SOURCE RUNS) # DEPRECATED! This is only included for backwards compatability. Use # the more general MULTIPASS_SOURCE_RUNS instead. # Always runs the given test, use this when you need to re-run tests # because parent variables have made old cache entries stale. +# +# MULTIPASS_C_SOURCE_COMPILES(includes libraries source compiles) +# Same as MULTIPASS_C_SOURCE_RUNS but only check if the source compiles. +# TODO: make version for any language like MULTIPASS_SOURCE_RUNS macro (FIND_PACKAGE_MULTIPASS _name _current) string (TOUPPER ${_name} _NAME) @@ -104,3 +109,27 @@ endmacro (MULTIPASS_SOURCE_RUNS) macro (MULTIPASS_C_SOURCE_RUNS includes libraries source runs) multipass_source_runs("${includes}" "${libraries}" "${source}" ${runs} "C") endmacro (MULTIPASS_C_SOURCE_RUNS) + + +macro (MULTIPASS_C_SOURCE_COMPILES includes libraries source compiles) + include (CheckCSourceCompiles) + # 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}_${compiles}) + set (CMAKE_REQUIRED_INCLUDES ${includes}) + set (CMAKE_REQUIRED_LIBRARIES ${libraries}) + message(STATUS "check_c_source_compiles: ${testname}") + check_c_source_compiles ("${source}" ${testname}) + set (${compiles} "${${testname}}") +endmacro (MULTIPASS_C_SOURCE_COMPILES) + + diff --git a/InstallPetsc.cmake b/InstallPetsc.cmake new file mode 100644 index 0000000..4eb1745 --- /dev/null +++ b/InstallPetsc.cmake @@ -0,0 +1,89 @@ +#InstallPetsc.cmake +# +# Created on: Jul 20, 2012 +# Author: jb +# +# accepted variables: +# EXTERNAL_PETSC_DIR - target directory used for instalation +# INSTALL_PETSC_URL - url with petsc tarball +# PETSC_MPI_DIR - pass MPI to PETSC configure +# PETSC_LAPACK_DIR - pass Lapack to PETSC configure +# INSTALL_PETSC_ONLY - install only petsc (possibly MPI and BLAS/LAPACK) +# INSTALL_PETSC_OPTIONS - add content of this variable to the PETSC configure command +# (default) - install also, metis, parmetis + + + +if (NOT EXTERNAL_PETSC_DIR) + set(EXTERNAL_PETSC_DIR "${EXTERNAL_PROJECT_DIR}/petsc_build") +endif() + +########################################################################## +# Download PETSC +# A temporary CMakeLists.txt + +# set configure line for PETSC +set(PETSC_CONF_LINE "--COPTFLAGS ${CMAKE_C_FLAGS} --CXXOPTFLAGS ${CMAKE_CXX_FLAGS} --with-clanguage=C --with-debugging=0") +if (CMAKE_Fortran_COMPILER) + set(PETSC_CONF_LINE "${PETSC_CONF_LINE} --FOPTFLAGS ${CMAKE_Fortran_FLAGS}") +endif() + +if (PETSC_MPI_DIR) + set(PETSC_CONF_LINE "${PETSC_CONF_LINE} --with-mpi-dir=${PETSC_MPI_DIR}") +else() + set(PETSC_CONF_LINE "${PETSC_CONF_LINE} --download-mpich=yes") +endif() + +if (PETSC_LAPACK_DIR) + set(PETSC_CONF_LINE "${PETSC_CONF_LINE} --with-lapack-dir=${PETSC_LAPACK_DIR}") +else() + if(CMAKE_Fortran_COMPILER) + set(PETSC_CONF_LINE "${PETSC_CONF_LINE} --download-f-blas-lapack=yes") + else() + set(PETSC_CONF_LINE "${PETSC_CONF_LINE} --download-c-blas-lapack=yes") + endif() +endif() + +if(INSTALL_PETSC_ONLY) +else() + set(PETSC_CONF_LINE "${PETSC_CONF_LINE} --download-metis=yes --download-parmetis=yes") +endif() + +set(PETSC_CONF_LINE "${PETSC_CONF_LINE} ${INSTALL_PETSC_OPTIONS}") + +set (cmakelists_fname "${EXTERNAL_PETSC_DIR}/CMakeLists.txt") +file (WRITE "${cmakelists_fname}" +" + ## This file was autogenerated by InstallPETSC.cmake + cmake_minimum_required(VERSION 2.8) + include(ExternalProject) + ExternalProject_Add(PETSC + DOWNLOAD_DIR ${EXTERNAL_PETSC_DIR} + URL ${INSTALL_PETSC_URL} + SOURCE_DIR ${EXTERNAL_PETSC_DIR}/src + BINARY_DIR ${EXTERNAL_PETSC_DIR}/src + CONFIGURE_COMMAND ${EXTERNAL_PETSC_DIR}/src/configure ${PETSC_CONF_LINE} + BUILD_COMMAND make all + INSTALL_COMMAND \"\" + ) +") + +message(STATUS "=== Installing PETSC ===") +# run cmake +set(PETSC_DIR "${EXTERNAL_PETSC_DIR}/src") +set(PETSC_ARCH "cmake") +set(ENV{PETSC_DIR} "${PETSC_DIR}") +set(ENV{PETSC_ARCH} "${PETSC_ARCH}") +execute_process(COMMAND ${CMAKE_COMMAND} ${EXTERNAL_PETSC_DIR} + WORKING_DIRECTORY ${EXTERNAL_PETSC_DIR}) + +find_program (MAKE_EXECUTABLE NAMES make gmake) +# run make +execute_process(COMMAND ${MAKE_EXECUTABLE} PETSC + WORKING_DIRECTORY ${EXTERNAL_PETSC_DIR}) + + +#file (REMOVE ${cmakelists_fname}) + +message(STATUS "== PETSC build done") + diff --git a/ResolveCompilerPaths.cmake b/ResolveCompilerPaths.cmake index 644a738..8fdab9b 100644 --- a/ResolveCompilerPaths.cmake +++ b/ResolveCompilerPaths.cmake @@ -41,6 +41,8 @@ include (CorrectWindowsPaths) macro (RESOLVE_LIBRARIES LIBS LINK_LINE) +# JB +# string (REGEX MATCHALL "((-L|-l|-Wl)([^\" ]+|\"[^\"]+\")|/[^\" ]+(a|so|dll))" _all_tokens "${LINK_LINE}") string (REGEX MATCHALL "((-L|-l|-Wl)([^\" ]+|\"[^\"]+\")|[^\" ]+\\.(a|so|dll|lib))" _all_tokens "${LINK_LINE}") set (_libs_found) set (_directory_list) @@ -52,6 +54,8 @@ macro (RESOLVE_LIBRARIES LIBS LINK_LINE) convert_cygwin_path(token) list (APPEND _directory_list ${token}) elseif (token MATCHES "^(-l([^\" ]+|\"[^\"]+\")|[^\" ]+\\.(a|so|dll|lib))") + # JB + # 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 if (WIN32) #windows expects "libfoo", linux expects "foo" string (REGEX REPLACE "^-l" "lib" token ${token}) @@ -66,6 +70,14 @@ macro (RESOLVE_LIBRARIES LIBS LINK_LINE) convert_cygwin_path(libpath) set (_directory_list ${_directory_list} ${libpath}) set (token ${libname}) +# JB +# if (token MATCHES "^/") # We have an absolute path, add root to the search path +# # workaround for bug in find_library on cygwin (do not work for libraries given as full path) +# # doesn;t work with paths containing spaces +# STRING(REGEX REPLACE "^/[^ ]*/lib([^/ ]*).(a|so|dll)" "\\1" LIB_NAME ${token}) +# STRING(REGEX REPLACE "(^/[^ ]*/)lib[^/ ]*.(a|so|dll)" "\\1" LIB_PATH ${token}) +# set (_root ${LIB_PATH}) +# set (token ${LIB_NAME}) endif (token MATCHES "^/") set (_lib "NOTFOUND" CACHE FILEPATH "Cleared" FORCE) find_library (_lib ${token} HINTS ${_directory_list} ${_root}) From 42927d1b5a00f060270fdb186181a20908d373a9 Mon Sep 17 00:00:00 2001 From: Jan Brezina Date: Thu, 5 Sep 2013 14:02:04 +0200 Subject: [PATCH 3/6] Make minimize changes compared to Jed's version. CorrectWindowsPaths.cmake - do not convert paths under cygwin ResolveCompilerPaths.cmake - make beter lib name separation for libraries given by absolute path CMake's find_library needs the root part of the filename (i.e. .../lib(ROOT).a) --- CorrectWindowsPaths.cmake | 8 ++- ResolveCompilerPaths.cmake | 100 +++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 51 deletions(-) diff --git a/CorrectWindowsPaths.cmake b/CorrectWindowsPaths.cmake index 09bcdd6..427acb7 100644 --- a/CorrectWindowsPaths.cmake +++ b/CorrectWindowsPaths.cmake @@ -5,10 +5,14 @@ # unix-style paths into paths useable by cmake on windows macro (CONVERT_CYGWIN_PATH _path) - if (WIN32) + +# Some cygwin utilities (namely make) do not like DOS paths, but are happy with UNIX paths +# On the other hand out of the cygwin, the cygpath tool doesn't need to be available. + + if (WIN32 AND NOT CYGWIN) EXECUTE_PROCESS(COMMAND cygpath.exe -m ${${_path}} OUTPUT_VARIABLE ${_path}) string (STRIP ${${_path}} ${_path}) - endif (WIN32) + endif (WIN32 AND NOT CYGWIN) endmacro (CONVERT_CYGWIN_PATH) diff --git a/ResolveCompilerPaths.cmake b/ResolveCompilerPaths.cmake index 8fdab9b..64cc673 100644 --- a/ResolveCompilerPaths.cmake +++ b/ResolveCompilerPaths.cmake @@ -1,48 +1,46 @@ # 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: +# 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") +# RESOLVE_LIBRARIES (FOO_LIBRARIES "-L/A -la -L/B -lb -lc -ld") # -# will be resolved to +# will be resolved to # -# FOO_LIBRARIES:STRING="/A/liba.so;/B/libb.so;/A/libc.so;/usr/lib/libd.so" +# FOO_LIBRARIES:STRING="/A/liba.so;/B/libb.so;/A/libc.so;/usr/lib/libd.so" # -# if the filesystem looks like +# 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 +# /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. +# 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). +# 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: +# 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") +# RESOLVE_INCLUDES (FOO_INCLUDES "-I/A -DBAR='\"irrelevant -I/string here\"' -I/B") # -# will be resolved to +# will be resolved to # -# FOO_INCLUDES:STRING="/A;/B" +# FOO_INCLUDES:STRING="/A;/B" # -# assuming both directories exist. -# Note: as currently implemented, the -I/string will be picked up mistakenly (cry, cry) +# assuming both directories exist. +# Note: as currently implemented, the -I/string will be picked up mistakenly (cry, cry) include (CorrectWindowsPaths) macro (RESOLVE_LIBRARIES LIBS LINK_LINE) -# JB -# string (REGEX MATCHALL "((-L|-l|-Wl)([^\" ]+|\"[^\"]+\")|/[^\" ]+(a|so|dll))" _all_tokens "${LINK_LINE}") string (REGEX MATCHALL "((-L|-l|-Wl)([^\" ]+|\"[^\"]+\")|[^\" ]+\\.(a|so|dll|lib))" _all_tokens "${LINK_LINE}") set (_libs_found) set (_directory_list) @@ -54,35 +52,38 @@ macro (RESOLVE_LIBRARIES LIBS LINK_LINE) convert_cygwin_path(token) list (APPEND _directory_list ${token}) elseif (token MATCHES "^(-l([^\" ]+|\"[^\"]+\")|[^\" ]+\\.(a|so|dll|lib))") - # JB - # 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 - if (WIN32) #windows expects "libfoo", linux expects "foo" + if (WIN32 AND NOT CYGWIN) #windows expects "libfoo", linux expects "foo" string (REGEX REPLACE "^-l" "lib" token ${token}) - else (WIN32) + else () string (REGEX REPLACE "^-l" "" token ${token}) - endif (WIN32) - set (_root) - if (token MATCHES "^/") # We have an absolute path - #separate into a path and a library name: - string (REGEX MATCH "[^/]*\\.(a|so|dll|lib)$" libname ${token}) - string (REGEX MATCH ".*[^${libname}$]" libpath ${token}) - convert_cygwin_path(libpath) - set (_directory_list ${_directory_list} ${libpath}) - set (token ${libname}) -# JB -# if (token MATCHES "^/") # We have an absolute path, add root to the search path -# # workaround for bug in find_library on cygwin (do not work for libraries given as full path) -# # doesn;t work with paths containing spaces -# STRING(REGEX REPLACE "^/[^ ]*/lib([^/ ]*).(a|so|dll)" "\\1" LIB_NAME ${token}) -# STRING(REGEX REPLACE "(^/[^ ]*/)lib[^/ ]*.(a|so|dll)" "\\1" LIB_PATH ${token}) -# set (_root ${LIB_PATH}) -# set (token ${LIB_NAME}) + endif () + + if (token MATCHES "^/") # We have an absolute path + #separate into a path and a library name: + if (WIN32 AND NOT CYGWIN) #windows expects "libfoo", linux expects "foo" + STRING(REGEX REPLACE "^/[^ ]*/([^/ ]*)[.](a|so|dll|lib)" "\\1" LIB_NAME ${token}) + STRING(REGEX REPLACE "(^/[^ ]*/)[^/ ]*[.](a|so|dll|lib)" "\\1" LIB_PATH ${token}) + else () + STRING(REGEX REPLACE "^/[^ ]*/lib([^/ ]*).(a|so|dll)" "\\1" LIB_NAME ${token}) + STRING(REGEX REPLACE "(^/[^ ]*/)lib[^/ ]*.(a|so|dll)" "\\1" LIB_PATH ${token}) + endif () + + convert_cygwin_path(LIB_PATH) + + set (_directory_list ${_directory_list} ${LIB_PATH}) + set (token ${LIB_NAME}) endif (token MATCHES "^/") + set (_lib "NOTFOUND" CACHE FILEPATH "Cleared" FORCE) - find_library (_lib ${token} HINTS ${_directory_list} ${_root}) + find_library (_lib NAMES ${token} HINTS ${_directory_list}) + ## debug + #message(STATUS "token: ${token}\ndlist: ${_directory_list}\nroot: ${_root}") if (_lib) - string (REPLACE "//" "/" _lib ${_lib}) + ## debug + #message(STATUS "RESULT: ${_lib}") + + string (REPLACE "//" "/" _lib ${_lib}) list (APPEND _libs_found ${_lib}) else (_lib) message (STATUS "Unable to find library ${token}") @@ -115,3 +116,4 @@ macro (RESOLVE_INCLUDES INCS COMPILE_LINE) list (REMOVE_DUPLICATES _incs_found) set (${INCS} "${_incs_found}") endmacro (RESOLVE_INCLUDES) + From 8c891c617569a15b552560cc7f8077defd32c2a1 Mon Sep 17 00:00:00 2001 From: Jan Brezina Date: Fri, 6 Sep 2013 15:58:30 +0200 Subject: [PATCH 4/6] Rebase to Jed's branch. From c70e6d0609f1ea2e01e8ab8bb79d2bd9190e1787 Mon Sep 17 00:00:00 2001 From: Jan Brezina Date: Fri, 6 Sep 2013 19:43:01 +0200 Subject: [PATCH 5/6] New merge of changes from Flow123d. Remove unecessary changes in formating, add parameter PETSC_EXPORT_LIST leave Debian hint path --- FindPETSc.cmake | 137 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 119 insertions(+), 18 deletions(-) diff --git a/FindPETSc.cmake b/FindPETSc.cmake index 8a9ab5d..f9817c4 100644 --- a/FindPETSc.cmake +++ b/FindPETSc.cmake @@ -1,5 +1,20 @@ # - Try to find PETSc -# Once done this will define +# +# +# Usage: +# find_package(PETSc COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0 +# find_package(PETSc COMPONENTS C) - standard behavior of checking build using a C compiler +# find_package(PETSc) - same as above +# +# Setting these changes the behavior of the search +# PETSC_DIR - directory in which PETSc resides +# PETSC_ARCH - build architecture +# PETSC_EXPORT_LIST - List of variables from PETSc makefile system to export. For each name XYZ in the list +# we set CMake variable PETSC_VAR_XYZ. +# PETSC_ADDITIONAL_LIBS - Add libraries to the link sequence; use only to fix possible reported +# problems with absolute path resolution. +# +# Once done this will define: # # PETSC_FOUND - system has PETSc # PETSC_INCLUDES - the PETSc include directories @@ -9,14 +24,11 @@ # PETSC_MPIEXEC - Executable for running MPI programs # PETSC_VERSION - Version string (MAJOR.MINOR.SUBMINOR) # -# Usage: -# find_package(PETSc COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0 -# find_package(PETSc COMPONENTS C) - standard behavior of checking build using a C compiler -# find_package(PETSc) - same as above +# PETSC_EXTERNAL_LIB - CMake list of resolved (hopefully) external libraries linked by PETSC, +# in the case of static PETSC libraries this list is already included in PETSC_LIBRARIES # -# Setting these changes the behavior of the search -# PETSC_DIR - directory in which PETSc resides -# PETSC_ARCH - build architecture +# PETSC_VAR_XYZ - exported variables from given PETSC_EXPORT_LIST + # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. @@ -66,8 +78,16 @@ function (petsc_get_version) else () message (SEND_ERROR "PETSC_DIR can not be used, ${PETSC_DIR}/include/petscversion.h does not exist") endif () + + MESSAGE(STATUS "PETSC version: ${PETSC_VERSION}") + endfunction () + + +########################################################## +# Try to find main header file. +########################################################## find_path (PETSC_DIR include/petsc.h HINTS ENV PETSC_DIR PATHS @@ -80,6 +100,10 @@ find_path (PETSC_DIR include/petsc.h find_program (MAKE_EXECUTABLE NAMES make gmake) + +########################################################## +# Try to find PETSC_ARCH subdirectory that contains petscconf.h file. +########################################################## if (PETSC_DIR AND NOT PETSC_ARCH) set (_petsc_arches $ENV{PETSC_ARCH} # If set, use environment variable first @@ -100,6 +124,10 @@ if (PETSC_DIR AND NOT PETSC_ARCH) set (petscconf "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE) endif (PETSC_DIR AND NOT PETSC_ARCH) + +########################################################## +# Use package multipass to alow multiple tries when search for PETSc. +########################################################## set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARIES_KSP LIBRARIES_SNES LIBRARIES_TS INCLUDE_DIR INCLUDE_CONF) include (FindPackageMultipass) @@ -107,6 +135,10 @@ find_package_multipass (PETSc petsc_config_current STATES DIR ARCH DEPENDENTS INCLUDES LIBRARIES COMPILER MPIEXEC ${petsc_slaves}) + +########################################################## +# Determine dir layout, detect 'rules' and 'variables' files, detect PETSc version +########################################################## # 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 @@ -119,6 +151,7 @@ elseif (PETSC_DIR) message (SEND_ERROR "The pair PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} do not specify a valid PETSc installation") endif () +# All remaining is under this condition except the standard variable handling at the very end if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current) petsc_get_version() @@ -127,6 +160,9 @@ if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current) set (ENV{PETSC_DIR} "${PETSC_DIR}") set (ENV{PETSC_ARCH} "${PETSC_ARCH}") + ################################################################ + # Extracting variables from PETSc configuration + ############################################################## # A temporary makefile to probe the PETSc configuration set (petsc_config_makefile "${PROJECT_BINARY_DIR}/Makefile.petsc") file (WRITE "${petsc_config_makefile}" @@ -136,15 +172,26 @@ if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current) include ${petsc_conf_rules} include ${petsc_conf_variables} show : - -@echo -n \${\${VARIABLE}} +\t-@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) + + macro(PETSC_EXPORT_VARIABLES var_list) + message(STATUS ${var_list}) + + foreach( var ${var_list} ) + petsc_get_variable(${var} PETSC_VAR_${var}) + message(STATUS "EXPORTING PETSC VARIABLE: " ${var} " as PETSC_VAR_${var} = " ${PETSC_VAR_${var}}) + endforeach(var) + endmacro(PETSC_EXPORT_VARIABLES) + 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) @@ -152,8 +199,16 @@ show : petsc_get_variable (PCC petsc_cc) petsc_get_variable (PCC_FLAGS petsc_cc_flags) petsc_get_variable (MPIEXEC petsc_mpiexec) + + set(export_variable_list ${PETSC_EXPORT_LIST} ) + petsc_export_variables("${export_variable_list}") + + # We are done with the temporary Makefile, calling PETSC_GET_VARIABLE after this point is invalid! file (REMOVE ${petsc_config_makefile}) + # add libraries specified by user (possibly fixing wrong sequence provided by PETSc) + set(petsc_libs_external "${petsc_libs_external} ${PETSC_ADDITIONAL_LIBS}") + include (ResolveCompilerPaths) # Extract include paths and libraries from compile command line @@ -184,6 +239,9 @@ show : convert_cygwin_path(petsc_lib_dir) message (STATUS "petsc_lib_dir ${petsc_lib_dir}") + ############################################################################### + # Find PETSc libraries + ############################################################################## 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 if (WIN32) @@ -207,6 +265,7 @@ show : petsc_find_library (TS petscts) macro (PETSC_JOIN libs deps) list (APPEND PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${deps}}) + message(STATUS "PETSC_LIBRARIES_${libs}: " ${PETSC_LIBRARIES_${libs}}) endmacro (PETSC_JOIN libs deps) petsc_join (VEC SYS) petsc_join (MAT VEC) @@ -229,6 +288,11 @@ show : endif () include(Check${PETSC_LANGUAGE_BINDINGS}SourceRuns) + include(Check${PETSC_LANGUAGE_BINDINGS}SourceCompiles) + + ######################################################################### + # Test that PETSc works + ############################################################ macro (PETSC_TEST_RUNS includes libraries runs) if(${PETSC_LANGUAGE_BINDINGS} STREQUAL "C") set(_PETSC_ERR_FUNC "CHKERRQ(ierr)") @@ -256,11 +320,19 @@ int main(int argc,char *argv[]) { return 0; } ") - multipass_source_runs ("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs} "${PETSC_LANGUAGE_BINDINGS}") - 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}}) + + # check if we can at least compile the source + multipass_c_source_compiles("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs}) + + if (${${runs}}) + # check if we can run the executable + multipass_c_source_runs ("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs}_runs) + + if (${${runs}_runs}) + set (PETSC_EXECUTABLE_RUNS "YES" CACHE BOOL + "Can the system successfully compile and link a PETSc executable? This variable can be manually set to \"YES\" to force CMake to accept a given PETSc configuration. If you change PETSC_DIR, PETSC_ARCH, or PETSC_CURRENT you would have to reset this variable." FORCE) + endif(${${runs}_runs}) + endif (${${runs}}) endmacro (PETSC_TEST_RUNS) @@ -269,17 +341,28 @@ int main(int argc,char *argv[]) { mark_as_advanced (PETSC_INCLUDE_DIR PETSC_INCLUDE_CONF) set (petsc_includes_minimal ${PETSC_INCLUDE_CONF} ${PETSC_INCLUDE_DIR}) + # Macro resolve_libraries comes from ResolveCompilerPaths, it tries resolve all libraries form given compiler line + # Unfortunately this only mimics compiler resolutions and occasionally can be incorrect. In such a case use PETSC_ADDITIONAL_LIBS. + message(STATUS "[FindPETSc] Try to resolve libraries from: '${petsc_libs_external}'") + resolve_libraries (petsc_libraries_external "${petsc_libs_external}") + message(STATUS "[FindPETSc] Resolved path: '${petsc_libraries_external}'") + + # Multipass_test_1 #################### 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 + + # Multipass_test_2 #################### 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}") + + # Multipass_test_3 #################### + foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) list (APPEND PETSC_LIBRARIES_${pkg} ${petsc_libraries_external}) endforeach (pkg) @@ -288,18 +371,35 @@ int main(int argc,char *argv[]) { 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) + + # Multipass_test_4 #################### # 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.") + set (petsc_includes_needed ${petsc_includes_all}) else (petsc_works_all) # We fail anyways - message (STATUS "PETSc could not be used, maybe the install is broken.") + message (STATUS " + Can not compile and link PETSc executable, probably some missing libraries. + See BUILD_DIR/CMakeFiles/CMakeError.log for reasons, check library resolution after 'MULTIPASS_TEST_*_petsc_works_allincludes'. + Try to add missing libraries through PETSC_ADDITIONAL_LIBS variable.") endif (petsc_works_all) endif (petsc_works_alllibraries) endif (petsc_works_allincludes) endif (petsc_works_minimal) + + + if (petsc_includes_needed) # this indicates PETSC_FOUND + if (${PETSC_EXECUTABLE_RUNS}) # this is optional + else() + message(STATUS " + Can compile but can not run PETSC executable. Probably problem with mpiexec or with shared libraries. + See See BUILD_DIR/CMakeFiles/CMakeError.log for reasons.") + endif(${PETSC_EXECUTABLE_RUNS}) + endif(petsc_includes_needed) + + # 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) @@ -311,6 +411,7 @@ int main(int argc,char *argv[]) { 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) + set (PETSC_EXTERNAL_LIB ${petsc_libraries_external} CACHE STRING "PETSc external libraries" 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. @@ -320,4 +421,4 @@ endif () 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) + PETSC_INCLUDES PETSC_LIBRARIES PETSC_EXTERNAL_LIB) From 127f5c7433d5662ebb01ec1158fa33e0aef02020 Mon Sep 17 00:00:00 2001 From: Jan Brezina Date: Fri, 2 Oct 2015 16:54:24 +0200 Subject: [PATCH 6/6] Merge changes from Flow123d project. --- FindPETSc.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/FindPETSc.cmake b/FindPETSc.cmake index cdbee2c..5c150d4 100644 --- a/FindPETSc.cmake +++ b/FindPETSc.cmake @@ -136,7 +136,7 @@ set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARI include (FindPackageMultipass) find_package_multipass (PETSc petsc_config_current STATES DIR ARCH - DEPENDENTS INCLUDES LIBRARIES COMPILER MPIEXEC ${petsc_slaves}) + DEPENDENTS INCLUDES LIBRARIES COMPILER MPIEXEC EXTERNAL_LIB ${petsc_slaves}) ########################################################## @@ -190,11 +190,12 @@ show : endmacro (PETSC_GET_VARIABLE) macro(PETSC_EXPORT_VARIABLES var_list) - message(STATUS ${var_list}) + #message(STATUS ${var_list}) foreach( var ${var_list} ) - petsc_get_variable(${var} PETSC_VAR_${var}) + petsc_get_variable(${var} PETSC_VAR_tmp_${var}) message(STATUS "EXPORTING PETSC VARIABLE: " ${var} " as PETSC_VAR_${var} = " ${PETSC_VAR_${var}}) + set(PETSC_VAR_${var} ${PETSC_VAR_tmp_${var}} CACHE STRING "Exported variable from PETSc." FORCE) endforeach(var) endmacro(PETSC_EXPORT_VARIABLES)