CMakeLists.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. cmake_minimum_required(VERSION 2.8.12)
  2. project(rabbitmq-c "C")
  3. # Enable MACOSX_RPATH by default. See: cmake --help-policy CMP0042
  4. if (POLICY CMP0042)
  5. cmake_policy(SET CMP0042 NEW)
  6. endif()
  7. set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
  8. # Follow all steps below in order to calculate new ABI version when updating the library
  9. # NOTE: THIS IS UNRELATED to the actual project version
  10. #
  11. # 1. If the library source code has changed at all since the last update, then increment revision
  12. # 2. If any interfaces have been added, removed, or changed since the last update, increment current and set revision to 0.
  13. # 3. If any interfaces have been added since the last public release, then increment age.
  14. # 4. If any interfaces have been removed since the last public release, then set age to 0.
  15. set(RMQ_SOVERSION_CURRENT 7)
  16. set(RMQ_SOVERSION_REVISION 0)
  17. set(RMQ_SOVERSION_AGE 3)
  18. math(EXPR RMQ_SOVERSION_MAJOR "${RMQ_SOVERSION_CURRENT} - ${RMQ_SOVERSION_AGE}")
  19. math(EXPR RMQ_SOVERSION_MINOR "${RMQ_SOVERSION_AGE}")
  20. math(EXPR RMQ_SOVERSION_PATCH "${RMQ_SOVERSION_REVISION}")
  21. set(RMQ_VERSION ${RMQ_SOVERSION_MAJOR}.${RMQ_SOVERSION_MINOR}.${RMQ_SOVERSION_PATCH})
  22. set(RMQ_SOVERSION ${RMQ_SOVERSION_MAJOR})
  23. file(STRINGS librabbitmq/amqp.h _API_VERSION_MAJOR REGEX "^#define AMQP_VERSION_MAJOR [0-9]+$")
  24. file(STRINGS librabbitmq/amqp.h _API_VERSION_MINOR REGEX "^#define AMQP_VERSION_MINOR [0-9]+$")
  25. file(STRINGS librabbitmq/amqp.h _API_VERSION_PATCH REGEX "^#define AMQP_VERSION_PATCH [0-9]+$")
  26. string(REGEX MATCH "[0-9]+" _API_VERSION_MAJOR ${_API_VERSION_MAJOR})
  27. string(REGEX MATCH "[0-9]+" _API_VERSION_MINOR ${_API_VERSION_MINOR})
  28. string(REGEX MATCH "[0-9]+" _API_VERSION_PATCH ${_API_VERSION_PATCH})
  29. # VERSION to match what is in autotools
  30. set(VERSION ${_API_VERSION_MAJOR}.${_API_VERSION_MINOR}.${_API_VERSION_PATCH})
  31. if (CMAKE_GENERATOR MATCHES ".*(Make|Ninja).*"
  32. AND NOT CMAKE_BUILD_TYPE)
  33. set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
  34. message(STATUS "CMAKE_BUILD_TYPE not specified. Creating ${CMAKE_BUILD_TYPE} build")
  35. endif()
  36. include(TestCInline)
  37. include(CheckSymbolExists)
  38. include(CheckLibraryExists)
  39. include(CMakePushCheckState)
  40. include(GNUInstallDirs)
  41. include(CheckCCompilerFlag)
  42. # Detect if we need to link against a socket library:
  43. cmake_push_check_state()
  44. if (WIN32)
  45. # Always use WinSock2 on Windows
  46. set(SOCKET_LIBRARIES ws2_32)
  47. else ()
  48. # Is it in the default link?
  49. check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO)
  50. if (NOT (HAVE_GETADDRINFO EQUAL 1))
  51. SET(CMAKE_REQUIRED_LIBRARIES "socket")
  52. check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO2)
  53. if (HAVE_GETADDRINFO2 EQUAL 1)
  54. set(SOCKET_LIBRARIES socket)
  55. else ()
  56. SET(CMAKE_REQUIRED_LIBRARIES "socket;nsl")
  57. check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO3)
  58. if (HAVE_GETADDRINFO3 EQUAL 1)
  59. set(SOCKET_LIBRARIES socket nsl)
  60. else ()
  61. message(FATAL_ERROR "Cannot find name resolution library (containing symbol getaddrinfo)")
  62. endif ()
  63. endif ()
  64. endif ()
  65. set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES})
  66. check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET)
  67. if (NOT HAVE_SOCKET EQUAL 1)
  68. set(CMAKE_REQUIRED_LIBRARIES socket ${SOCKET_LIBRARIES})
  69. check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET2)
  70. if (HAVE_SOCKET2 EQUAL 1)
  71. set(SOCKET_LIBRARIES socket ${SOCKET_LIBRARIES})
  72. else ()
  73. set(CMAKE_REQUIRED_LIBRARIES socket nsl ${SOCKET_LIBRARIES})
  74. check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET3)
  75. if (HAVE_SOCKET3 EQUAL 1)
  76. set(SOCKET_LIBRARIES socket nsl ${SOCKET_LIBRARIES})
  77. else ()
  78. message(FATAL_ERROR "Cannot find socket library (containing symbol socket)")
  79. endif ()
  80. endif ()
  81. endif ()
  82. endif ()
  83. cmake_pop_check_state()
  84. cmake_push_check_state()
  85. set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES})
  86. check_symbol_exists(poll poll.h HAVE_POLL)
  87. if (NOT HAVE_POLL)
  88. if (WIN32)
  89. set(HAVE_SELECT 1)
  90. else()
  91. check_symbol_exists(select sys/select.h HAVE_SELECT)
  92. endif()
  93. if (NOT HAVE_SELECT)
  94. message(FATAL_ERROR "rabbitmq-c requires poll() or select() to be available")
  95. endif()
  96. endif()
  97. cmake_pop_check_state()
  98. check_library_exists(rt clock_gettime "time.h" CLOCK_GETTIME_NEEDS_LIBRT)
  99. check_library_exists(rt posix_spawnp "spawn.h" POSIX_SPAWNP_NEEDS_LIBRT)
  100. if (CLOCK_GETTIME_NEEDS_LIBRT OR POSIX_SPAWNP_NEEDS_LIBRT)
  101. set(LIBRT rt)
  102. endif()
  103. option(ENABLE_SSL_SUPPORT "Enable SSL support" ON)
  104. if (ENABLE_SSL_SUPPORT)
  105. find_package(OpenSSL 0.9.8 REQUIRED)
  106. cmake_push_check_state()
  107. set(THREADS_PREFER_PTHREAD_FLAG ON)
  108. find_package(Threads REQUIRED)
  109. cmake_pop_check_state()
  110. endif()
  111. if (MSVC)
  112. set(CMAKE_C_FLAGS "/W4 /nologo ${CMAKE_C_FLAGS}")
  113. elseif (CMAKE_C_COMPILER_ID MATCHES ".*Clang")
  114. set(CMAKE_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wno-unused-function -fno-common -fvisibility=hidden ${CMAKE_C_FLAGS}")
  115. elseif (CMAKE_COMPILER_IS_GNUCC)
  116. set(RMQ_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wno-unused-function -fno-common")
  117. execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
  118. if (GCC_VERSION VERSION_GREATER 4.0 OR GCC_VERSION VERSION_EQUAL 4.0)
  119. set(RMQ_C_FLAGS "${RMQ_C_FLAGS} -fvisibility=hidden")
  120. endif()
  121. set(CMAKE_C_FLAGS "${RMQ_C_FLAGS} ${CMAKE_C_FLAGS}")
  122. endif ()
  123. CHECK_C_COMPILER_FLAG("-std=gnu90" HAVE_GNU90)
  124. if (HAVE_GNU90)
  125. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90")
  126. else()
  127. CHECK_C_COMPILER_FLAG("-std=c90" HAVE_C90)
  128. if (HAVE_C90)
  129. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c90")
  130. endif()
  131. endif()
  132. option(REGENERATE_AMQP_FRAMING "Regenerate amqp_framing.h/amqp_framing.c sources (for developer use)" OFF)
  133. mark_as_advanced(REGENERATE_AMQP_FRAMING)
  134. if (REGENERATE_AMQP_FRAMING)
  135. find_package(PythonInterp)
  136. if (NOT PYTHONINTERP_FOUND)
  137. message(FATAL_ERROR "REGENERATE_AMQP_FRAMING requires Python to be available")
  138. endif ()
  139. #Determine Python Version:
  140. if(PYTHON_EXECUTABLE)
  141. execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c
  142. "import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))"
  143. OUTPUT_VARIABLE _VERSION
  144. RESULT_VARIABLE _PYTHON_VERSION_RESULT
  145. ERROR_QUIET)
  146. if(NOT _PYTHON_VERSION_RESULT)
  147. string(REPLACE ";" "." PYTHON_VERSION_STRING "${_VERSION}")
  148. list(GET _VERSION 0 PYTHON_VERSION_MAJOR)
  149. list(GET _VERSION 1 PYTHON_VERSION_MINOR)
  150. list(GET _VERSION 2 PYTHON_VERSION_PATCH)
  151. if(PYTHON_VERSION_PATCH EQUAL 0)
  152. # it's called "Python 2.7", not "2.7.0"
  153. string(REGEX REPLACE "\\.0$" "" PYTHON_VERSION_STRING "${PYTHON_VERSION_STRING}")
  154. endif()
  155. else()
  156. # sys.version predates sys.version_info, so use that
  157. execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.version)"
  158. OUTPUT_VARIABLE _VERSION
  159. RESULT_VARIABLE _PYTHON_VERSION_RESULT
  160. ERROR_QUIET)
  161. if(NOT _PYTHON_VERSION_RESULT)
  162. string(REGEX REPLACE " .*" "" PYTHON_VERSION_STRING "${_VERSION}")
  163. string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" PYTHON_VERSION_MAJOR "${PYTHON_VERSION_STRING}")
  164. string(REGEX REPLACE "^[0-9]+\\.([0-9])+.*" "\\1" PYTHON_VERSION_MINOR "${PYTHON_VERSION_STRING}")
  165. if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*")
  166. string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PYTHON_VERSION_PATCH "${PYTHON_VERSION_STRING}")
  167. else()
  168. set(PYTHON_VERSION_PATCH "0")
  169. endif()
  170. else()
  171. # sys.version was first documented for Python 1.5, so assume
  172. # this is older.
  173. set(PYTHON_VERSION_STRING "1.4")
  174. set(PYTHON_VERSION_MAJOR "1")
  175. set(PYTHON_VERSION_MAJOR "4")
  176. set(PYTHON_VERSION_MAJOR "0")
  177. endif()
  178. endif()
  179. unset(_PYTHON_VERSION_RESULT)
  180. unset(_VERSION)
  181. endif(PYTHON_EXECUTABLE)
  182. # If we're running v3.x look for a 2to3 utility
  183. if (PYTHON_VERSION_MAJOR GREATER 2)
  184. get_filename_component(PYTHON_EXE_DIR ${PYTHON_EXECUTABLE} PATH)
  185. find_program(PYTHON_2TO3_EXECUTABLE
  186. NAMES 2to3
  187. HINTS ${PYTHON_EXE_DIR}
  188. )
  189. if ("PYTHON_2TO3_EXECUTABLE-NOTFOUND" STREQUAL PYTHON_2TO3_EXECUTABLE)
  190. message(FATAL_ERROR "Unable to find 2to3 python utility, specify python 2.7 or specify 2to3 utility")
  191. endif ()
  192. endif (PYTHON_VERSION_MAJOR GREATER 2)
  193. #check for json or simplejson
  194. execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import json"
  195. RESULT_VARIABLE CHECK_PYTHON_JSON_FAILED
  196. )
  197. if (CHECK_PYTHON_JSON_FAILED)
  198. execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import simplejson"
  199. RESULT_VARIABLE CHECK_PYTHON_SIMPLEJSON_FAILED
  200. )
  201. if (CHECK_PYTHON_SIMPLEJSON_FAILED)
  202. message(FATAL_ERROR "REGENERATE_AMQP_FRAMING requires a python with json or simplejson modules")
  203. endif (CHECK_PYTHON_SIMPLEJSON_FAILED)
  204. endif (CHECK_PYTHON_JSON_FAILED)
  205. find_path(AMQP_CODEGEN_DIR
  206. amqp_codegen.py
  207. PATHS ${CMAKE_CURRENT_SOURCE_DIR}/codegen
  208. ${CMAKE_CURRENT_SOURCE_DIR}/rabbitmq-codegen
  209. ${CMAKE_CURRENT_SOURCE_DIR}/../rabbitmq-codegen
  210. DOC "Path to directory containing amqp_codegen.py (rabbitmq-codegen)"
  211. NO_DEFAULT_PATH
  212. )
  213. if (AMQP_CODEGEN_DIR STREQUAL "AMQP_CODEGEN_DIR-NOTFOUND")
  214. message(SEND_ERROR "REGENERATE_AMQP_FRAMING requires the amqp_codegen.py script. If this is a git clone you can:\n\ngit submodule init\ngit submodule update\n\n Or set AMQP_CODEGEN_DIR to directory containing amqp_codegen.py")
  215. else ()
  216. message(STATUS "Found amqp_codegen.py in ${AMQP_CODEGEN_DIR}")
  217. endif()
  218. endif (REGENERATE_AMQP_FRAMING)
  219. find_package(POPT)
  220. find_package(XmlTo)
  221. find_package(Doxygen)
  222. if (POPT_FOUND AND XmlTo_FOUND)
  223. set(DO_DOCS ON)
  224. endif()
  225. option(BUILD_SHARED_LIBS "Build rabbitmq-c as a shared library" ON)
  226. option(BUILD_STATIC_LIBS "Build rabbitmq-c as a static library" ON)
  227. option(BUILD_EXAMPLES "Build Examples" ON)
  228. option(BUILD_TOOLS "Build Tools (requires POPT Library)" ${POPT_FOUND})
  229. option(BUILD_TOOLS_DOCS "Build man pages for Tools (requires xmlto)" ${DO_DOCS})
  230. option(BUILD_TESTS "Build tests (run tests with make test)" ON)
  231. option(BUILD_API_DOCS "Build Doxygen API docs" ${DOXYGEN_FOUND})
  232. if (NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
  233. message(FATAL_ERROR "One or both of BUILD_SHARED_LIBS or BUILD_STATIC_LIBS must be set to ON to build")
  234. endif()
  235. add_subdirectory(librabbitmq)
  236. if (BUILD_EXAMPLES)
  237. add_subdirectory(examples)
  238. endif ()
  239. if (BUILD_TOOLS)
  240. if (POPT_FOUND)
  241. add_subdirectory(tools)
  242. else ()
  243. message(WARNING "POpt library was not found. Tools will not be built")
  244. endif ()
  245. endif ()
  246. if (BUILD_TESTS)
  247. if (NOT BUILD_STATIC_LIBS)
  248. message(FATAL_ERROR
  249. "Tests can only be built against static libraries "
  250. "(set BUILD_STATIC_LIBS=ON)")
  251. endif ()
  252. enable_testing()
  253. add_subdirectory(tests)
  254. endif (BUILD_TESTS)
  255. if (BUILD_API_DOCS)
  256. if (NOT DOXYGEN_FOUND)
  257. message(FATAL_ERROR "Doxygen is required to build the API documentation")
  258. endif ()
  259. configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile @ONLY)
  260. add_custom_target(docs
  261. COMMAND ${DOXYGEN_EXECUTABLE}
  262. VERBATIM
  263. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs
  264. DEPENDS rabbitmq
  265. COMMENT "Generating API documentation"
  266. SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in
  267. )
  268. endif ()
  269. set(libs_private ${SOCKET_LIBRARIES} ${LIBRT})
  270. if (ENABLE_SSL_SUPPORT)
  271. set(requires_private "openssl")
  272. set(libs_private ${libs_private} ${CMAKE_THREAD_LIBS_INIT})
  273. endif()
  274. set(prefix ${CMAKE_INSTALL_PREFIX})
  275. set(exec_prefix "\${prefix}")
  276. set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
  277. set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
  278. configure_file(cmake/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq/config.h)
  279. configure_file(librabbitmq.pc.in ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq.pc @ONLY)
  280. install(FILES
  281. ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq.pc
  282. DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
  283. )
  284. if (BUILD_SHARED_LIBS)
  285. message(STATUS "Building rabbitmq as a shared library - yes")
  286. else ()
  287. message(STATUS "Building rabbitmq as a shared library - no")
  288. endif ()
  289. if (BUILD_STATIC_LIBS)
  290. message(STATUS "Building rabbitmq as a static library - yes")
  291. else ()
  292. message(STATUS "Building rabbitmq as a static library - no")
  293. endif ()