FindPostgreSQL.cmake 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. # Find PostgreSQL.
  2. #
  3. # Specifically, this finds the C client library (libpq) that can be used to talk to PostgreSQL databases.
  4. #
  5. # Set this variable to any additional path you want the module to search:
  6. # PostgreSQL_DIR
  7. #
  8. # Imported targets defined by this module:
  9. # PostgreSQL::pq - shared library if available, or static if that's all there is
  10. # PostgreSQL::pq_shared - shared library
  11. # PostgreSQL::pq_static - static library
  12. #
  13. # Informational variables:
  14. # PostgreSQL_FOUND - PostgreSQL (or all requested components of PostgreSQL) was found.
  15. # PostgreSQL_VERSION - the version of PostgreSQL that was found
  16. #
  17. include(CacheLog)
  18. include(FindPackageHandleStandardArgs)
  19. # Helper function for globbing for directories.
  20. function(append_glob_dirs list_name glob_path)
  21. file(TO_CMAKE_PATH "${glob_path}" glob_path)
  22. file(GLOB dirs LIST_DIRECTORIES true "${glob_path}")
  23. if (dirs)
  24. list(APPEND ${list_name} "${dirs}")
  25. set(${list_name} "${${list_name}}" PARENT_SCOPE)
  26. endif ()
  27. endfunction()
  28. # If PostgreSQL_DIR has changed since the last invocation, wipe internal cache variables so we can search for everything
  29. # again.
  30. if (NOT "${PostgreSQL_DIR}" STREQUAL "${_internal_old_postgresql_dir}")
  31. unset_cachelog_entries()
  32. endif ()
  33. reset_cachelog()
  34. set(_old_suffixes "${CMAKE_FIND_LIBRARY_SUFFIXES}")
  35. # Set path guesses.
  36. set(_paths)
  37. if (CMAKE_HOST_WIN32)
  38. if (CMAKE_SIZEOF_VOID_P EQUAL 8)
  39. set(archdir "$ENV{ProgramFiles}")
  40. set(notarchdir "$ENV{ProgramFiles\(x86\)}")
  41. set(arch 64)
  42. else ()
  43. set(archdir "$ENV{ProgramFiles\(x86\)}")
  44. set(notarchdir "$ENV{ProgramFiles}")
  45. set(arch 32)
  46. endif ()
  47. # This should find installations from either the BigSQL or EDB Postgres installers.
  48. # (Note: I'd recommend BigSQL, it's built with MinGW, so it's easier to package)
  49. list(APPEND _paths /PostgreSQL${arch})
  50. append_glob_dirs(_paths "/PostgreSQL${arch}/pg*/")
  51. list(APPEND _paths /PostgreSQL)
  52. append_glob_dirs(_paths "/PostgreSQL/pg*/")
  53. list(APPEND _paths "${archdir}/PostgreSQL")
  54. append_glob_dirs(_paths "${archdir}/PostgreSQL/*/")
  55. list(APPEND _paths "${notarchdir}/PostgreSQL")
  56. append_glob_dirs(_paths "${notarchdir}/PostgreSQL/*/")
  57. else ()
  58. if (CMAKE_SIZEOF_VOID_P EQUAL 8)
  59. set(arch 64)
  60. else ()
  61. set(arch 32)
  62. endif ()
  63. list(APPEND _paths
  64. /usr/local/postgresql${arch}
  65. /usr/local/pgsql${arch}
  66. /usr/local/postgresql
  67. /usr/local/pgsql
  68. )
  69. append_glob_dirs(_paths "/usr/pgsql-*")
  70. endif ()
  71. # Find include directory.
  72. find_path(PostgreSQL_INCLUDE_DIR
  73. NAMES libpq-fe.h
  74. HINTS ${PostgreSQL_DIR}
  75. $ENV{PostgreSQL_DIR}
  76. ${POSTGRESQL_ROOT_DIR}
  77. PATHS ${_paths}
  78. PATH_SUFFIXES include include/postgresql postgresql
  79. )
  80. add_to_cachelog(PostgreSQL_INCLUDE_DIR)
  81. if (PostgreSQL_INCLUDE_DIR)
  82. # Calculate root directory of installation from include directory.
  83. string(REGEX REPLACE "(/)*include(/)*.*$" "" _root_dir "${PostgreSQL_INCLUDE_DIR}")
  84. set(PostgreSQL_DIR "${_root_dir}" CACHE PATH "Root directory of PostgreSQL installation" FORCE)
  85. set(_internal_old_postgresql_dir "${PostgreSQL_DIR}" CACHE INTERNAL "" FORCE)
  86. mark_as_advanced(FORCE PostgreSQL_DIR)
  87. # Find version by parsing the pg_config.h header.
  88. set(header "${PostgreSQL_INCLUDE_DIR}/pg_config_x86_64.h")
  89. if (NOT EXISTS "${header}")
  90. set(header "${PostgreSQL_INCLUDE_DIR}/pg_config_x86.h")
  91. if (NOT EXISTS "${header}")
  92. set(header "${PostgreSQL_INCLUDE_DIR}/pg_config.h")
  93. if (NOT EXISTS "${header}")
  94. set(header)
  95. endif ()
  96. endif ()
  97. endif ()
  98. if (header)
  99. file(STRINGS "${header}" _ver_str
  100. REGEX "^[ \t]*#[ \t]*define[\t ]+PG_VERSION[ \t]+\".*\"")
  101. if (_ver_str MATCHES "^[ \t]*#[ \t]*define[\t ]+PG_VERSION[ \t]+\"([^\"]*)\"")
  102. set(PostgreSQL_VERSION "${CMAKE_MATCH_1}")
  103. endif ()
  104. endif ()
  105. # Find static library (if not on Windows, none of the installers I could find there had a static libpq)).
  106. if (WIN32)
  107. set(PostgreSQL_STATIC_LIBRARY "PostgreSQL_STATIC_LIBRARY-NOTFOUND" CACHE PATH "Path to libpq static lib")
  108. else ()
  109. set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
  110. foreach(defpath "NO_DEFAULT_PATH" "")
  111. find_library(PostgreSQL_STATIC_LIBRARY
  112. NAMES pq libpq
  113. NAMES_PER_DIR
  114. HINTS ${PostgreSQL_DIR}
  115. PATH_SUFFIXES lib
  116. ${defpath}
  117. )
  118. if (PostgreSQL_STATIC_LIBRARY)
  119. break()
  120. endif ()
  121. endforeach()
  122. endif ()
  123. add_to_cachelog(PostgreSQL_STATIC_LIBRARY)
  124. if (PostgreSQL_STATIC_LIBRARY)
  125. set(PostgreSQL_pq_static_FOUND TRUE)
  126. set(PostgreSQL_pq_FOUND TRUE)
  127. endif ()
  128. # Find shared library (will pick up static lib if shared not found).
  129. set(CMAKE_FIND_LIBRARY_SUFFIXES "${_old_suffixes}")
  130. if (WIN32)
  131. list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".a") #BigSQL installer names the import lib with a .a extension
  132. endif ()
  133. foreach(defpath "NO_DEFAULT_PATH" "")
  134. find_library(PostgreSQL_LIBRARY
  135. NAMES pq libpq
  136. NAMES_PER_DIR
  137. HINTS ${PostgreSQL_DIR}
  138. PATH_SUFFIXES lib
  139. ${defpath}
  140. )
  141. if (PostgreSQL_LIBRARY)
  142. break()
  143. endif ()
  144. endforeach()
  145. add_to_cachelog(PostgreSQL_LIBRARY)
  146. if (PostgreSQL_LIBRARY AND NOT PostgreSQL_LIBRARY STREQUAL PostgreSQL_STATIC_LIBRARY)
  147. set(PostgreSQL_pq_shared_FOUND TRUE)
  148. set(PostgreSQL_pq_FOUND TRUE)
  149. endif ()
  150. # Find the DLL (if any).
  151. if (WIN32)
  152. set(CMAKE_FIND_LIBRARY_SUFFIXES .dll)
  153. foreach(defpath "NO_DEFAULT_PATH" "")
  154. find_library(PostgreSQL_DLL_LIBRARY
  155. NAMES pq libpq
  156. NAMES_PER_DIR
  157. HINTS ${PostgreSQL_DIR}
  158. PATH_SUFFIXES bin lib ""
  159. ${defpath}
  160. )
  161. if (PostgreSQL_DLL_LIBRARY)
  162. break()
  163. endif ()
  164. endforeach()
  165. add_to_cachelog(PostgreSQL_DLL_LIBRARY)
  166. endif ()
  167. endif ()
  168. set(_reqs PostgreSQL_INCLUDE_DIR)
  169. if (NOT PostgreSQL_FIND_COMPONENTS) # If user didn't request any particular component explicitly:
  170. list(APPEND _reqs PostgreSQL_LIBRARY) # Will contain shared lib, or static lib if no shared lib present
  171. endif ()
  172. find_package_handle_standard_args(PostgreSQL
  173. REQUIRED_VARS ${_reqs}
  174. VERSION_VAR PostgreSQL_VERSION
  175. HANDLE_COMPONENTS
  176. FAIL_MESSAGE "PostgreSQL not found, try -DPostgreSQL_DIR=<path>"
  177. )
  178. add_to_cachelog(FIND_PACKAGE_MESSAGE_DETAILS_PostgreSQL)
  179. # Static library.
  180. if (PostgreSQL_pq_static_FOUND AND NOT TARGET PostgreSQL::pq_static)
  181. add_library(PostgreSQL::pq_static STATIC IMPORTED)
  182. set_target_properties(PostgreSQL::pq_static PROPERTIES
  183. IMPORTED_LOCATION "${PostgreSQL_STATIC_LIBRARY}"
  184. IMPORTED_LINK_INTERFACE_LANGUAGES "C"
  185. INTERFACE_INCLUDE_DIRECTORIES "${PostgreSQL_INCLUDE_DIR}"
  186. )
  187. set(_pq_any PostgreSQL::pq_static)
  188. endif ()
  189. # Shared library.
  190. if (PostgreSQL_pq_shared_FOUND AND NOT TARGET PostgreSQL::pq_shared)
  191. add_library(PostgreSQL::pq_shared SHARED IMPORTED)
  192. set_target_properties(PostgreSQL::pq_shared PROPERTIES
  193. IMPORTED_LINK_INTERFACE_LANGUAGES "C"
  194. INTERFACE_INCLUDE_DIRECTORIES "${PostgreSQL_INCLUDE_DIR}"
  195. )
  196. if (WIN32)
  197. set_target_properties(PostgreSQL::pq_shared PROPERTIES
  198. IMPORTED_IMPLIB "${PostgreSQL_LIBRARY}"
  199. )
  200. if (PostgreSQL_DLL_LIBRARY)
  201. set_target_properties(PostgreSQL::pq_shared PROPERTIES
  202. IMPORTED_LOCATION "${PostgreSQL_DLL_LIBRARY}"
  203. )
  204. endif ()
  205. else ()
  206. set_target_properties(PostgreSQL::pq_shared PROPERTIES
  207. IMPORTED_LOCATION "${PostgreSQL_LIBRARY}"
  208. )
  209. endif ()
  210. set(_pq_any PostgreSQL::pq_shared)
  211. endif ()
  212. # I-don't-care library (shared, or static if shared not available).
  213. if (PostgreSQL_pq_FOUND AND NOT TARGET PostgreSQL::pq)
  214. add_library(PostgreSQL::pq INTERFACE IMPORTED)
  215. set_target_properties(PostgreSQL::pq PROPERTIES
  216. INTERFACE_LINK_LIBRARIES ${_pq_any}
  217. )
  218. endif ()
  219. set(CMAKE_FIND_LIBRARY_SUFFIXES "${_old_suffixes}")
  220. # From https://github.com/Monetra/mstdlib/blob/master/CMakeModules
  221. # The MIT License (MIT)
  222. # Copyright (c) 2015-2017 Main Street Softworks, Inc.
  223. # Permission is hereby granted, free of charge, to any person obtaining a copy
  224. # of this software and associated documentation files (the "Software"), to deal
  225. # in the Software without restriction, including without limitation the rights
  226. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  227. # copies of the Software, and to permit persons to whom the Software is
  228. # furnished to do so, subject to the following conditions:
  229. # The above copyright notice and this permission notice shall be included in
  230. # all copies or substantial portions of the Software.
  231. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  232. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  233. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  234. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  235. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  236. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  237. # THE SOFTWARE.