FindRuby.cmake 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file Copyright.txt or https://cmake.org/licensing for details.
  3. #[=======================================================================[.rst:
  4. FindRuby
  5. --------
  6. Find Ruby
  7. This module finds if Ruby is installed and determines where the
  8. include files and libraries are. Ruby 1.8 through 2.7 are
  9. supported.
  10. The minimum required version of Ruby can be specified using the
  11. standard syntax, e.g.
  12. .. code-block:: cmake
  13. find_package(Ruby 2.5.1 EXACT REQUIRED)
  14. # OR
  15. find_package(Ruby 2.4)
  16. It also determines what the name of the library is.
  17. Result Variables
  18. ^^^^^^^^^^^^^^^^
  19. This module will set the following variables in your project:
  20. ``Ruby_FOUND``
  21. set to true if ruby was found successfully
  22. ``Ruby_EXECUTABLE``
  23. full path to the ruby binary
  24. ``Ruby_INCLUDE_DIRS``
  25. include dirs to be used when using the ruby library
  26. ``Ruby_LIBRARIES``
  27. libraries needed to use ruby from C.
  28. ``Ruby_VERSION``
  29. the version of ruby which was found, e.g. "1.8.7"
  30. ``Ruby_VERSION_MAJOR``
  31. Ruby major version.
  32. ``Ruby_VERSION_MINOR``
  33. Ruby minor version.
  34. ``Ruby_VERSION_PATCH``
  35. Ruby patch version.
  36. Also:
  37. ``Ruby_INCLUDE_PATH``
  38. same as Ruby_INCLUDE_DIRS, only provided for compatibility reasons, don't use it
  39. #]=======================================================================]
  40. # Backwards compatibility
  41. # Define camel case versions of input variables
  42. foreach(UPPER
  43. RUBY_EXECUTABLE
  44. RUBY_LIBRARY
  45. RUBY_INCLUDE_DIR
  46. RUBY_CONFIG_INCLUDE_DIR
  47. )
  48. if (DEFINED ${UPPER})
  49. string(REPLACE "RUBY_" "Ruby_" Camel ${UPPER})
  50. if (NOT DEFINED ${Camel})
  51. set(${Camel} ${${UPPER}})
  52. endif()
  53. endif()
  54. endforeach()
  55. # Ruby_ARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'`
  56. # Ruby_SITEARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'`
  57. # Ruby_SITEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'`
  58. # Ruby_LIBDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"libdir"@:>@)'`
  59. # Ruby_LIBRUBYARG=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"LIBRUBYARG_SHARED"@:>@)'`
  60. # uncomment the following line to get debug output for this file
  61. # set(_Ruby_DEBUG_OUTPUT TRUE)
  62. # Determine the list of possible names of the ruby executable depending
  63. # on which version of ruby is required
  64. set(_Ruby_POSSIBLE_EXECUTABLE_NAMES ruby)
  65. # If not specified, allow everything as far back as 1.8.0
  66. if(NOT DEFINED Ruby_FIND_VERSION_MAJOR)
  67. set(Ruby_FIND_VERSION "1.8.0")
  68. set(Ruby_FIND_VERSION_MAJOR 1)
  69. set(Ruby_FIND_VERSION_MINOR 8)
  70. set(Ruby_FIND_VERSION_PATCH 0)
  71. endif()
  72. if(_Ruby_DEBUG_OUTPUT)
  73. message("Ruby_FIND_VERSION=${Ruby_FIND_VERSION}")
  74. message("Ruby_FIND_VERSION_MAJOR=${Ruby_FIND_VERSION_MAJOR}")
  75. message("Ruby_FIND_VERSION_MINOR=${Ruby_FIND_VERSION_MINOR}")
  76. message("Ruby_FIND_VERSION_PATCH=${Ruby_FIND_VERSION_PATCH}")
  77. endif()
  78. set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR}")
  79. # Set name of possible executables, ignoring the minor
  80. # Eg:
  81. # 2.1.1 => from ruby27 to ruby21 included
  82. # 2.1 => from ruby27 to ruby21 included
  83. # 2 => from ruby26 to ruby20 included
  84. # empty => from ruby27 to ruby18 included
  85. if(NOT Ruby_FIND_VERSION_EXACT)
  86. foreach(_ruby_version RANGE 27 18 -1)
  87. string(SUBSTRING "${_ruby_version}" 0 1 _ruby_major_version)
  88. string(SUBSTRING "${_ruby_version}" 1 1 _ruby_minor_version)
  89. if(NOT "${_ruby_major_version}${_ruby_minor_version}" VERSION_LESS ${Ruby_FIND_VERSION_SHORT_NODOT})
  90. # Append both rubyX.Y and rubyXY (eg: ruby2.7 ruby27)
  91. list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby${_ruby_major_version}.${_ruby_minor_version} ruby${_ruby_major_version}${_ruby_minor_version})
  92. else()
  93. break()
  94. endif()
  95. endforeach()
  96. list(REMOVE_DUPLICATES _Ruby_POSSIBLE_EXECUTABLE_NAMES)
  97. endif()
  98. if(_Ruby_DEBUG_OUTPUT)
  99. message("_Ruby_POSSIBLE_EXECUTABLE_NAMES=${_Ruby_POSSIBLE_EXECUTABLE_NAMES}")
  100. endif()
  101. find_program (Ruby_EXECUTABLE
  102. NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}
  103. NAMES_PER_DIR
  104. )
  105. if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR)
  106. function(_RUBY_CONFIG_VAR RBVAR OUTVAR)
  107. execute_process(COMMAND ${Ruby_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']"
  108. RESULT_VARIABLE _Ruby_SUCCESS
  109. OUTPUT_VARIABLE _Ruby_OUTPUT
  110. ERROR_QUIET)
  111. if(_Ruby_SUCCESS OR _Ruby_OUTPUT STREQUAL "")
  112. execute_process(COMMAND ${Ruby_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']"
  113. RESULT_VARIABLE _Ruby_SUCCESS
  114. OUTPUT_VARIABLE _Ruby_OUTPUT
  115. ERROR_QUIET)
  116. endif()
  117. set(${OUTVAR} "${_Ruby_OUTPUT}" PARENT_SCOPE)
  118. endfunction()
  119. # query the ruby version
  120. _RUBY_CONFIG_VAR("MAJOR" Ruby_VERSION_MAJOR)
  121. _RUBY_CONFIG_VAR("MINOR" Ruby_VERSION_MINOR)
  122. _RUBY_CONFIG_VAR("TEENY" Ruby_VERSION_PATCH)
  123. # query the different directories
  124. _RUBY_CONFIG_VAR("archdir" Ruby_ARCH_DIR)
  125. _RUBY_CONFIG_VAR("arch" Ruby_ARCH)
  126. _RUBY_CONFIG_VAR("rubyhdrdir" Ruby_HDR_DIR)
  127. _RUBY_CONFIG_VAR("rubyarchhdrdir" Ruby_ARCHHDR_DIR)
  128. _RUBY_CONFIG_VAR("libdir" Ruby_POSSIBLE_LIB_DIR)
  129. _RUBY_CONFIG_VAR("rubylibdir" Ruby_RUBY_LIB_DIR)
  130. # site_ruby
  131. _RUBY_CONFIG_VAR("sitearchdir" Ruby_SITEARCH_DIR)
  132. _RUBY_CONFIG_VAR("sitelibdir" Ruby_SITELIB_DIR)
  133. # vendor_ruby available ?
  134. execute_process(COMMAND ${Ruby_EXECUTABLE} -r vendor-specific -e "print 'true'"
  135. OUTPUT_VARIABLE Ruby_HAS_VENDOR_RUBY ERROR_QUIET)
  136. if(Ruby_HAS_VENDOR_RUBY)
  137. _RUBY_CONFIG_VAR("vendorlibdir" Ruby_VENDORLIB_DIR)
  138. _RUBY_CONFIG_VAR("vendorarchdir" Ruby_VENDORARCH_DIR)
  139. endif()
  140. # save the results in the cache so we don't have to run ruby the next time again
  141. set(Ruby_VERSION_MAJOR ${Ruby_VERSION_MAJOR} CACHE PATH "The Ruby major version" FORCE)
  142. set(Ruby_VERSION_MINOR ${Ruby_VERSION_MINOR} CACHE PATH "The Ruby minor version" FORCE)
  143. set(Ruby_VERSION_PATCH ${Ruby_VERSION_PATCH} CACHE PATH "The Ruby patch version" FORCE)
  144. set(Ruby_ARCH_DIR ${Ruby_ARCH_DIR} CACHE PATH "The Ruby arch dir" FORCE)
  145. set(Ruby_HDR_DIR ${Ruby_HDR_DIR} CACHE PATH "The Ruby header dir (1.9+)" FORCE)
  146. set(Ruby_ARCHHDR_DIR ${Ruby_ARCHHDR_DIR} CACHE PATH "The Ruby arch header dir (2.0+)" FORCE)
  147. set(Ruby_POSSIBLE_LIB_DIR ${Ruby_POSSIBLE_LIB_DIR} CACHE PATH "The Ruby lib dir" FORCE)
  148. set(Ruby_RUBY_LIB_DIR ${Ruby_RUBY_LIB_DIR} CACHE PATH "The Ruby ruby-lib dir" FORCE)
  149. set(Ruby_SITEARCH_DIR ${Ruby_SITEARCH_DIR} CACHE PATH "The Ruby site arch dir" FORCE)
  150. set(Ruby_SITELIB_DIR ${Ruby_SITELIB_DIR} CACHE PATH "The Ruby site lib dir" FORCE)
  151. set(Ruby_HAS_VENDOR_RUBY ${Ruby_HAS_VENDOR_RUBY} CACHE BOOL "Vendor Ruby is available" FORCE)
  152. set(Ruby_VENDORARCH_DIR ${Ruby_VENDORARCH_DIR} CACHE PATH "The Ruby vendor arch dir" FORCE)
  153. set(Ruby_VENDORLIB_DIR ${Ruby_VENDORLIB_DIR} CACHE PATH "The Ruby vendor lib dir" FORCE)
  154. mark_as_advanced(
  155. Ruby_ARCH_DIR
  156. Ruby_ARCH
  157. Ruby_HDR_DIR
  158. Ruby_ARCHHDR_DIR
  159. Ruby_POSSIBLE_LIB_DIR
  160. Ruby_RUBY_LIB_DIR
  161. Ruby_SITEARCH_DIR
  162. Ruby_SITELIB_DIR
  163. Ruby_HAS_VENDOR_RUBY
  164. Ruby_VENDORARCH_DIR
  165. Ruby_VENDORLIB_DIR
  166. Ruby_VERSION_MAJOR
  167. Ruby_VERSION_MINOR
  168. Ruby_VERSION_PATCH
  169. )
  170. endif()
  171. # In case Ruby_EXECUTABLE could not be executed (e.g. cross compiling)
  172. # try to detect which version we found. This is not too good.
  173. if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR)
  174. # by default assume 1.8.0
  175. set(Ruby_VERSION_MAJOR 1)
  176. set(Ruby_VERSION_MINOR 8)
  177. set(Ruby_VERSION_PATCH 0)
  178. # check whether we found 1.9.x
  179. if(${Ruby_EXECUTABLE} MATCHES "ruby1\\.?9")
  180. set(Ruby_VERSION_MAJOR 1)
  181. set(Ruby_VERSION_MINOR 9)
  182. endif()
  183. # check whether we found 2.0.x
  184. if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?0")
  185. set(Ruby_VERSION_MAJOR 2)
  186. set(Ruby_VERSION_MINOR 0)
  187. endif()
  188. # check whether we found 2.1.x
  189. if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?1")
  190. set(Ruby_VERSION_MAJOR 2)
  191. set(Ruby_VERSION_MINOR 1)
  192. endif()
  193. # check whether we found 2.2.x
  194. if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?2")
  195. set(Ruby_VERSION_MAJOR 2)
  196. set(Ruby_VERSION_MINOR 2)
  197. endif()
  198. # check whether we found 2.3.x
  199. if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?3")
  200. set(Ruby_VERSION_MAJOR 2)
  201. set(Ruby_VERSION_MINOR 3)
  202. endif()
  203. # check whether we found 2.4.x
  204. if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?4")
  205. set(Ruby_VERSION_MAJOR 2)
  206. set(Ruby_VERSION_MINOR 4)
  207. endif()
  208. # check whether we found 2.5.x
  209. if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?5")
  210. set(Ruby_VERSION_MAJOR 2)
  211. set(Ruby_VERSION_MINOR 5)
  212. endif()
  213. # check whether we found 2.6.x
  214. if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?6")
  215. set(Ruby_VERSION_MAJOR 2)
  216. set(Ruby_VERSION_MINOR 6)
  217. endif()
  218. # check whether we found 2.7.x
  219. if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?7")
  220. set(Ruby_VERSION_MAJOR 2)
  221. set(Ruby_VERSION_MINOR 7)
  222. endif()
  223. endif()
  224. if(Ruby_VERSION_MAJOR)
  225. set(Ruby_VERSION "${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}.${Ruby_VERSION_PATCH}")
  226. set(_Ruby_VERSION_SHORT "${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}")
  227. set(_Ruby_VERSION_SHORT_NODOT "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}")
  228. set(_Ruby_NODOT_VERSION "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}${Ruby_VERSION_PATCH}")
  229. endif()
  230. find_path(Ruby_INCLUDE_DIR
  231. NAMES ruby.h
  232. HINTS
  233. ${Ruby_HDR_DIR}
  234. ${Ruby_ARCH_DIR}
  235. /usr/lib/ruby/${_Ruby_VERSION_SHORT}/i586-linux-gnu/
  236. )
  237. set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIR})
  238. # if ruby > 1.8 is required or if ruby > 1.8 was found, search for the config.h dir
  239. if( Ruby_FIND_VERSION VERSION_GREATER_EQUAL "1.9" OR Ruby_VERSION VERSION_GREATER_EQUAL "1.9" OR Ruby_HDR_DIR)
  240. find_path(Ruby_CONFIG_INCLUDE_DIR
  241. NAMES ruby/config.h config.h
  242. HINTS
  243. ${Ruby_HDR_DIR}/${Ruby_ARCH}
  244. ${Ruby_ARCH_DIR}
  245. ${Ruby_ARCHHDR_DIR}
  246. )
  247. set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIRS} ${Ruby_CONFIG_INCLUDE_DIR} )
  248. endif()
  249. # Determine the list of possible names for the ruby library
  250. set(_Ruby_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_Ruby_VERSION_SHORT} ruby${_Ruby_VERSION_SHORT_NODOT} ruby-${_Ruby_VERSION_SHORT} ruby-${Ruby_VERSION})
  251. if(WIN32)
  252. if(MSVC_TOOLSET_VERSION)
  253. set(_Ruby_MSVC_RUNTIME "${MSVC_TOOLSET_VERSION}")
  254. else()
  255. set(_Ruby_MSVC_RUNTIME "")
  256. endif()
  257. set(_Ruby_ARCH_PREFIX "")
  258. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  259. set(_Ruby_ARCH_PREFIX "x64-")
  260. endif()
  261. list(APPEND _Ruby_POSSIBLE_LIB_NAMES
  262. "${_Ruby_ARCH_PREFIX}msvcr${_Ruby_MSVC_RUNTIME}-ruby${_Ruby_NODOT_VERSION}"
  263. "${_Ruby_ARCH_PREFIX}msvcr${_Ruby_MSVC_RUNTIME}-ruby${_Ruby_NODOT_VERSION}-static"
  264. "${_Ruby_ARCH_PREFIX}msvcrt-ruby${_Ruby_NODOT_VERSION}"
  265. "${_Ruby_ARCH_PREFIX}msvcrt-ruby${_Ruby_NODOT_VERSION}-static" )
  266. endif()
  267. find_library(Ruby_LIBRARY NAMES ${_Ruby_POSSIBLE_LIB_NAMES} HINTS ${Ruby_POSSIBLE_LIB_DIR} )
  268. set(_Ruby_REQUIRED_VARS Ruby_EXECUTABLE Ruby_INCLUDE_DIR Ruby_LIBRARY)
  269. if(_Ruby_VERSION_SHORT_NODOT GREATER 18)
  270. list(APPEND _Ruby_REQUIRED_VARS Ruby_CONFIG_INCLUDE_DIR)
  271. endif()
  272. if(_Ruby_DEBUG_OUTPUT)
  273. message(STATUS "--------FindRuby.cmake debug------------")
  274. message(STATUS "_Ruby_POSSIBLE_EXECUTABLE_NAMES: ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}")
  275. message(STATUS "_Ruby_POSSIBLE_LIB_NAMES: ${_Ruby_POSSIBLE_LIB_NAMES}")
  276. message(STATUS "Ruby_ARCH_DIR: ${Ruby_ARCH_DIR}")
  277. message(STATUS "Ruby_HDR_DIR: ${Ruby_HDR_DIR}")
  278. message(STATUS "Ruby_POSSIBLE_LIB_DIR: ${Ruby_POSSIBLE_LIB_DIR}")
  279. message(STATUS "Found Ruby_VERSION: \"${Ruby_VERSION}\" , short: \"${_Ruby_VERSION_SHORT}\", nodot: \"${_Ruby_VERSION_SHORT_NODOT}\"")
  280. message(STATUS "_Ruby_REQUIRED_VARS: ${_Ruby_REQUIRED_VARS}")
  281. message(STATUS "Ruby_EXECUTABLE: ${Ruby_EXECUTABLE}")
  282. message(STATUS "Ruby_LIBRARY: ${Ruby_LIBRARY}")
  283. message(STATUS "Ruby_INCLUDE_DIR: ${Ruby_INCLUDE_DIR}")
  284. message(STATUS "Ruby_CONFIG_INCLUDE_DIR: ${Ruby_CONFIG_INCLUDE_DIR}")
  285. message(STATUS "--------------------")
  286. endif()
  287. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  288. FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ruby REQUIRED_VARS ${_Ruby_REQUIRED_VARS}
  289. VERSION_VAR Ruby_VERSION )
  290. if(Ruby_FOUND)
  291. set(Ruby_LIBRARIES ${Ruby_LIBRARY})
  292. endif()
  293. mark_as_advanced(
  294. Ruby_EXECUTABLE
  295. Ruby_LIBRARY
  296. Ruby_INCLUDE_DIR
  297. Ruby_CONFIG_INCLUDE_DIR
  298. )
  299. # Set some variables for compatibility with previous version of this file (no need to provide a CamelCase version of that...)
  300. set(RUBY_POSSIBLE_LIB_PATH ${Ruby_POSSIBLE_LIB_DIR})
  301. set(RUBY_RUBY_LIB_PATH ${Ruby_RUBY_LIB_DIR})
  302. set(RUBY_INCLUDE_PATH ${Ruby_INCLUDE_DIRS})
  303. # Backwards compatibility
  304. # Define upper case versions of output variables
  305. foreach(Camel
  306. Ruby_EXECUTABLE
  307. Ruby_INCLUDE_DIRS
  308. Ruby_LIBRARY
  309. Ruby_VERSION
  310. Ruby_VERSION_MAJOR
  311. Ruby_VERSION_MINOR
  312. Ruby_VERSION_PATCH
  313. Ruby_INCLUDE_PATH
  314. Ruby_ARCH_DIR
  315. Ruby_ARCH
  316. Ruby_HDR_DIR
  317. Ruby_ARCHHDR_DIR
  318. Ruby_POSSIBLE_LIB_DIR
  319. Ruby_RUBY_LIB_DIR
  320. Ruby_SITEARCH_DIR
  321. Ruby_SITELIB_DIR
  322. Ruby_HAS_VENDOR_RUBY
  323. Ruby_VENDORARCH_DIR
  324. )
  325. string(TOUPPER ${Camel} UPPER)
  326. set(${UPPER} ${${Camel}})
  327. endforeach()