فهرست منبع

Merge topic 'FindRuby-updates'

46064c8193 FindRuby: Add support for versions up to 2.7
675eaf3bd0 FindRuby: Update MSVC runtime library selection
b970e25d98 FindRuby: Remove extra whitespace
ecdace4d61 FindRuby: Include FPHSA closer to where it is used
f52f496138 FindRuby: Provide Ruby_LIBRARIES result variable
b00d736a0b FindRuby: Add dedicated tests

Acked-by: Kitware Robot <[email protected]>
Merge-request: !4481
Brad King 5 سال پیش
والد
کامیت
863b0fa2ac

+ 94 - 49
Modules/FindRuby.cmake

@@ -8,25 +8,42 @@ FindRuby
 Find Ruby
 
 This module finds if Ruby is installed and determines where the
-include files and libraries are.  Ruby 1.8, 1.9, 2.0 and 2.1 are
+include files and libraries are.  Ruby 1.8 through 2.7 are
 supported.
 
 The minimum required version of Ruby can be specified using the
-standard syntax, e.g.  find_package(Ruby 1.8)
+standard syntax, e.g.
 
-It also determines what the name of the library is.  This code sets
-the following variables:
+.. code-block:: cmake
 
+  find_package(Ruby 2.5.1 EXACT REQUIRED)
+  # OR
+  find_package(Ruby 2.4)
+
+It also determines what the name of the library is.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project:
+
+``Ruby_FOUND``
+  set to true if ruby was found successfully
 ``Ruby_EXECUTABLE``
   full path to the ruby binary
 ``Ruby_INCLUDE_DIRS``
   include dirs to be used when using the ruby library
-``Ruby_LIBRARY``
-  full path to the ruby library
+``Ruby_LIBRARIES``
+  libraries needed to use ruby from C.
 ``Ruby_VERSION``
   the version of ruby which was found, e.g. "1.8.7"
-``Ruby_FOUND``
-  set to true if ruby ws found successfully
+``Ruby_VERSION_MAJOR``
+  Ruby major version.
+``Ruby_VERSION_MINOR``
+  Ruby minor version.
+``Ruby_VERSION_PATCH``
+  Ruby patch version.
+
 
 Also:
 
@@ -63,37 +80,57 @@ endforeach()
 # on which version of ruby is required
 set(_Ruby_POSSIBLE_EXECUTABLE_NAMES ruby)
 
-# if 1.9 is required, don't look for ruby18 and ruby1.8, default to version 1.8
-if(DEFINED Ruby_FIND_VERSION_MAJOR AND DEFINED Ruby_FIND_VERSION_MINOR)
-  set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR}")
-  # we can't construct that if only major version is given
-  set(_Ruby_POSSIBLE_EXECUTABLE_NAMES
-    ruby${Ruby_FIND_VERSION_MAJOR}.${Ruby_FIND_VERSION_MINOR}
-    ruby${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR}
-    ${_Ruby_POSSIBLE_EXECUTABLE_NAMES})
-else()
-  set(Ruby_FIND_VERSION_SHORT_NODOT "18")
+# If not specified, allow everything as far back as 1.8.0
+if(NOT DEFINED Ruby_FIND_VERSION_MAJOR)
+  set(Ruby_FIND_VERSION "1.8.0")
+  set(Ruby_FIND_VERSION_MAJOR 1)
+  set(Ruby_FIND_VERSION_MINOR 8)
+  set(Ruby_FIND_VERSION_PATCH 0)
+endif()
+
+if(_Ruby_DEBUG_OUTPUT)
+  message("Ruby_FIND_VERSION=${Ruby_FIND_VERSION}")
+  message("Ruby_FIND_VERSION_MAJOR=${Ruby_FIND_VERSION_MAJOR}")
+  message("Ruby_FIND_VERSION_MINOR=${Ruby_FIND_VERSION_MINOR}")
+  message("Ruby_FIND_VERSION_PATCH=${Ruby_FIND_VERSION_PATCH}")
 endif()
 
+set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR}")
+
+# Set name of possible executables, ignoring the minor
+# Eg:
+# 2.1.1 => from ruby27 to ruby21 included
+# 2.1   => from ruby27 to ruby21 included
+# 2     => from ruby26 to ruby20 included
+# empty => from ruby27 to ruby18 included
 if(NOT Ruby_FIND_VERSION_EXACT)
