Alpine3D

Alpine3D Svn Source Tree

Root/trunk/tools/cmake/FindPETSc.cmake

1# - Try to find PETSc
2# Once done this will define
3#
4# PETSC_FOUND - system has PETSc
5# PETSC_INCLUDES - the PETSc include directories
6# PETSC_LIBRARIES - Link these to use PETSc
7# PETSC_COMPILER - Compiler used by PETSc, helpful to find a compatible MPI
8# PETSC_DEFINITIONS - Compiler switches for using PETSc
9# PETSC_MPIEXEC - Executable for running MPI programs
10# PETSC_VERSION - Version string (MAJOR.MINOR.SUBMINOR)
11#
12# Usage:
13# find_package(PETSc COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0
14# find_package(PETSc COMPONENTS C) - standard behavior of checking build using a C compiler
15# find_package(PETSc) - same as above
16#
17# Setting these changes the behavior of the search
18# PETSC_DIR - directory in which PETSc resides
19# PETSC_ARCH - build architecture
20#
21# Redistribution and use is allowed according to the terms of the BSD license.
22# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
23#
24
25set(PETSC_VALID_COMPONENTS
26 C
27 CXX)
28
29if(NOT PETSc_FIND_COMPONENTS)
30 set(PETSC_LANGUAGE_BINDINGS "C")
31else()
32 # Right now, this is designed for compatability with the --with-clanguage option, so
33 # only allow one item in the components list.
34 list(LENGTH ${PETSc_FIND_COMPONENTS} components_length)
35 if(${components_length} GREATER 1)
36 message(FATAL_ERROR "Only one component for PETSc is allowed to be specified")
37 endif()
38 # This is a stub for allowing multiple components should that time ever come. Perhaps
39 # to also test Fortran bindings?
40 foreach(component ${PETSc_FIND_COMPONENTS})
41 list(FIND PETSC_VALID_COMPONENTS ${component} component_location)
42 if(${component_location} EQUAL -1)
43 message(FATAL_ERROR "\"${component}\" is not a valid PETSc component.")
44else()
45list(APPEND PETSC_LANGUAGE_BINDINGS ${component})
46endif()
47endforeach()
48endif()
49
50function (petsc_get_version)
51if (EXISTS "${PETSC_DIR}/include/petscversion.h")
52file (STRINGS "${PETSC_DIR}/include/petscversion.h" vstrings REGEX "#define PETSC_VERSION_(RELEASE|MAJOR|MINOR|SUBMINOR|PATCH) ")
53 foreach (line ${vstrings})
54 string (REGEX REPLACE " +" ";" fields ${line}) # break line into three fields (the first is always "#define")
55 list (GET fields 1 var)
56 list (GET fields 2 val)
57 set (${var} ${val} PARENT_SCOPE)
58 set (${var} ${val}) # Also in local scope so we have access below
59 endforeach ()
60 if (PETSC_VERSION_RELEASE)
61 set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}p${PETSC_VERSION_PATCH}" PARENT_SCOPE)
62 else ()
63 # make dev version compare higher than any patch level of a released version
64 set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}.99" PARENT_SCOPE)
65 endif ()
66 else ()
67 message (SEND_ERROR "PETSC_DIR can not be used, ${PETSC_DIR}/include/petscversion.h does not exist")
68 endif ()
69endfunction ()
70
71find_path (PETSC_DIR include/petsc.h
72 HINTS ENV PETSC_DIR
73 PATHS
74 # Debian paths
75 /usr/lib/petscdir/3.4
76 /usr/lib/petscdir/3.3 /usr/lib/petscdir/3.2 /usr/lib/petscdir/3.1
77 /usr/lib/petscdir/3.0.0 /usr/lib/petscdir/2.3.3 /usr/lib/petscdir/2.3.2
78 $ENV{HOME}/petsc
79 DOC "PETSc Directory")
80
81find_program (MAKE_EXECUTABLE NAMES make gmake)
82
83if (PETSC_DIR AND NOT PETSC_ARCH)
84 set (_petsc_arches
85 $ENV{PETSC_ARCH} # If set, use environment variable first
86 linux-gnu-c-debug linux-gnu-c-opt # Debian defaults
87 x86_64-unknown-linux-gnu i386-unknown-linux-gnu)
88 set (petscconf "NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
89 foreach (arch ${_petsc_arches})
90 if (NOT PETSC_ARCH)
91 find_path (petscconf petscconf.h
92 HINTS ${PETSC_DIR}
93 PATH_SUFFIXES ${arch}/include bmake/${arch}
94 NO_DEFAULT_PATH)
95 if (petscconf)
96 set (PETSC_ARCH "${arch}" CACHE STRING "PETSc build architecture")
97 endif (petscconf)
98 endif (NOT PETSC_ARCH)
99 endforeach (arch)
100 set (petscconf "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE)
101endif (PETSC_DIR AND NOT PETSC_ARCH)
102
103set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARIES_KSP LIBRARIES_SNES LIBRARIES_TS
104 INCLUDE_DIR INCLUDE_CONF)
105include (FindPackageMultipass)
106find_package_multipass (PETSc petsc_config_current
107 STATES DIR ARCH
108 DEPENDENTS INCLUDES LIBRARIES COMPILER MPIEXEC ${petsc_slaves})
109
110# Determine whether the PETSc layout is old-style (through 2.3.3) or
111# new-style (>= 3.0.0)
112if (EXISTS "${PETSC_DIR}/${PETSC_ARCH}/include/petscconf.h") # > 2.3.3
113 set (petsc_conf_rules "${PETSC_DIR}/conf/rules")
114 set (petsc_conf_variables "${PETSC_DIR}/conf/variables")
115elseif (EXISTS "${PETSC_DIR}/bmake/${PETSC_ARCH}/petscconf.h") # <= 2.3.3
116 set (petsc_conf_rules "${PETSC_DIR}/bmake/common/rules")
117 set (petsc_conf_variables "${PETSC_DIR}/bmake/common/variables")
118elseif (PETSC_DIR)
119 message (SEND_ERROR "The pair PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} do not specify a valid PETSc installation")
120endif ()
121
122if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current)
123 petsc_get_version()
124
125 # Put variables into environment since they are needed to get
126 # configuration (petscvariables) in the PETSc makefile
127 set (ENV{PETSC_DIR} "${PETSC_DIR}")
128 set (ENV{PETSC_ARCH} "${PETSC_ARCH}")
129
130 # A temporary makefile to probe the PETSc configuration
131 set (petsc_config_makefile "${PROJECT_BINARY_DIR}/Makefile.petsc")
132 file (WRITE "${petsc_config_makefile}"
133"## This file was autogenerated by FindPETSc.cmake
134# PETSC_DIR = ${PETSC_DIR}
135# PETSC_ARCH = ${PETSC_ARCH}
136include ${petsc_conf_rules}
137include ${petsc_conf_variables}
138show :
139\t-@echo -n \${\${VARIABLE}}
140")
141
142 macro (PETSC_GET_VARIABLE name var)
143 set (${var} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE)
144 execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} show VARIABLE=${name}
145 OUTPUT_VARIABLE ${var}
146 RESULT_VARIABLE petsc_return)
147 endmacro (PETSC_GET_VARIABLE)
148 petsc_get_variable (PETSC_LIB_DIR petsc_lib_dir)
149 petsc_get_variable (PETSC_EXTERNAL_LIB_BASIC petsc_libs_external)
150 petsc_get_variable (PETSC_CCPPFLAGS petsc_cpp_line)
151 petsc_get_variable (PETSC_INCLUDE petsc_include)
152 petsc_get_variable (PCC petsc_cc)
153 petsc_get_variable (PCC_FLAGS petsc_cc_flags)
154 petsc_get_variable (MPIEXEC petsc_mpiexec)
155 # We are done with the temporary Makefile, calling PETSC_GET_VARIABLE after this point is invalid!
156 file (REMOVE ${petsc_config_makefile})
157
158 include (ResolveCompilerPaths)
159 # Extract include paths and libraries from compile command line
160 resolve_includes (petsc_includes_all "${petsc_cpp_line}")
161
162 #on windows we need to make sure we're linking against the right
163 #runtime library
164 if (WIN32)
165 if (petsc_cc_flags MATCHES "-MT")
166 set(using_md False)
167 foreach(flag_var
168 CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
169 CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
170 CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
171 CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
172 if(${flag_var} MATCHES "/MD")
173 set(using_md True)
174 endif(${flag_var} MATCHES "/MD")
175 endforeach(flag_var)
176 if(${using_md} MATCHES "True")
177 message(WARNING "PETSc was built with /MT, but /MD is currently set.
178See http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F")
179 endif(${using_md} MATCHES "True")
180 endif (petsc_cc_flags MATCHES "-MT")
181 endif (WIN32)
182
183 include (CorrectWindowsPaths)
184 convert_cygwin_path(petsc_lib_dir)
185 message (STATUS "petsc_lib_dir ${petsc_lib_dir}")
186
187 macro (PETSC_FIND_LIBRARY suffix name)
188 set (PETSC_LIBRARY_${suffix} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) # Clear any stale value, if we got here, we need to find it again
189 if (WIN32)
190 set (libname lib${name}) #windows expects "libfoo", linux expects "foo"
191 else (WIN32)
192 set (libname ${name})
193 endif (WIN32)
194 find_library (PETSC_LIBRARY_${suffix} NAMES ${libname} HINTS ${petsc_lib_dir} NO_DEFAULT_PATH)
195 set (PETSC_LIBRARIES_${suffix} "${PETSC_LIBRARY_${suffix}}")
196 mark_as_advanced (PETSC_LIBRARY_${suffix})
197 endmacro (PETSC_FIND_LIBRARY suffix name)
198
199 # Look for petscvec first, if it doesn't exist, we must be using single-library
200 petsc_find_library (VEC petscvec)
201 if (PETSC_LIBRARY_VEC)
202 petsc_find_library (SYS "petscsys;petsc") # libpetscsys is called libpetsc prior to 3.1 (when single-library was introduced)
203 petsc_find_library (MAT petscmat)
204 petsc_find_library (DM petscdm)
205 petsc_find_library (KSP petscksp)
206 petsc_find_library (SNES petscsnes)
207 petsc_find_library (TS petscts)
208 macro (PETSC_JOIN libs deps)
209 list (APPEND PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${deps}})
210 endmacro (PETSC_JOIN libs deps)
211 petsc_join (VEC SYS)
212 petsc_join (MAT VEC)
213 petsc_join (DM MAT)
214 petsc_join (KSP DM)
215 petsc_join (SNES KSP)
216 petsc_join (TS SNES)
217 petsc_join (ALL TS)
218 else ()
219 set (PETSC_LIBRARY_VEC "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) # There is no libpetscvec
220 petsc_find_library (SINGLE petsc)
221 foreach (pkg SYS VEC MAT DM KSP SNES TS ALL)
222 set (PETSC_LIBRARIES_${pkg} "${PETSC_LIBRARY_SINGLE}")
223 endforeach ()
224 endif ()
225 if (PETSC_LIBRARY_TS)
226 message (STATUS "Recognized PETSc install with separate libraries for each package")
227 else ()
228 message (STATUS "Recognized PETSc install with single library for all packages")
229 endif ()
230
231 include(Check${PETSC_LANGUAGE_BINDINGS}SourceRuns)
232 macro (PETSC_TEST_RUNS includes libraries runs)
233 if(${PETSC_LANGUAGE_BINDINGS} STREQUAL "C")
234 set(_PETSC_ERR_FUNC "CHKERRQ(ierr)")
235 elseif(${PETSC_LANGUAGE_BINDINGS} STREQUAL "CXX")
236 set(_PETSC_ERR_FUNC "CHKERRXX(ierr)")
237 endif()
238 if (PETSC_VERSION VERSION_GREATER 3.1)
239 set (_PETSC_TSDestroy "TSDestroy(&ts)")
240 else ()
241 set (_PETSC_TSDestroy "TSDestroy(ts)")
242 endif ()
243
244 set(_PETSC_TEST_SOURCE "
245static const char help[] = \"PETSc test program.\";
246#include <petscts.h>
247int main(int argc,char *argv[]) {
248PetscErrorCode ierr;
249TS ts;
250
251ierr = PetscInitialize(&argc,&argv,0,help);${_PETSC_ERR_FUNC};
252ierr = TSCreate(PETSC_COMM_WORLD,&ts);${_PETSC_ERR_FUNC};
253ierr = TSSetFromOptions(ts);${_PETSC_ERR_FUNC};
254ierr = ${_PETSC_TSDestroy};${_PETSC_ERR_FUNC};
255ierr = PetscFinalize();${_PETSC_ERR_FUNC};
256return 0;
257}
258")
259 multipass_source_runs ("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs} "${PETSC_LANGUAGE_BINDINGS}")
260 if (${${runs}})
261 set (PETSC_EXECUTABLE_RUNS "YES" CACHE BOOL
262 "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)
263 endif (${${runs}})
264 endmacro (PETSC_TEST_RUNS)
265
266
267 find_path (PETSC_INCLUDE_DIR petscts.h HINTS "${PETSC_DIR}" PATH_SUFFIXES include NO_DEFAULT_PATH)
268 find_path (PETSC_INCLUDE_CONF petscconf.h HINTS "${PETSC_DIR}" PATH_SUFFIXES "${PETSC_ARCH}/include" "bmake/${PETSC_ARCH}" NO_DEFAULT_PATH)
269 mark_as_advanced (PETSC_INCLUDE_DIR PETSC_INCLUDE_CONF)
270 set (petsc_includes_minimal ${PETSC_INCLUDE_CONF} ${PETSC_INCLUDE_DIR})
271
272 petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_minimal)
273 if (petsc_works_minimal)
274 message (STATUS "Minimal PETSc includes and libraries work. This probably means we are building with shared libs.")
275 set (petsc_includes_needed "${petsc_includes_minimal}")
276 else (petsc_works_minimal) # Minimal includes fail, see if just adding full includes fixes it
277 petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_allincludes)
278 if (petsc_works_allincludes) # It does, we just need all the includes (
279 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).")
280 set (petsc_includes_needed ${petsc_includes_all})
281 else (petsc_works_allincludes) # We are going to need to link the external libs explicitly
282 resolve_libraries (petsc_libraries_external "${petsc_libs_external}")
283 foreach (pkg SYS VEC MAT DM KSP SNES TS ALL)
284 list (APPEND PETSC_LIBRARIES_${pkg} ${petsc_libraries_external})
285 endforeach (pkg)
286 petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_alllibraries)
287 if (petsc_works_alllibraries)
288 message (STATUS "PETSc only need minimal includes, but requires explicit linking to all dependencies. This is expected when PETSc is built with static libraries.")
289 set (petsc_includes_needed ${petsc_includes_minimal})
290 else (petsc_works_alllibraries)
291 # It looks like we really need everything, should have listened to Matt
292 set (petsc_includes_needed ${petsc_includes_all})
293 petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_all)
294 if (petsc_works_all) # We fail anyways
295 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.")
296 else (petsc_works_all) # We fail anyways
297 message (STATUS "PETSc could not be used, maybe the install is broken.")
298 endif (petsc_works_all)
299 endif (petsc_works_alllibraries)
300 endif (petsc_works_allincludes)
301 endif (petsc_works_minimal)
302
303 # We do an out-of-source build so __FILE__ will be an absolute path, hence __INSDIR__ is superfluous
304 if (${PETSC_VERSION} VERSION_LESS 3.1)
305 set (PETSC_DEFINITIONS "-D__SDIR__=\"\"" CACHE STRING "PETSc definitions" FORCE)
306 else ()
307 set (PETSC_DEFINITIONS "-D__INSDIR__=" CACHE STRING "PETSc definitions" FORCE)
308 endif ()
309 # Sometimes this can be used to assist FindMPI.cmake
310 set (PETSC_MPIEXEC ${petsc_mpiexec} CACHE FILEPATH "Executable for running PETSc MPI programs" FORCE)
311 set (PETSC_INCLUDES ${petsc_includes_needed} CACHE STRING "PETSc include path" FORCE)
312 set (PETSC_LIBRARIES ${PETSC_LIBRARIES_ALL} CACHE STRING "PETSc libraries" FORCE)
313 set (PETSC_COMPILER ${petsc_cc} CACHE FILEPATH "PETSc compiler" FORCE)
314 # Note that we have forced values for all these choices. If you
315 # change these, you are telling the system to trust you that they
316 # work. It is likely that you will end up with a broken build.
317 mark_as_advanced (PETSC_INCLUDES PETSC_LIBRARIES PETSC_COMPILER PETSC_DEFINITIONS PETSC_MPIEXEC PETSC_EXECUTABLE_RUNS)
318endif ()
319
320include (FindPackageHandleStandardArgs)
321find_package_handle_standard_args (PETSc
322 "PETSc could not be found. Be sure to set PETSC_DIR and PETSC_ARCH."
323 PETSC_INCLUDES PETSC_LIBRARIES PETSC_EXECUTABLE_RUNS)

Archive Download this file

Revision: HEAD