CMakeLists.txt 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. # Copyright 2007 - 2021, Alan Antonuk and the rabbitmq-c contributors.
  2. # SPDX-License-Identifier: mit
  3. cmake_minimum_required(VERSION 3.22...3.26)
  4. set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
  5. # Follow all steps below in order to calculate new ABI version when updating the library
  6. # NOTE: THIS IS UNRELATED to the actual project version
  7. #
  8. # 1. If the library source code has changed at all since the last update, then increment revision
  9. # 2. If any interfaces have been added, removed, or changed since the last update, increment current and set revision to 0.
  10. # 3. If any interfaces have been added since the last public release, then increment age.
  11. # 4. If any interfaces have been removed since the last public release, then set age to 0.
  12. set(RMQ_SOVERSION_CURRENT 9)
  13. set(RMQ_SOVERSION_REVISION 4)
  14. set(RMQ_SOVERSION_AGE 5)
  15. include(VersionFunctions)
  16. get_library_version(RMQ_VERSION)
  17. compute_soversion(${RMQ_SOVERSION_CURRENT} ${RMQ_SOVERSION_REVISION} ${RMQ_SOVERSION_AGE} RMQ_SOVERSION)
  18. project(rabbitmq-c
  19. VERSION ${RMQ_VERSION}
  20. DESCRIPTION "C RabbitMQ AMQP client library"
  21. LANGUAGES C)
  22. set(CMAKE_C_STANDARD 99)
  23. set(CMAKE_C_STANDARD_REQUIRED ON)
  24. set(CMAKE_C_EXTENSIONS ON)
  25. set(CMAKE_C_VISIBILITY_PRESET hidden)
  26. set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
  27. set(default_build_type "Release")
  28. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  29. message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
  30. set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
  31. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
  32. endif()
  33. include(CheckSymbolExists)
  34. include(CheckLibraryExists)
  35. include(CMakePushCheckState)
  36. include(GNUInstallDirs)
  37. # Detect if we need to link against a socket library:
  38. cmake_push_check_state()
  39. if (WIN32)
  40. # Always use WinSock2 on Windows
  41. set(SOCKET_LIBRARIES ws2_32)
  42. else ()
  43. # Is it in the default link?
  44. check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO)
  45. if (NOT (HAVE_GETADDRINFO EQUAL 1))
  46. SET(CMAKE_REQUIRED_LIBRARIES "socket")
  47. check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO2)
  48. if (HAVE_GETADDRINFO2 EQUAL 1)
  49. set(SOCKET_LIBRARIES socket)
  50. else ()
  51. SET(CMAKE_REQUIRED_LIBRARIES "socket;nsl")
  52. check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO3)
  53. if (HAVE_GETADDRINFO3 EQUAL 1)
  54. set(SOCKET_LIBRARIES socket nsl)
  55. else ()
  56. message(FATAL_ERROR "Cannot find name resolution library (containing symbol getaddrinfo)")
  57. endif ()
  58. endif ()
  59. endif ()
  60. set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES})
  61. check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET)
  62. if (NOT HAVE_SOCKET EQUAL 1)
  63. set(CMAKE_REQUIRED_LIBRARIES socket ${SOCKET_LIBRARIES})
  64. check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET2)
  65. if (HAVE_SOCKET2 EQUAL 1)
  66. set(SOCKET_LIBRARIES socket ${SOCKET_LIBRARIES})
  67. else ()
  68. set(CMAKE_REQUIRED_LIBRARIES socket nsl ${SOCKET_LIBRARIES})
  69. check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET3)
  70. if (HAVE_SOCKET3 EQUAL 1)
  71. set(SOCKET_LIBRARIES socket nsl ${SOCKET_LIBRARIES})
  72. else ()
  73. message(FATAL_ERROR "Cannot find socket library (containing symbol socket)")
  74. endif ()
  75. endif ()
  76. endif ()
  77. endif ()
  78. cmake_pop_check_state()
  79. cmake_push_check_state()
  80. set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES})
  81. check_symbol_exists(poll poll.h HAVE_POLL)
  82. if (NOT HAVE_POLL)
  83. if (WIN32)
  84. set(HAVE_SELECT 1)
  85. else()
  86. check_symbol_exists(select sys/select.h HAVE_SELECT)
  87. endif()
  88. if (NOT HAVE_SELECT)
  89. message(FATAL_ERROR "rabbitmq-c requires poll() or select() to be available")
  90. endif()
  91. endif()
  92. cmake_pop_check_state()
  93. check_library_exists(rt clock_gettime "time.h" CLOCK_GETTIME_NEEDS_LIBRT)
  94. check_library_exists(rt posix_spawnp "spawn.h" POSIX_SPAWNP_NEEDS_LIBRT)
  95. if (CLOCK_GETTIME_NEEDS_LIBRT OR POSIX_SPAWNP_NEEDS_LIBRT)
  96. set(LIBRT rt)
  97. endif()
  98. option(ENABLE_SSL_SUPPORT "Enable SSL support" ON)
  99. if (ENABLE_SSL_SUPPORT)
  100. set(RMQ_OPENSSL_MIN_VERSION 1.1.1)
  101. find_package(OpenSSL "${RMQ_OPENSSL_MIN_VERSION}" REQUIRED)
  102. cmake_push_check_state()
  103. set(THREADS_PREFER_PTHREAD_FLAG ON)
  104. find_package(Threads REQUIRED)
  105. cmake_pop_check_state()
  106. endif()
  107. if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
  108. include(CTest)
  109. endif()
  110. include(CMakeDependentOption)
  111. option(BUILD_SHARED_LIBS "Build rabbitmq-c as a shared library" ON)
  112. option(BUILD_STATIC_LIBS "Build rabbitmq-c as a static library" ON)
  113. option(INSTALL_STATIC_LIBS "Install rabbitmq-c static library" ON)
  114. option(BUILD_EXAMPLES "Build Examples" OFF)
  115. option(BUILD_TOOLS "Build Tools (requires POPT Library)" OFF)
  116. cmake_dependent_option(BUILD_TOOLS_DOCS "Build man pages for tools (requires xmlto)" OFF "BUILD_TOOLS" OFF)
  117. option(BUILD_API_DOCS "Build Doxygen API docs" OFF)
  118. option(RUN_SYSTEM_TESTS "Run system tests (i.e. tests requiring an accessible RabbitMQ server instance on localhost)" OFF)
  119. option(BUILD_OSSFUZZ "Build OSSFUZZ" OFF)
  120. if (NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
  121. message(FATAL_ERROR "One or both of BUILD_SHARED_LIBS or BUILD_STATIC_LIBS must be set to ON to build")
  122. endif()
  123. set(targets_export_name rabbitmq-targets)
  124. if(BUILD_OSSFUZZ)
  125. if (NOT BUILD_STATIC_LIBS)
  126. message(FATAL_ERROR "OSS-FUZZ can only be built against static libraries " "(set BUILD_STATIC_LIBS=ON)")
  127. endif ()
  128. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
  129. SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
  130. endif ()
  131. add_subdirectory(librabbitmq)
  132. if(BUILD_EXAMPLES)
  133. if(NOT BUILD_SHARED_LIBS)
  134. message(FATAL_ERROR "Examples require -DBUILD_SHARED_LIBS=ON")
  135. endif()
  136. add_subdirectory(examples)
  137. endif()
  138. if(BUILD_TOOLS)
  139. find_package(POPT REQUIRED)
  140. if(BUILD_TOOLS_DOCS)
  141. find_package(XMLTO REQUIRED)
  142. endif()
  143. add_subdirectory(tools)
  144. endif()
  145. if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
  146. if (NOT BUILD_STATIC_LIBS)
  147. message(FATAL_ERROR
  148. "Tests can only be built against static libraries "
  149. "(set BUILD_STATIC_LIBS=ON)")
  150. endif ()
  151. add_subdirectory(tests)
  152. endif ()
  153. if(BUILD_OSSFUZZ)
  154. add_subdirectory(fuzz)
  155. endif ()
  156. if (BUILD_API_DOCS)
  157. find_package(Doxygen REQUIRED)
  158. configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile @ONLY)
  159. add_custom_target(docs
  160. COMMAND ${DOXYGEN_EXECUTABLE}
  161. VERBATIM
  162. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs
  163. DEPENDS rabbitmq
  164. COMMENT "Generating API documentation"
  165. SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in
  166. )
  167. endif ()
  168. foreach (lib ${SOCKET_LIBRARIES})
  169. set(libs_private "${libs_private} -l${lib}")
  170. endforeach(lib)
  171. set(libs_private "${libs_private} -l${LIBRT}")
  172. if (ENABLE_SSL_SUPPORT)
  173. set(libs_private "${libs_private} -lssl -lcrypto ${CMAKE_THREAD_LIBS_INIT}")
  174. endif()
  175. set(prefix ${CMAKE_INSTALL_PREFIX})
  176. set(exec_prefix "\${prefix}")
  177. cmake_path(APPEND libdir "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
  178. cmake_path(APPEND includedir "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
  179. configure_file(cmake/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq/config.h)
  180. configure_file(librabbitmq.pc.in ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq.pc @ONLY)
  181. include(CMakePackageConfigHelpers)
  182. set(RMQ_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/rabbitmq-c)
  183. set(project_config "${CMAKE_CURRENT_BINARY_DIR}/rabbitmq-c-config.cmake")
  184. set(version_config "${CMAKE_CURRENT_BINARY_DIR}/rabbitmq-c-config-version.cmake")
  185. write_basic_package_version_file(
  186. "${version_config}"
  187. VERSION ${RMQ_VERSION}
  188. COMPATIBILITY SameMajorVersion)
  189. configure_package_config_file(
  190. "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rabbitmq-c-config.cmake.in"
  191. "${project_config}"
  192. INSTALL_DESTINATION "${RMQ_CMAKE_DIR}")
  193. if(BUILD_SHARED_LIBS)
  194. list(APPEND INSTALL_TARGETS rabbitmq)
  195. endif()
  196. if(BUILD_STATIC_LIBS AND INSTALL_STATIC_LIBS)
  197. list(APPEND INSTALL_TARGETS rabbitmq-static)
  198. endif()
  199. export(TARGETS ${INSTALL_TARGETS}
  200. NAMESPACE rabbitmq::
  201. FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake)
  202. install(FILES ${project_config} ${version_config}
  203. DESTINATION ${RMQ_CMAKE_DIR}
  204. COMPONENT rabbitmq-c-development
  205. )
  206. install(EXPORT ${targets_export_name}
  207. DESTINATION ${RMQ_CMAKE_DIR}
  208. NAMESPACE rabbitmq::
  209. COMPONENT rabbitmq-c-development
  210. )
  211. install(FILES
  212. ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq.pc
  213. DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
  214. )
  215. if (BUILD_SHARED_LIBS)
  216. message(STATUS "Building rabbitmq as a shared library - yes")
  217. else ()
  218. message(STATUS "Building rabbitmq as a shared library - no")
  219. endif ()
  220. if (BUILD_STATIC_LIBS)
  221. message(STATUS "Building rabbitmq as a static library - yes")
  222. else ()
  223. message(STATUS "Building rabbitmq as a static library - no")
  224. endif ()