-  list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby2.4 ruby24)
-  list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby2.3 ruby23)
-  list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby2.2 ruby22)
-  list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby2.1 ruby21)
-  list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby2.0 ruby20)
-  list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby1.9 ruby19)
-
-  # if we want a version below 1.9, also look for ruby 1.8
-  if("${Ruby_FIND_VERSION_SHORT_NODOT}" VERSION_LESS "19")
-    list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby1.8 ruby18)
-  endif()
+
+  foreach(_ruby_version RANGE 27 18 -1)
+    string(SUBSTRING "${_ruby_version}" 0 1 _ruby_major_version)
+    string(SUBSTRING "${_ruby_version}" 1 1 _ruby_minor_version)
+
+    if(NOT "${_ruby_major_version}${_ruby_minor_version}" VERSION_LESS ${Ruby_FIND_VERSION_SHORT_NODOT})
+      # Append both rubyX.Y and rubyXY (eg: ruby2.7 ruby27)
+      list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby${_ruby_major_version}.${_ruby_minor_version} ruby${_ruby_major_version}${_ruby_minor_version})
+    else()
+      break()
+    endif()
+
+  endforeach()
 
   list(REMOVE_DUPLICATES _Ruby_POSSIBLE_EXECUTABLE_NAMES)
 endif()
 
-find_program(Ruby_EXECUTABLE NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES})
+if(_Ruby_DEBUG_OUTPUT)
+  message("_Ruby_POSSIBLE_EXECUTABLE_NAMES=${_Ruby_POSSIBLE_EXECUTABLE_NAMES}")
+endif()
 
-if(Ruby_EXECUTABLE  AND NOT  Ruby_VERSION_MAJOR)
+find_program (Ruby_EXECUTABLE
+  NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}
+  NAMES_PER_DIR
+  )
+
+if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR)
   function(_RUBY_CONFIG_VAR RBVAR OUTVAR)
     execute_process(COMMAND ${Ruby_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']"
       RESULT_VARIABLE _Ruby_SUCCESS
@@ -205,6 +242,21 @@ if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR)
     set(Ruby_VERSION_MAJOR 2)
     set(Ruby_VERSION_MINOR 4)
   endif()
+  # check whether we found 2.5.x
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?5")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 5)
+  endif()
+  # check whether we found 2.6.x
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?6")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 6)
+  endif()
+  # check whether we found 2.7.x
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?7")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 7)
+  endif()
 endif()
 
 if(Ruby_VERSION_MAJOR)
@@ -222,10 +274,10 @@ find_path(Ruby_INCLUDE_DIR
     /usr/lib/ruby/${_Ruby_VERSION_SHORT}/i586-linux-gnu/
 )
 
-set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIR} )
+set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIR})
 
 # if ruby > 1.8 is required or if ruby > 1.8 was found, search for the config.h dir
-if( "${Ruby_FIND_VERSION_SHORT_NODOT}" GREATER 18  OR  "${_Ruby_VERSION_SHORT_NODOT}" GREATER 18  OR  Ruby_HDR_DIR)
+if( Ruby_FIND_VERSION VERSION_GREATER_EQUAL "1.9"  OR  Ruby_VERSION VERSION_GREATER_EQUAL "1.9"  OR  Ruby_HDR_DIR)
   find_path(Ruby_CONFIG_INCLUDE_DIR
     NAMES ruby/config.h  config.h
     HINTS
@@ -242,21 +294,10 @@ endif()
 set(_Ruby_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_Ruby_VERSION_SHORT} ruby${_Ruby_VERSION_SHORT_NODOT} ruby-${_Ruby_VERSION_SHORT} ruby-${Ruby_VERSION})
 
 if(WIN32)
-  set( _Ruby_MSVC_RUNTIME "" )
-  if( MSVC_VERSION EQUAL 1200 )
-    set( _Ruby_MSVC_RUNTIME "60" )
-  endif()
-  if( MSVC_VERSION EQUAL 1300 )
-    set( _Ruby_MSVC_RUNTIME "70" )
-  endif()
-  if( MSVC_VERSION EQUAL 1310 )
-    set( _Ruby_MSVC_RUNTIME "71" )
-  endif()
-  if( MSVC_VERSION EQUAL 1400 )
-    set( _Ruby_MSVC_RUNTIME "80" )
-  endif()
-  if( MSVC_VERSION EQUAL 1500 )
-    set( _Ruby_MSVC_RUNTIME "90" )
+  if(MSVC_TOOLSET_VERSION)
+    set(_Ruby_MSVC_RUNTIME "${MSVC_TOOLSET_VERSION}")
+  else()
+    set(_Ruby_MSVC_RUNTIME "")
   endif()
 
   set(_Ruby_ARCH_PREFIX "")
