FindIntl.cmake 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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. FindIntl
  5. --------
  6. .. versionadded:: 3.2
  7. Find the Gettext libintl headers and libraries.
  8. This module reports information about the Gettext libintl
  9. installation in several variables.
  10. .. variable:: Intl_FOUND
  11. True if libintl is found.
  12. .. variable:: Intl_INCLUDE_DIRS
  13. The directory containing the libintl headers.
  14. .. variable:: Intl_LIBRARIES
  15. The intl libraries to be linked.
  16. .. variable:: Intl_VERSION
  17. .. versionadded:: 3.21
  18. The version of intl found (x.y.z)
  19. .. variable:: Intl_VERSION_MAJOR
  20. .. versionadded:: 3.21
  21. The major version of intl
  22. .. variable:: Intl_VERSION_MINOR
  23. .. versionadded:: 3.21
  24. The minor version of intl
  25. .. variable:: Intl_VERSION_PATCH
  26. .. versionadded:: 3.21
  27. The patch version of intl
  28. .. versionadded:: 3.20
  29. This module defines :prop_tgt:`IMPORTED` target ``Intl::Intl``.
  30. The following cache variables may also be set:
  31. .. variable:: Intl_INCLUDE_DIR
  32. The directory containing the libintl headers
  33. .. variable:: Intl_LIBRARY
  34. The libintl library (if any)
  35. .. variable:: Intl_IS_BUILT_IN
  36. .. versionadded:: 3.20
  37. whether ``intl`` is a part of the C library.
  38. .. note::
  39. On some platforms, such as Linux with GNU libc, the gettext
  40. functions are present in the C standard library and libintl
  41. is not required. ``Intl_LIBRARIES`` will be empty in this
  42. case.
  43. .. note::
  44. Some libintl implementations don't embed the version number in their header files.
  45. In this case the variables ``Intl_VERSION*`` will be empty.
  46. .. note::
  47. If you wish to use the Gettext tools (``msgmerge``,
  48. ``msgfmt``, etc.), use :module:`FindGettext`.
  49. #]=======================================================================]
  50. cmake_policy(PUSH)
  51. cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
  52. include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
  53. if(CMAKE_C_COMPILER_LOADED)
  54. include(${CMAKE_CURRENT_LIST_DIR}/CheckCSourceCompiles.cmake)
  55. elseif(CMAKE_CXX_COMPILER_LOADED)
  56. include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXSourceCompiles.cmake)
  57. else()
  58. # If neither C nor CXX are loaded, implicit intl makes no sense.
  59. set(Intl_IS_BUILT_IN FALSE)
  60. endif()
  61. # Check if Intl is built in to the C library.
  62. if(NOT DEFINED Intl_IS_BUILT_IN)
  63. if(NOT DEFINED Intl_INCLUDE_DIR AND NOT DEFINED Intl_LIBRARY)
  64. cmake_push_check_state(RESET)
  65. set(CMAKE_REQUIRED_QUIET TRUE)
  66. set(Intl_IMPLICIT_TEST_CODE [[
  67. #include <libintl.h>
  68. int main(void) {
  69. gettext("");
  70. dgettext("", "");
  71. dcgettext("", "", 0);
  72. return 0;
  73. }
  74. ]])
  75. if(CMAKE_C_COMPILER_LOADED)
  76. check_c_source_compiles("${Intl_IMPLICIT_TEST_CODE}" Intl_IS_BUILT_IN)
  77. else()
  78. check_cxx_source_compiles("${Intl_IMPLICIT_TEST_CODE}" Intl_IS_BUILT_IN)
  79. endif()
  80. cmake_pop_check_state()
  81. else()
  82. set(Intl_IS_BUILT_IN FALSE)
  83. endif()
  84. endif()
  85. set(_Intl_REQUIRED_VARS)
  86. if(Intl_IS_BUILT_IN)
  87. set(_Intl_REQUIRED_VARS _Intl_IS_BUILT_IN_MSG)
  88. set(_Intl_IS_BUILT_IN_MSG "built in to C library")
  89. else()
  90. set(_Intl_REQUIRED_VARS Intl_LIBRARY Intl_INCLUDE_DIR)
  91. find_path(Intl_INCLUDE_DIR
  92. NAMES "libintl.h"
  93. DOC "libintl include directory")
  94. mark_as_advanced(Intl_INCLUDE_DIR)
  95. find_library(Intl_LIBRARY
  96. NAMES "intl" "libintl"
  97. NAMES_PER_DIR
  98. DOC "libintl libraries (if not in the C library)")
  99. mark_as_advanced(Intl_LIBRARY)
  100. endif()
  101. # NOTE: glibc's libintl.h does not define LIBINTL_VERSION
  102. if(Intl_INCLUDE_DIR AND EXISTS "${Intl_INCLUDE_DIR}/libintl.h")
  103. file(STRINGS ${Intl_INCLUDE_DIR}/libintl.h Intl_VERSION_DEFINE REGEX "LIBINTL_VERSION (.*)")
  104. if(Intl_VERSION_DEFINE MATCHES "(0x[A-Fa-f0-9]+)")
  105. set(Intl_VERSION_NUMBER "${CMAKE_MATCH_1}")
  106. # encoding -> version number: (major<<16) + (minor<<8) + patch
  107. math(EXPR Intl_VERSION_MAJOR "${Intl_VERSION_NUMBER} >> 16" OUTPUT_FORMAT HEXADECIMAL)
  108. math(EXPR Intl_VERSION_MINOR "(${Intl_VERSION_NUMBER} - (${Intl_VERSION_MAJOR} << 16)) >> 8" OUTPUT_FORMAT HEXADECIMAL)
  109. math(EXPR Intl_VERSION_PATCH "${Intl_VERSION_NUMBER} - ((${Intl_VERSION_MAJOR} << 16) + (${Intl_VERSION_MINOR} << 8))" OUTPUT_FORMAT HEXADECIMAL)
  110. math(EXPR Intl_VERSION_MAJOR "${Intl_VERSION_MAJOR}" OUTPUT_FORMAT DECIMAL)
  111. math(EXPR Intl_VERSION_MINOR "${Intl_VERSION_MINOR}" OUTPUT_FORMAT DECIMAL)
  112. math(EXPR Intl_VERSION_PATCH "${Intl_VERSION_PATCH}" OUTPUT_FORMAT DECIMAL)
  113. set(Intl_VERSION "${Intl_VERSION_MAJOR}.${Intl_VERSION_MINOR}.${Intl_VERSION_PATCH}")
  114. endif()
  115. unset(Intl_VERSION_DEFINE)
  116. unset(Intl_VERSION_NUMBER)
  117. endif()
  118. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  119. FIND_PACKAGE_HANDLE_STANDARD_ARGS(Intl
  120. FOUND_VAR Intl_FOUND
  121. REQUIRED_VARS ${_Intl_REQUIRED_VARS}
  122. VERSION_VAR Intl_VERSION
  123. FAIL_MESSAGE "Failed to find Gettext libintl")
  124. unset(_Intl_REQUIRED_VARS)
  125. unset(_Intl_IS_BUILT_IN_MSG)
  126. if(Intl_FOUND)
  127. if(Intl_IS_BUILT_IN)
  128. set(Intl_INCLUDE_DIRS "")
  129. set(Intl_LIBRARIES "")
  130. else()
  131. set(Intl_INCLUDE_DIRS "${Intl_INCLUDE_DIR}")
  132. set(Intl_LIBRARIES "${Intl_LIBRARY}")
  133. endif()
  134. if(NOT TARGET Intl::Intl)
  135. add_library(Intl::Intl INTERFACE IMPORTED)
  136. set_target_properties(Intl::Intl PROPERTIES
  137. INTERFACE_INCLUDE_DIRECTORIES "${Intl_INCLUDE_DIRS}"
  138. INTERFACE_LINK_LIBRARIES "${Intl_LIBRARIES}")
  139. endif()
  140. endif()
  141. cmake_policy(POP)