FindRuby.cmake 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file LICENSE.rst or https://cmake.org/licensing for details.
  3. #[=======================================================================[.rst:
  4. FindRuby
  5. --------
  6. Finds Ruby installation and the locations of its include files and libraries:
  7. .. code-block:: cmake
  8. find_package(Ruby [<version>] [COMPONENTS <components>...] [...])
  9. Ruby is a general-purpose programming language. This module supports Ruby
  10. 2.0 through 4.0. Virtual environments, such as RVM or RBENV, are also
  11. supported.
  12. Components
  13. ^^^^^^^^^^
  14. .. versionadded:: 4.3
  15. This module supports the following components:
  16. ``Interpreter``
  17. The Ruby interpreter executable.
  18. ``Development``
  19. Headers and libraries needed to build Ruby extensions or embed Ruby.
  20. If no components are specified, both ``Interpreter`` and ``Development``
  21. are searched for.
  22. Imported Targets
  23. ^^^^^^^^^^^^^^^^
  24. .. versionadded:: 4.3
  25. This module defines the following :prop_tgt:`IMPORTED` targets:
  26. ``Ruby::Interpreter``
  27. Ruby interpreter. Target defined if component ``Interpreter`` is found.
  28. ``Ruby::Ruby``
  29. Ruby library for embedding Ruby in C/C++ applications.
  30. Target defined if component ``Development`` is found.
  31. ``Ruby::Module``
  32. Ruby library for building Ruby extension modules.
  33. Target defined if component ``Development`` is found.
  34. Use this target when creating native extensions that will be
  35. loaded into Ruby via ``require``. On most platforms, extension
  36. modules do not link directly to libruby. Includes appropriate
  37. symbol visibility settings.
  38. Result Variables
  39. ^^^^^^^^^^^^^^^^
  40. This module defines the following variables:
  41. ``Ruby_FOUND``
  42. .. versionadded:: 3.3
  43. Boolean indicating whether (the requested version of) ruby was found.
  44. ``Ruby_VERSION``
  45. The version of ruby which was found, e.g. ``3.2.6``.
  46. ``Ruby_VERSION_MAJOR``
  47. Ruby major version.
  48. ``Ruby_VERSION_MINOR``
  49. Ruby minor version.
  50. ``Ruby_VERSION_PATCH``
  51. Ruby patch version.
  52. ``Ruby_EXECUTABLE``
  53. The full path to the ruby binary.
  54. ``Ruby_INCLUDE_DIRS``
  55. Include dirs to be used when using the ruby library.
  56. ``Ruby_LIBRARIES``
  57. .. versionadded:: 3.18
  58. Libraries needed to use ruby from C.
  59. .. versionchanged:: 3.18
  60. Previous versions of CMake used the ``RUBY_`` prefix for all variables.
  61. Hints
  62. ^^^^^
  63. This module accepts the following variables:
  64. ``Ruby_FIND_VIRTUALENV``
  65. .. versionadded:: 3.18
  66. This variable defines the handling of virtual environments.
  67. It can be left empty or be set to one of the following values:
  68. * ``FIRST``: Virtual Ruby environments are searched for first,
  69. then the system Ruby installation.
  70. This is the default.
  71. * ``ONLY``: Only virtual environments are searched
  72. * ``STANDARD``: Only the system Ruby installation is searched.
  73. Virtual environments may be provided by:
  74. ``rvm``
  75. Requires that the ``MY_RUBY_HOME`` environment is defined.
  76. ``rbenv``
  77. Requires that ``rbenv`` is installed in ``~/.rbenv/bin``
  78. or that the ``RBENV_ROOT`` environment variable is defined.
  79. Deprecated Variables
  80. ^^^^^^^^^^^^^^^^^^^^
  81. The following variables are provided for backward compatibility:
  82. .. deprecated:: 4.0
  83. The following variables are deprecated. See policy :policy:`CMP0185`.
  84. ``RUBY_FOUND``
  85. Same as ``Ruby_FOUND``.
  86. ``RUBY_VERSION``
  87. Same as ``Ruby_VERSION``.
  88. ``RUBY_EXECUTABLE``
  89. Same as ``Ruby_EXECUTABLE``.
  90. ``RUBY_INCLUDE_DIRS``
  91. Same as ``Ruby_INCLUDE_DIRS``.
  92. ``RUBY_INCLUDE_PATH``
  93. Same as ``Ruby_INCLUDE_DIRS``.
  94. ``RUBY_LIBRARY``
  95. Same as ``Ruby_LIBRARY``.
  96. Examples
  97. ^^^^^^^^
  98. Finding Ruby and specifying the minimum required version:
  99. .. code-block:: cmake
  100. find_package(Ruby 3.2.6 EXACT REQUIRED)
  101. # or
  102. find_package(Ruby 3.2)
  103. #]=======================================================================]
  104. cmake_policy(GET CMP0185 _Ruby_CMP0185)
  105. if(NOT _Ruby_CMP0185 STREQUAL "NEW")
  106. # Backwards compatibility
  107. # Define camel case versions of input variables
  108. foreach (UPPER
  109. RUBY_EXECUTABLE
  110. RUBY_LIBRARY
  111. RUBY_INCLUDE_DIR
  112. RUBY_CONFIG_INCLUDE_DIR)
  113. if (DEFINED ${UPPER})
  114. string(REPLACE "RUBY_" "Ruby_" Camel ${UPPER})
  115. if (NOT DEFINED ${Camel})
  116. set(${Camel} ${${UPPER}})
  117. endif ()
  118. endif ()
  119. endforeach ()
  120. endif()
  121. # Uncomment the following line to get debug output for this file
  122. # set(CMAKE_MESSAGE_LOG_LEVEL DEBUG)
  123. # Determine the list of possible names of the ruby executable depending
  124. # on which version of ruby is required
  125. set(_Ruby_POSSIBLE_EXECUTABLE_NAMES ruby)
  126. # If the user has not specified a Ruby version, create a list of Ruby versions
  127. # to check going from 1.8 to 4.0
  128. if (NOT Ruby_FIND_VERSION_EXACT)
  129. foreach (_ruby_version RANGE 40 18 -1)
  130. string(SUBSTRING "${_ruby_version}" 0 1 _ruby_major_version)
  131. string(SUBSTRING "${_ruby_version}" 1 1 _ruby_minor_version)
  132. # Append both rubyX.Y and rubyXY (eg: ruby3.4 ruby34)
  133. list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby${_ruby_major_version}.${_ruby_minor_version} ruby${_ruby_major_version}${_ruby_minor_version})
  134. endforeach ()
  135. endif ()
  136. # Virtual environment handling
  137. if (DEFINED Ruby_FIND_VIRTUALENV AND NOT Ruby_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY|STANDARD)$")
  138. message(AUTHOR_WARNING "FindRuby: ${Ruby_FIND_VIRTUALENV}: invalid value for 'Ruby_FIND_VIRTUALENV'. 'FIRST', 'ONLY' or 'STANDARD' expected. 'FIRST' will be used instead.")
  139. set(Ruby_FIND_VIRTUALENV "FIRST")
  140. elseif (NOT DEFINED Ruby_FIND_VIRTUALENV)
  141. # Default is to search for virtual environments first
  142. set(Ruby_FIND_VIRTUALENV "FIRST")
  143. endif ()
  144. # Validate the found Ruby interpreter to make sure that it is
  145. # callable and that its version matches the requested version
  146. function(_RUBY_VALIDATE_INTERPRETER result_var path)
  147. # Get the interpreter version
  148. execute_process(COMMAND "${path}" -e "puts RUBY_VERSION"
  149. RESULT_VARIABLE result
  150. OUTPUT_VARIABLE version
  151. ERROR_QUIET
  152. OUTPUT_STRIP_TRAILING_WHITESPACE)
  153. if (NOT result EQUAL 0)
  154. set(_Ruby_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${path}\"")
  155. set(${result_var} FALSE PARENT_SCOPE)
  156. return()
  157. endif ()
  158. if (Ruby_FIND_VERSION)
  159. if (Ruby_FIND_VERSION_EXACT AND NOT version VERSION_EQUAL Ruby_FIND_VERSION)
  160. message(DEBUG "Incorrect Ruby found. Requested: ${Ruby_FIND_VERSION}. Found: ${version}. Path: \"${path}\"")
  161. set(${result_var} FALSE PARENT_SCOPE)
  162. return()
  163. elseif (version VERSION_LESS Ruby_FIND_VERSION)
  164. message(DEBUG "Ruby version is too old. Minimum: ${Ruby_FIND_VERSION}. Found: ${version}. Path: \"${path}\"")
  165. set(${result_var} FALSE PARENT_SCOPE)
  166. return()
  167. endif ()
  168. endif ()
  169. # Found valid Ruby interpreter!
  170. set(${result_var} TRUE PARENT_SCOPE)
  171. endfunction()
  172. # Query Ruby RBConfig module for the specified variable (_RUBY_CONFIG_VAR)
  173. function(_RUBY_CONFIG_VAR RBVAR OUTVAR)
  174. execute_process(COMMAND "${Ruby_EXECUTABLE}" -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']"
  175. RESULT_VARIABLE _Ruby_SUCCESS
  176. OUTPUT_VARIABLE _Ruby_OUTPUT
  177. ERROR_QUIET)
  178. # Config was deprecated in Ruby 1.9 and then removed in Ruby 2 - so this is for ancient code
  179. if (_Ruby_SUCCESS OR _Ruby_OUTPUT STREQUAL "")
  180. execute_process(COMMAND "${Ruby_EXECUTABLE}" -r rbconfig -e "print Config::CONFIG['${RBVAR}']"
  181. RESULT_VARIABLE _Ruby_SUCCESS
  182. OUTPUT_VARIABLE _Ruby_OUTPUT
  183. ERROR_QUIET)
  184. endif ()
  185. set(${OUTVAR} "${_Ruby_OUTPUT}" PARENT_SCOPE)
  186. endfunction()
  187. # Check for RVM virtual environments
  188. function(_RUBY_CHECK_RVM)
  189. if (NOT DEFINED ENV{MY_RUBY_HOME})
  190. return()
  191. endif ()
  192. find_program(Ruby_EXECUTABLE
  193. NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}
  194. NAMES_PER_DIR
  195. PATHS ENV MY_RUBY_HOME
  196. PATH_SUFFIXES bin Scripts
  197. VALIDATOR _RUBY_VALIDATE_INTERPRETER
  198. NO_CMAKE_PATH
  199. NO_CMAKE_ENVIRONMENT_PATH
  200. NO_SYSTEM_ENVIRONMENT_PATH
  201. NO_CMAKE_SYSTEM_PATH)
  202. if (Ruby_EXECUTABLE)
  203. set(Ruby_ENV "RVM" CACHE INTERNAL "Ruby environment")
  204. endif ()
  205. endfunction()
  206. # Check for RBENV virtual environments
  207. function(_RUBY_CHECK_RBENV)
  208. find_program(Ruby_RBENV_EXECUTABLE
  209. NAMES rbenv
  210. NAMES_PER_DIR
  211. PATHS "$ENV{HOME}/.rbenv/bin/rbenv" ENV RBENV_ROOT
  212. PATH_SUFFIXES bin Scripts
  213. NO_CACHE
  214. NO_CMAKE_PATH
  215. NO_CMAKE_ENVIRONMENT_PATH
  216. NO_CMAKE_SYSTEM_PATH)
  217. execute_process(COMMAND "${Ruby_RBENV_EXECUTABLE}" "which" "ruby"
  218. RESULT_VARIABLE result
  219. OUTPUT_VARIABLE ruby_exe
  220. ERROR_QUIET
  221. OUTPUT_STRIP_TRAILING_WHITESPACE)
  222. if (NOT result EQUAL 0)
  223. return()
  224. endif ()
  225. cmake_path(GET ruby_exe PARENT_PATH ruby_dir)
  226. find_program(Ruby_EXECUTABLE
  227. NAMES ruby
  228. NAMES_PER_DIR
  229. PATHS ${ruby_dir}
  230. VALIDATOR _RUBY_VALIDATE_INTERPRETER
  231. NO_DEFAULT_PATH)
  232. if (Ruby_EXECUTABLE)
  233. set(Ruby_ENV "RBENV" CACHE INTERNAL "Ruby environment")
  234. endif ()
  235. endfunction()
  236. # Check Ruby installed via Homebrew on macOS
  237. function(_RUBY_CHECK_BREW)
  238. # Try to locate brew in common locations and in PATH
  239. find_program(_BREW_EXECUTABLE
  240. NAMES brew
  241. NAMES_PER_DIR
  242. PATHS
  243. /opt/homebrew/bin # Apple Silicon default
  244. /usr/local/bin # Intel default
  245. ENV PATH
  246. NO_CACHE
  247. )
  248. if (NOT _BREW_EXECUTABLE)
  249. return()
  250. endif ()
  251. message(DEBUG "Found brew at: ${_BREW_EXECUTABLE}")
  252. # Query Homebrew for the prefix of the 'ruby' formula.
  253. # If Ruby is not installed via Homebrew, this will fail.
  254. execute_process(
  255. COMMAND "${_BREW_EXECUTABLE}" --prefix ruby
  256. RESULT_VARIABLE _Ruby_BREW_RESULT
  257. OUTPUT_VARIABLE _Ruby_BREW_DIR
  258. ERROR_QUIET
  259. OUTPUT_STRIP_TRAILING_WHITESPACE
  260. )
  261. message(DEBUG "Ruby BREW is: ${_Ruby_BREW_DIR}")
  262. if (NOT _Ruby_BREW_RESULT EQUAL 0 OR _Ruby_BREW_DIR STREQUAL "")
  263. # No 'ruby' formula installed in Homebrew
  264. return()
  265. endif ()
  266. find_program(Ruby_EXECUTABLE
  267. NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}
  268. NAMES_PER_DIR
  269. PATHS "${_Ruby_BREW_DIR}/bin"
  270. VALIDATOR _RUBY_VALIDATE_INTERPRETER
  271. NO_DEFAULT_PATH
  272. )
  273. if (Ruby_EXECUTABLE)
  274. set(Ruby_ENV "BREW" CACHE INTERNAL "Ruby environment")
  275. endif ()
  276. endfunction()
  277. # Check system installed Ruby
  278. function(_RUBY_CHECK_SYSTEM)
  279. find_program(Ruby_EXECUTABLE
  280. NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}
  281. NAMES_PER_DIR
  282. VALIDATOR _RUBY_VALIDATE_INTERPRETER)
  283. if (Ruby_EXECUTABLE)
  284. set(Ruby_ENV "Standard" CACHE INTERNAL "Ruby environment")
  285. endif ()
  286. endfunction()
  287. # Find Ruby
  288. if (NOT Ruby_EXECUTABLE AND Ruby_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
  289. # First check for RVM virtual environments
  290. _RUBY_CHECK_RVM()
  291. # Second check for RBENV virtual environments
  292. if (NOT Ruby_EXECUTABLE)
  293. _RUBY_CHECK_RBENV()
  294. endif ()
  295. endif ()
  296. # Check for Homebrew Ruby (non-virtualenv, common on MacOS)
  297. if (NOT Ruby_EXECUTABLE AND NOT Ruby_FIND_VIRTUALENV STREQUAL "ONLY")
  298. _RUBY_CHECK_BREW()
  299. endif ()
  300. # Fallback to system installed Ruby
  301. if (NOT Ruby_EXECUTABLE AND NOT Ruby_FIND_VIRTUALENV STREQUAL "ONLY")
  302. _RUBY_CHECK_SYSTEM()
  303. endif ()
  304. # We found a new Ruby or a Ruby that is different than the last one we found.
  305. # So reload a number of variables by querying the Ruby interpreter.
  306. if (Ruby_EXECUTABLE AND NOT Ruby_EXECUTABLE STREQUAL "${_Ruby_EXECUTABLE_LAST_QUERIED}")
  307. # query the ruby version
  308. _RUBY_CONFIG_VAR("MAJOR" Ruby_VERSION_MAJOR)
  309. _RUBY_CONFIG_VAR("MINOR" Ruby_VERSION_MINOR)
  310. _RUBY_CONFIG_VAR("TEENY" Ruby_VERSION_PATCH)
  311. # Ruby extensions information
  312. _RUBY_CONFIG_VAR("arch" Ruby_ARCH) # x86_64-linux, arm64-darwin, x64-mswin64_140, etc
  313. # Extension directory where so/bundle files are stored
  314. _RUBY_CONFIG_VAR("archdir" Ruby_ARCH_DIR)
  315. # Extension suffix
  316. _RUBY_CONFIG_VAR("DLEXT" _Ruby_DLEXT) # so, bundle, *not* dll
  317. # Headers
  318. _RUBY_CONFIG_VAR("rubyhdrdir" Ruby_HDR_DIR)
  319. _RUBY_CONFIG_VAR("rubyarchhdrdir" Ruby_ARCHHDR_DIR)
  320. # Ruby library information
  321. _RUBY_CONFIG_VAR("libdir" _Ruby_POSSIBLE_LIB_DIR) # /usr/lib64
  322. _RUBY_CONFIG_VAR("RUBY_SO_NAME" _Ruby_SO_NAME) # ruby, x64-vcruntime140-ruby340, etc.
  323. # Ruby directory for ruby files (*.rb). TODO - not relevant should be removed
  324. _RUBY_CONFIG_VAR("rubylibdir" Ruby_RUBY_LIB_DIR)
  325. # site_ruby - TODO - not relevant and should be removed
  326. _RUBY_CONFIG_VAR("sitearchdir" Ruby_SITEARCH_DIR)
  327. _RUBY_CONFIG_VAR("sitelibdir" Ruby_SITELIB_DIR)
  328. # vendor_ruby - TODO - Not relevant and should be removed.
  329. execute_process(COMMAND "${Ruby_EXECUTABLE}" -r vendor-specific -e "print 'true'"
  330. OUTPUT_VARIABLE Ruby_HAS_VENDOR_RUBY ERROR_QUIET)
  331. if (Ruby_HAS_VENDOR_RUBY)
  332. _RUBY_CONFIG_VAR("vendorlibdir" Ruby_VENDORLIB_DIR)
  333. _RUBY_CONFIG_VAR("vendorarchdir" Ruby_VENDORARCH_DIR)
  334. endif ()
  335. # save the results in the cache so we don't have to run ruby the next time again
  336. set(_Ruby_EXECUTABLE_LAST_QUERIED "${Ruby_EXECUTABLE}" CACHE INTERNAL "The ruby executable last queried for version and path info")
  337. set(Ruby_VERSION_MAJOR ${Ruby_VERSION_MAJOR} CACHE STRING "The Ruby major version" FORCE)
  338. set(Ruby_VERSION_MINOR ${Ruby_VERSION_MINOR} CACHE STRING "The Ruby minor version" FORCE)
  339. set(Ruby_VERSION_PATCH ${Ruby_VERSION_PATCH} CACHE STRING "The Ruby patch version" FORCE)
  340. set(Ruby_ARCH_DIR ${Ruby_ARCH_DIR} CACHE INTERNAL "The Ruby arch dir" FORCE)
  341. set(Ruby_HDR_DIR ${Ruby_HDR_DIR} CACHE INTERNAL "The Ruby header dir (1.9+)" FORCE)
  342. set(Ruby_ARCHHDR_DIR ${Ruby_ARCHHDR_DIR} CACHE INTERNAL "The Ruby arch header dir (2.0+)" FORCE)
  343. set(_Ruby_POSSIBLE_LIB_DIR ${_Ruby_POSSIBLE_LIB_DIR} CACHE INTERNAL "The Ruby lib dir" FORCE)
  344. set(Ruby_RUBY_LIB_DIR ${Ruby_RUBY_LIB_DIR} CACHE INTERNAL "The Ruby ruby-lib dir" FORCE)
  345. set(_Ruby_SO_NAME ${_Ruby_SO_NAME} CACHE PATH "The Ruby shared library name" FORCE)
  346. set(_Ruby_DLEXT ${_Ruby_DLEXT} CACHE PATH "Ruby extensions extension" FORCE)
  347. set(_Ruby_SO_NAME ${_Ruby_SO_NAME} CACHE STRING "The Ruby shared library name" FORCE)
  348. set(_Ruby_DLEXT ${_Ruby_DLEXT} CACHE STRING "Ruby extensions extension" FORCE)
  349. set(Ruby_SITEARCH_DIR ${Ruby_SITEARCH_DIR} CACHE INTERNAL "The Ruby site arch dir" FORCE)
  350. set(Ruby_SITELIB_DIR ${Ruby_SITELIB_DIR} CACHE INTERNAL "The Ruby site lib dir" FORCE)
  351. set(Ruby_HAS_VENDOR_RUBY ${Ruby_HAS_VENDOR_RUBY} CACHE BOOL "Vendor Ruby is available" FORCE)
  352. set(Ruby_VENDORARCH_DIR ${Ruby_VENDORARCH_DIR} CACHE INTERNAL "The Ruby vendor arch dir" FORCE)
  353. set(Ruby_VENDORLIB_DIR ${Ruby_VENDORLIB_DIR} CACHE INTERNAL "The Ruby vendor lib dir" FORCE)
  354. mark_as_advanced(
  355. Ruby_ARCH_DIR
  356. Ruby_ARCH
  357. Ruby_HDR_DIR
  358. Ruby_ARCHHDR_DIR
  359. _Ruby_POSSIBLE_LIB_DIR
  360. Ruby_RUBY_LIB_DIR
  361. _Ruby_SO_NAME
  362. _Ruby_DLEXT
  363. Ruby_SITEARCH_DIR
  364. Ruby_SITELIB_DIR
  365. Ruby_HAS_VENDOR_RUBY
  366. Ruby_VENDORARCH_DIR
  367. Ruby_VENDORLIB_DIR
  368. Ruby_VERSION_MAJOR
  369. Ruby_VERSION_MINOR
  370. Ruby_VERSION_PATCH
  371. )
  372. endif ()
  373. if (Ruby_VERSION_MAJOR)
  374. set(Ruby_VERSION "${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}.${Ruby_VERSION_PATCH}")
  375. set(_Ruby_VERSION_NODOT "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}${Ruby_VERSION_PATCH}")
  376. set(_Ruby_VERSION_NODOT_ZERO_PATCH "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}0")
  377. set(_Ruby_VERSION_SHORT "${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}")
  378. set(_Ruby_VERSION_SHORT_NODOT "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}")
  379. endif ()
  380. # Save CMAKE_FIND_FRAMEWORK
  381. set(_Ruby_CMAKE_FIND_FRAMEWORK_ORIGINAL ${CMAKE_FIND_FRAMEWORK})
  382. # Avoid finding the ancient Ruby framework included in macOS.
  383. set(CMAKE_FIND_FRAMEWORK LAST)
  384. find_path(Ruby_INCLUDE_DIR
  385. NAMES ruby.h
  386. HINTS ${Ruby_HDR_DIR})
  387. find_path(Ruby_CONFIG_INCLUDE_DIR
  388. NAMES ruby/config.h config.h
  389. HINTS ${Ruby_ARCHHDR_DIR})
  390. set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIR} ${Ruby_CONFIG_INCLUDE_DIR})
  391. find_library(Ruby_LIBRARY
  392. NAMES "${_Ruby_SO_NAME}"
  393. HINTS ${_Ruby_POSSIBLE_LIB_DIR})
  394. # Restore CMAKE_FIND_FRAMEWORK
  395. set(CMAKE_FIND_FRAMEWORK ${_Ruby_CMAKE_FIND_FRAMEWORK_ORIGINAL})
  396. message(DEBUG "--------FindRuby.cmake debug------------")
  397. message(DEBUG "_Ruby_POSSIBLE_EXECUTABLE_NAMES: ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}")
  398. message(DEBUG "_Ruby_POSSIBLE_LIB_DIR: ${_Ruby_POSSIBLE_LIB_DIR}")
  399. message(DEBUG "_Ruby_SO_NAME: ${_Ruby_SO_NAME}")
  400. message(DEBUG "_Ruby_DLEXT: ${_Ruby_DLEXT}")
  401. message(DEBUG "Ruby_FIND_VIRTUALENV=${Ruby_FIND_VIRTUALENV}")
  402. message(DEBUG "Ruby_ENV: ${Ruby_ENV}")
  403. message(DEBUG "Found Ruby_VERSION: \"${Ruby_VERSION}\"")
  404. message(DEBUG "Ruby_EXECUTABLE: ${Ruby_EXECUTABLE}")
  405. message(DEBUG "Ruby_LIBRARY: ${Ruby_LIBRARY}")
  406. message(DEBUG "Ruby_INCLUDE_DIR: ${Ruby_INCLUDE_DIR}")
  407. message(DEBUG "Ruby_CONFIG_INCLUDE_DIR: ${Ruby_CONFIG_INCLUDE_DIR}")
  408. message(DEBUG "Ruby_HDR_DIR: ${Ruby_HDR_DIR}")
  409. message(DEBUG "Ruby_ARCH_DIR: ${Ruby_ARCH_DIR}")
  410. message(DEBUG "Ruby_ARCHHDR_DIR: ${Ruby_ARCHHDR_DIR}")
  411. message(DEBUG "--------------------")
  412. # Components
  413. #
  414. # If the caller does not request components, preserve legacy behavior
  415. if (NOT Ruby_FIND_COMPONENTS)
  416. set(Ruby_FIND_COMPONENTS Interpreter Development)
  417. endif ()
  418. set(_Ruby_WANT_INTERPRETER FALSE)
  419. set(_Ruby_WANT_DEVELOPMENT FALSE)
  420. set(_Ruby_REQUIRED_VARS "")
  421. foreach (component IN LISTS Ruby_FIND_COMPONENTS)
  422. if (component STREQUAL "Interpreter")
  423. set(_Ruby_WANT_INTERPRETER TRUE)
  424. list(APPEND _Ruby_REQUIRED_VARS Ruby_EXECUTABLE)
  425. elseif (component STREQUAL "Development")
  426. set(_Ruby_WANT_DEVELOPMENT TRUE)
  427. list(APPEND _Ruby_REQUIRED_VARS Ruby_INCLUDE_DIR Ruby_CONFIG_INCLUDE_DIR)
  428. if (WIN32)
  429. list(APPEND _Ruby_REQUIRED_VARS Ruby_LIBRARY)
  430. endif ()
  431. else ()
  432. message(FATAL_ERROR
  433. "FindRuby: Unsupported component '${component}'. Supported components are: Interpreter, Development")
  434. endif ()
  435. endforeach ()
  436. # Set component found flags
  437. if (Ruby_EXECUTABLE)
  438. set(Ruby_Interpreter_FOUND TRUE)
  439. else ()
  440. set(Ruby_Interpreter_FOUND FALSE)
  441. endif ()
  442. if (Ruby_INCLUDE_DIR AND Ruby_CONFIG_INCLUDE_DIR AND (Ruby_LIBRARY OR NOT WIN32))
  443. set(Ruby_Development_FOUND TRUE)
  444. else ()
  445. set(Ruby_Development_FOUND FALSE)
  446. endif ()
  447. include(FindPackageHandleStandardArgs)
  448. find_package_handle_standard_args(Ruby
  449. REQUIRED_VARS ${_Ruby_REQUIRED_VARS}
  450. VERSION_VAR Ruby_VERSION
  451. HANDLE_COMPONENTS)
  452. if (Ruby_FOUND)
  453. if (NOT TARGET Ruby::Interpreter)
  454. add_executable(Ruby::Interpreter IMPORTED GLOBAL)
  455. set_target_properties(Ruby::Interpreter PROPERTIES
  456. IMPORTED_LOCATION "${Ruby_EXECUTABLE}"
  457. )
  458. endif ()
  459. if (Ruby_Development_FOUND)
  460. set(Ruby_LIBRARIES ${Ruby_LIBRARY})
  461. if (Ruby_LIBRARY AND NOT TARGET Ruby::Ruby)
  462. add_library(Ruby::Ruby UNKNOWN IMPORTED)
  463. set_target_properties(Ruby::Ruby PROPERTIES
  464. IMPORTED_LOCATION "${Ruby_LIBRARY}"
  465. INTERFACE_INCLUDE_DIRECTORIES "${Ruby_INCLUDE_DIRS}"
  466. # Custom property for extension suffix (with dot), e.g. ".so", ".bundle"
  467. INTERFACE_RUBY_EXTENSION_SUFFIX ".${_Ruby_DLEXT}"
  468. )
  469. endif ()
  470. # Ruby::Module - For building Ruby extension modules
  471. if (NOT TARGET Ruby::Module)
  472. if (WIN32)
  473. add_library(Ruby::Module UNKNOWN IMPORTED)
  474. set_target_properties(Ruby::Module PROPERTIES
  475. IMPORTED_LOCATION "${Ruby_LIBRARY}"
  476. )
  477. else ()
  478. add_library(Ruby::Module INTERFACE IMPORTED)
  479. endif ()
  480. set_target_properties(Ruby::Module PROPERTIES
  481. INTERFACE_INCLUDE_DIRECTORIES "${Ruby_INCLUDE_DIRS}"
  482. # Custom property for extension suffix (with dot), e.g. ".so", ".bundle"
  483. INTERFACE_RUBY_EXTENSION_SUFFIX ".${_Ruby_DLEXT}"
  484. INTERFACE_C_VISIBILITY_PRESET hidden
  485. INTERFACE_CXX_VISIBILITY_PRESET hidden
  486. INTERFACE_VISIBILITY_INLINES_HIDDEN ON
  487. )
  488. # macOS: allow unresolved Ruby API symbols; resolved when Ruby loads the bundle.
  489. if (APPLE)
  490. target_link_options(Ruby::Module INTERFACE
  491. "LINKER:-undefined,dynamic_lookup"
  492. )
  493. endif ()
  494. # Linux (and other ELF platforms):
  495. # Normally undefined Ruby API symbols are allowed in shared objects and resolved at dlopen().
  496. # But if the toolchain/preset adds -Wl,--no-undefined, linking will fail.
  497. # This counteracts that.
  498. if (UNIX AND NOT APPLE)
  499. target_link_options(Ruby::Module INTERFACE
  500. "LINKER:--unresolved-symbols=ignore-all"
  501. )
  502. endif ()
  503. endif ()
  504. endif ()
  505. endif ()
  506. mark_as_advanced(
  507. Ruby_EXECUTABLE
  508. Ruby_LIBRARY
  509. Ruby_INCLUDE_DIR
  510. Ruby_CONFIG_INCLUDE_DIR
  511. )
  512. if(NOT _Ruby_CMP0185 STREQUAL "NEW")
  513. # Set some variables for compatibility with previous version of this file (no need to provide a CamelCase version of that...)
  514. set(RUBY_POSSIBLE_LIB_PATH ${_Ruby_POSSIBLE_LIB_DIR})
  515. set(RUBY_RUBY_LIB_PATH ${Ruby_RUBY_LIB_DIR})
  516. set(RUBY_INCLUDE_PATH ${Ruby_INCLUDE_DIRS})
  517. # Backwards compatibility
  518. # Define upper case versions of output variables
  519. foreach (Camel
  520. Ruby_EXECUTABLE
  521. Ruby_INCLUDE_DIRS
  522. Ruby_LIBRARY
  523. Ruby_VERSION
  524. Ruby_VERSION_MAJOR
  525. Ruby_VERSION_MINOR
  526. Ruby_VERSION_PATCH
  527. Ruby_ARCH_DIR
  528. Ruby_ARCH
  529. Ruby_HDR_DIR
  530. Ruby_ARCHHDR_DIR
  531. Ruby_RUBY_LIB_DIR
  532. Ruby_SITEARCH_DIR
  533. Ruby_SITELIB_DIR
  534. Ruby_HAS_VENDOR_RUBY
  535. Ruby_VENDORARCH_DIR
  536. Ruby_VENDORLIB_DIR)
  537. string(TOUPPER ${Camel} UPPER)
  538. set(${UPPER} ${${Camel}})
  539. endforeach ()
  540. endif()