@@ -273,7 +314,6 @@ endif()
 
 find_library(Ruby_LIBRARY NAMES ${_Ruby_POSSIBLE_LIB_NAMES} HINTS ${Ruby_POSSIBLE_LIB_DIR} )
 
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 set(_Ruby_REQUIRED_VARS Ruby_EXECUTABLE Ruby_INCLUDE_DIR Ruby_LIBRARY)
 if(_Ruby_VERSION_SHORT_NODOT GREATER 18)
   list(APPEND _Ruby_REQUIRED_VARS Ruby_CONFIG_INCLUDE_DIR)
@@ -295,9 +335,14 @@ if(_Ruby_DEBUG_OUTPUT)
   message(STATUS "--------------------")
 endif()
 
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ruby  REQUIRED_VARS  ${_Ruby_REQUIRED_VARS}
                                         VERSION_VAR Ruby_VERSION )
 
+if(Ruby_FOUND)
+  set(Ruby_LIBRARIES ${Ruby_LIBRARY})
+endif()
+
 mark_as_advanced(
   Ruby_EXECUTABLE
   Ruby_LIBRARY

+ 4 - 0
Tests/CMakeLists.txt

@@ -1478,6 +1478,10 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
     add_subdirectory(UseSWIG)
   endif()
 
+  if(CMake_TEST_FindRuby)
+    add_subdirectory(FindRuby)
+  endif()
+
   add_subdirectory(FindThreads)
 
   # Matlab module

+ 44 - 0
Tests/FindRuby/CMakeLists.txt

@@ -0,0 +1,44 @@
+if(CMake_TEST_FindRuby)
+
+  # Looks for ruby >=1.9.9, which is true on any Ubuntu (that installs it) or macOS (> 10.9)
+  add_test(NAME FindRuby.Test COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindRuby/Test"
+    "${CMake_BINARY_DIR}/Tests/FindRuby/Test"
+    ${build_generator_args}
+    --build-project TestRuby
+    --build-options ${build_options}
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+
+  # Looks for ruby >= 50.1.0, which should logically fail
+  add_test(NAME FindRuby.Fail COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindRuby/Fail"
+    "${CMake_BINARY_DIR}/Tests/FindRuby/Fail"
+    ${build_generator_args}
+    --build-project TestRubyFail
+    --build-options ${build_options}
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  set_tests_properties(FindRuby.Fail PROPERTIES
+    PASS_REGULAR_EXPRESSION "Could NOT find Ruby: Found unsuitable version \".*\", but required is.*least \"[0-9]+\\.[0-9]+\\.[0-9]+\" \\(found .*\\)")
+
+  # Looks for 1.9.9 EXACTLY, which unlike the "FindRuby" test above will fail on every machine
+  # since this version doesn't exist (ruby goes from 1.9.3 to 2.0.0)
+  add_test(NAME FindRuby.FailExact COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindRuby/FailExact"
+    "${CMake_BINARY_DIR}/Tests/FindRuby/FailExact"
+    ${build_generator_args}
+    --build-project TestRubyFailExact
+    --build-options ${build_options}
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  set_tests_properties(FindRuby.FailExact PROPERTIES
+    PASS_REGULAR_EXPRESSION "Could NOT find Ruby: Found unsuitable version \".*\", but required is.*exact version \"[0-9]+\\.[0-9]+\\.[0-9]+\" \\(found .*\\)")
+
+endif()

+ 5 - 0
Tests/FindRuby/Fail/CMakeLists.txt

@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRubyFail LANGUAGES NONE)
+
+# Should always fail since there is NO ruby 50.1.0 yet.
+find_package(Ruby 50.1.0 REQUIRED)

+ 8 - 0
Tests/FindRuby/FailExact/CMakeLists.txt

@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRubyFailExact LANGUAGES NONE)
+
+# Should always fail since there is NO ruby 1.9.9 (goes from 1.9.3 to 2.0.0)
+find_package(Ruby 1.9.9 EXACT REQUIRED)
+if (NOT Ruby_FOUND)
+  message (FATAL_ERROR "Failed to find Ruby 1.9.9")
+endif()

+ 14 - 0
Tests/FindRuby/Test/CMakeLists.txt

@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRuby LANGUAGES C)
+include(CTest)
+
+find_package(Ruby 1.9.9 REQUIRED)
+if (NOT Ruby_FOUND)
+  message (FATAL_ERROR "Failed to find Ruby >=1.9.9")
+endif()
+
+add_executable(ruby_version ruby_version.c)
+target_include_directories(ruby_version PRIVATE ${Ruby_INCLUDE_DIRS})
+target_link_libraries(ruby_version PRIVATE ${Ruby_LIBRARIES})
+
+add_test(NAME ruby_version COMMAND ruby_version)

+ 7 - 0
Tests/FindRuby/Test/ruby_version.c

@@ -0,0 +1,7 @@
+#include "ruby.h"
+
+int main(void)
+{
+  ruby_show_version();
+  return 0;
+}