FindICU.cmake 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  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. # FindICU
  5. # -------
  6. #
  7. # Find the International Components for Unicode (ICU) libraries and
  8. # programs.
  9. #
  10. # This module supports multiple components.
  11. # Components can include any of: ``data``, ``i18n``, ``io``, ``le``,
  12. # ``lx``, ``test``, ``tu`` and ``uc``.
  13. #
  14. # Note that on Windows ``data`` is named ``dt`` and ``i18n`` is named
  15. # ``in``; any of the names may be used, and the appropriate
  16. # platform-specific library name will be automatically selected.
  17. #
  18. # This module reports information about the ICU installation in
  19. # several variables. General variables::
  20. #
  21. # ICU_VERSION - ICU release version
  22. # ICU_FOUND - true if the main programs and libraries were found
  23. # ICU_LIBRARIES - component libraries to be linked
  24. # ICU_INCLUDE_DIRS - the directories containing the ICU headers
  25. #
  26. # Imported targets::
  27. #
  28. # ICU::<C>
  29. #
  30. # Where ``<C>`` is the name of an ICU component, for example
  31. # ``ICU::i18n``.
  32. #
  33. # ICU programs are reported in::
  34. #
  35. # ICU_GENCNVAL_EXECUTABLE - path to gencnval executable
  36. # ICU_ICUINFO_EXECUTABLE - path to icuinfo executable
  37. # ICU_GENBRK_EXECUTABLE - path to genbrk executable
  38. # ICU_ICU-CONFIG_EXECUTABLE - path to icu-config executable
  39. # ICU_GENRB_EXECUTABLE - path to genrb executable
  40. # ICU_GENDICT_EXECUTABLE - path to gendict executable
  41. # ICU_DERB_EXECUTABLE - path to derb executable
  42. # ICU_PKGDATA_EXECUTABLE - path to pkgdata executable
  43. # ICU_UCONV_EXECUTABLE - path to uconv executable
  44. # ICU_GENCFU_EXECUTABLE - path to gencfu executable
  45. # ICU_MAKECONV_EXECUTABLE - path to makeconv executable
  46. # ICU_GENNORM2_EXECUTABLE - path to gennorm2 executable
  47. # ICU_GENCCODE_EXECUTABLE - path to genccode executable
  48. # ICU_GENSPREP_EXECUTABLE - path to gensprep executable
  49. # ICU_ICUPKG_EXECUTABLE - path to icupkg executable
  50. # ICU_GENCMN_EXECUTABLE - path to gencmn executable
  51. #
  52. # ICU component libraries are reported in::
  53. #
  54. # ICU_<C>_FOUND - ON if component was found
  55. # ICU_<C>_LIBRARIES - libraries for component
  56. #
  57. # ICU datafiles are reported in::
  58. #
  59. # ICU_MAKEFILE_INC - Makefile.inc
  60. # ICU_PKGDATA_INC - pkgdata.inc
  61. #
  62. # Note that ``<C>`` is the uppercased name of the component.
  63. #
  64. # This module reads hints about search results from::
  65. #
  66. # ICU_ROOT - the root of the ICU installation
  67. #
  68. # The environment variable ``ICU_ROOT`` may also be used; the
  69. # ICU_ROOT variable takes precedence.
  70. #
  71. # The following cache variables may also be set::
  72. #
  73. # ICU_<P>_EXECUTABLE - the path to executable <P>
  74. # ICU_INCLUDE_DIR - the directory containing the ICU headers
  75. # ICU_<C>_LIBRARY - the library for component <C>
  76. #
  77. # .. note::
  78. #
  79. # In most cases none of the above variables will require setting,
  80. # unless multiple ICU versions are available and a specific version
  81. # is required.
  82. #
  83. # Other variables one may set to control this module are::
  84. #
  85. # ICU_DEBUG - Set to ON to enable debug output from FindICU.
  86. # Written by Roger Leigh <rleigh@codelibre.net>
  87. set(icu_programs
  88. gencnval
  89. icuinfo
  90. genbrk
  91. icu-config
  92. genrb
  93. gendict
  94. derb
  95. pkgdata
  96. uconv
  97. gencfu
  98. makeconv
  99. gennorm2
  100. genccode
  101. gensprep
  102. icupkg
  103. gencmn)
  104. set(icu_data
  105. Makefile.inc
  106. pkgdata.inc)
  107. # The ICU checks are contained in a function due to the large number
  108. # of temporary variables needed.
  109. function(_ICU_FIND)
  110. # Set up search paths, taking compiler into account. Search ICU_ROOT,
  111. # with ICU_ROOT in the environment as a fallback if unset.
  112. if(ICU_ROOT)
  113. list(APPEND icu_roots "${ICU_ROOT}")
  114. else()
  115. if(NOT "$ENV{ICU_ROOT}" STREQUAL "")
  116. file(TO_CMAKE_PATH "$ENV{ICU_ROOT}" NATIVE_PATH)
  117. list(APPEND icu_roots "${NATIVE_PATH}")
  118. set(ICU_ROOT "${NATIVE_PATH}"
  119. CACHE PATH "Location of the ICU installation" FORCE)
  120. endif()
  121. endif()
  122. # Find include directory
  123. list(APPEND icu_include_suffixes "include")
  124. find_path(ICU_INCLUDE_DIR
  125. NAMES "unicode/utypes.h"
  126. HINTS ${icu_roots}
  127. PATH_SUFFIXES ${icu_include_suffixes}
  128. DOC "ICU include directory")
  129. set(ICU_INCLUDE_DIR "${ICU_INCLUDE_DIR}" PARENT_SCOPE)
  130. # Get version
  131. if(ICU_INCLUDE_DIR AND EXISTS "${ICU_INCLUDE_DIR}/unicode/uvernum.h")
  132. file(STRINGS "${ICU_INCLUDE_DIR}/unicode/uvernum.h" icu_header_str
  133. REGEX "^#define[\t ]+U_ICU_VERSION[\t ]+\".*\".*")
  134. string(REGEX REPLACE "^#define[\t ]+U_ICU_VERSION[\t ]+\"([^ \\n]*)\".*"
  135. "\\1" icu_version_string "${icu_header_str}")
  136. set(ICU_VERSION "${icu_version_string}")
  137. set(ICU_VERSION "${icu_version_string}" PARENT_SCOPE)
  138. unset(icu_header_str)
  139. unset(icu_version_string)
  140. endif()
  141. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  142. # 64-bit binary directory
  143. set(_bin64 "bin64")
  144. # 64-bit library directory
  145. set(_lib64 "lib64")
  146. endif()
  147. # Find all ICU programs
  148. list(APPEND icu_binary_suffixes "${_bin64}" "bin" "sbin")
  149. foreach(program ${icu_programs})
  150. string(TOUPPER "${program}" program_upcase)
  151. set(cache_var "ICU_${program_upcase}_EXECUTABLE")
  152. set(program_var "ICU_${program_upcase}_EXECUTABLE")
  153. find_program("${cache_var}" "${program}"
  154. HINTS ${icu_roots}
  155. PATH_SUFFIXES ${icu_binary_suffixes}
  156. DOC "ICU ${program} executable")
  157. mark_as_advanced(cache_var)
  158. set("${program_var}" "${${cache_var}}" PARENT_SCOPE)
  159. endforeach()
  160. # Find all ICU libraries
  161. list(APPEND icu_library_suffixes "${_lib64}" "lib")
  162. set(ICU_REQUIRED_LIBS_FOUND ON)
  163. set(static_prefix )
  164. # static icu libraries compiled with MSVC have the prefix 's'
  165. if(MSVC)
  166. set(static_prefix "s")
  167. endif()
  168. foreach(component ${ICU_FIND_COMPONENTS})
  169. string(TOUPPER "${component}" component_upcase)
  170. set(component_cache "ICU_${component_upcase}_LIBRARY")
  171. set(component_cache_release "${component_cache}_RELEASE")
  172. set(component_cache_debug "${component_cache}_DEBUG")
  173. set(component_found "${component_upcase}_FOUND")
  174. set(component_libnames "icu${component}")
  175. set(component_debug_libnames "icu${component}d")
  176. # Special case deliberate library naming mismatches between Unix
  177. # and Windows builds
  178. unset(component_libnames)
  179. unset(component_debug_libnames)
  180. list(APPEND component_libnames "icu${component}")
  181. list(APPEND component_debug_libnames "icu${component}d")
  182. if(component STREQUAL "data")
  183. list(APPEND component_libnames "icudt")
  184. # Note there is no debug variant at present
  185. list(APPEND component_debug_libnames "icudtd")
  186. endif()
  187. if(component STREQUAL "dt")
  188. list(APPEND component_libnames "icudata")
  189. # Note there is no debug variant at present
  190. list(APPEND component_debug_libnames "icudatad")
  191. endif()
  192. if(component STREQUAL "i18n")
  193. list(APPEND component_libnames "icuin")
  194. list(APPEND component_debug_libnames "icuind")
  195. endif()
  196. if(component STREQUAL "in")
  197. list(APPEND component_libnames "icui18n")
  198. list(APPEND component_debug_libnames "icui18nd")
  199. endif()
  200. if(static_prefix)
  201. unset(static_component_libnames)
  202. unset(static_component_debug_libnames)
  203. foreach(component_libname ${component_libnames})
  204. list(APPEND static_component_libnames
  205. ${static_prefix}${component_libname})
  206. endforeach()
  207. foreach(component_libname ${component_debug_libnames})
  208. list(APPEND static_component_debug_libnames
  209. ${static_prefix}${component_libname})
  210. endforeach()
  211. list(APPEND component_libnames ${static_component_libnames})
  212. list(APPEND component_debug_libnames ${static_component_debug_libnames})
  213. endif()
  214. find_library("${component_cache_release}" ${component_libnames}
  215. HINTS ${icu_roots}
  216. PATH_SUFFIXES ${icu_library_suffixes}
  217. DOC "ICU ${component} library (release)")
  218. find_library("${component_cache_debug}" ${component_debug_libnames}
  219. HINTS ${icu_roots}
  220. PATH_SUFFIXES ${icu_library_suffixes}
  221. DOC "ICU ${component} library (debug)")
  222. include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
  223. select_library_configurations(ICU_${component_upcase})
  224. mark_as_advanced("${component_cache_release}" "${component_cache_debug}")
  225. if(${component_cache})
  226. set("${component_found}" ON)
  227. list(APPEND ICU_LIBRARY "${${component_cache}}")
  228. endif()
  229. mark_as_advanced("${component_found}")
  230. set("${component_cache}" "${${component_cache}}" PARENT_SCOPE)
  231. set("${component_found}" "${${component_found}}" PARENT_SCOPE)
  232. if(${component_found})
  233. if (ICU_FIND_REQUIRED_${component})
  234. list(APPEND ICU_LIBS_FOUND "${component} (required)")
  235. else()
  236. list(APPEND ICU_LIBS_FOUND "${component} (optional)")
  237. endif()
  238. else()
  239. if (ICU_FIND_REQUIRED_${component})
  240. set(ICU_REQUIRED_LIBS_FOUND OFF)
  241. list(APPEND ICU_LIBS_NOTFOUND "${component} (required)")
  242. else()
  243. list(APPEND ICU_LIBS_NOTFOUND "${component} (optional)")
  244. endif()
  245. endif()
  246. endforeach()
  247. set(_ICU_REQUIRED_LIBS_FOUND "${ICU_REQUIRED_LIBS_FOUND}" PARENT_SCOPE)
  248. set(ICU_LIBRARY "${ICU_LIBRARY}" PARENT_SCOPE)
  249. # Find all ICU data files
  250. if(CMAKE_LIBRARY_ARCHITECTURE)
  251. list(APPEND icu_data_suffixes
  252. "${_lib64}/${CMAKE_LIBRARY_ARCHITECTURE}/icu/${ICU_VERSION}"
  253. "lib/${CMAKE_LIBRARY_ARCHITECTURE}/icu/${ICU_VERSION}"
  254. "${_lib64}/${CMAKE_LIBRARY_ARCHITECTURE}/icu"
  255. "lib/${CMAKE_LIBRARY_ARCHITECTURE}/icu")
  256. endif()
  257. list(APPEND icu_data_suffixes
  258. "${_lib64}/icu/${ICU_VERSION}"
  259. "lib/icu/${ICU_VERSION}"
  260. "${_lib64}/icu"
  261. "lib/icu")
  262. foreach(data ${icu_data})
  263. string(TOUPPER "${data}" data_upcase)
  264. string(REPLACE "." "_" data_upcase "${data_upcase}")
  265. set(cache_var "ICU_${data_upcase}")
  266. set(data_var "ICU_${data_upcase}")
  267. find_file("${cache_var}" "${data}"
  268. HINTS ${icu_roots}
  269. PATH_SUFFIXES ${icu_data_suffixes}
  270. DOC "ICU ${data} data file")
  271. mark_as_advanced(cache_var)
  272. set("${data_var}" "${${cache_var}}" PARENT_SCOPE)
  273. endforeach()
  274. if(NOT ICU_FIND_QUIETLY)
  275. if(ICU_LIBS_FOUND)
  276. message(STATUS "Found the following ICU libraries:")
  277. foreach(found ${ICU_LIBS_FOUND})
  278. message(STATUS " ${found}")
  279. endforeach()
  280. endif()
  281. if(ICU_LIBS_NOTFOUND)
  282. message(STATUS "The following ICU libraries were not found:")
  283. foreach(notfound ${ICU_LIBS_NOTFOUND})
  284. message(STATUS " ${notfound}")
  285. endforeach()
  286. endif()
  287. endif()
  288. if(ICU_DEBUG)
  289. message(STATUS "--------FindICU.cmake search debug--------")
  290. message(STATUS "ICU binary path search order: ${icu_roots}")
  291. message(STATUS "ICU include path search order: ${icu_roots}")
  292. message(STATUS "ICU library path search order: ${icu_roots}")
  293. message(STATUS "----------------")
  294. endif()
  295. endfunction()
  296. _ICU_FIND()
  297. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  298. FIND_PACKAGE_HANDLE_STANDARD_ARGS(ICU
  299. FOUND_VAR ICU_FOUND
  300. REQUIRED_VARS ICU_INCLUDE_DIR
  301. ICU_LIBRARY
  302. _ICU_REQUIRED_LIBS_FOUND
  303. VERSION_VAR ICU_VERSION
  304. FAIL_MESSAGE "Failed to find all ICU components")
  305. unset(_ICU_REQUIRED_LIBS_FOUND)
  306. if(ICU_FOUND)
  307. set(ICU_INCLUDE_DIRS "${ICU_INCLUDE_DIR}")
  308. set(ICU_LIBRARIES "${ICU_LIBRARY}")
  309. foreach(_ICU_component ${ICU_FIND_COMPONENTS})
  310. string(TOUPPER "${_ICU_component}" _ICU_component_upcase)
  311. set(_ICU_component_cache "ICU_${_ICU_component_upcase}_LIBRARY")
  312. set(_ICU_component_cache_release "ICU_${_ICU_component_upcase}_LIBRARY_RELEASE")
  313. set(_ICU_component_cache_debug "ICU_${_ICU_component_upcase}_LIBRARY_DEBUG")
  314. set(_ICU_component_lib "ICU_${_ICU_component_upcase}_LIBRARIES")
  315. set(_ICU_component_found "${_ICU_component_upcase}_FOUND")
  316. set(_ICU_imported_target "ICU::${_ICU_component}")
  317. if(${_ICU_component_found})
  318. set("${_ICU_component_lib}" "${${_ICU_component_cache}}")
  319. if(NOT TARGET ${_ICU_imported_target})
  320. add_library(${_ICU_imported_target} UNKNOWN IMPORTED)
  321. if(ICU_INCLUDE_DIR)
  322. set_target_properties(${_ICU_imported_target} PROPERTIES
  323. INTERFACE_INCLUDE_DIRECTORIES "${ICU_INCLUDE_DIR}")
  324. endif()
  325. if(EXISTS "${${_ICU_component_cache}}")
  326. set_target_properties(${_ICU_imported_target} PROPERTIES
  327. IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
  328. IMPORTED_LOCATION "${${_ICU_component_cache}}")
  329. endif()
  330. if(EXISTS "${${_ICU_component_cache_release}}")
  331. set_property(TARGET ${_ICU_imported_target} APPEND PROPERTY
  332. IMPORTED_CONFIGURATIONS RELEASE)
  333. set_target_properties(${_ICU_imported_target} PROPERTIES
  334. IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
  335. IMPORTED_LOCATION_RELEASE "${${_ICU_component_cache_release}}")
  336. endif()
  337. if(EXISTS "${${_ICU_component_cache_debug}}")
  338. set_property(TARGET ${_ICU_imported_target} APPEND PROPERTY
  339. IMPORTED_CONFIGURATIONS DEBUG)
  340. set_target_properties(${_ICU_imported_target} PROPERTIES
  341. IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
  342. IMPORTED_LOCATION_DEBUG "${${_ICU_component_cache_debug}}")
  343. endif()
  344. endif()
  345. endif()
  346. unset(_ICU_component_upcase)
  347. unset(_ICU_component_cache)
  348. unset(_ICU_component_lib)
  349. unset(_ICU_component_found)
  350. unset(_ICU_imported_target)
  351. endforeach()
  352. endif()
  353. if(ICU_DEBUG)
  354. message(STATUS "--------FindICU.cmake results debug--------")
  355. message(STATUS "ICU found: ${ICU_FOUND}")
  356. message(STATUS "ICU_VERSION number: ${ICU_VERSION}")
  357. message(STATUS "ICU_ROOT directory: ${ICU_ROOT}")
  358. message(STATUS "ICU_INCLUDE_DIR directory: ${ICU_INCLUDE_DIR}")
  359. message(STATUS "ICU_LIBRARIES: ${ICU_LIBRARIES}")
  360. foreach(program IN LISTS icu_programs)
  361. string(TOUPPER "${program}" program_upcase)
  362. set(program_lib "ICU_${program_upcase}_EXECUTABLE")
  363. message(STATUS "${program} program: ${${program_lib}}")
  364. unset(program_upcase)
  365. unset(program_lib)
  366. endforeach()
  367. foreach(data IN LISTS icu_data)
  368. string(TOUPPER "${data}" data_upcase)
  369. string(REPLACE "." "_" data_upcase "${data_upcase}")
  370. set(data_lib "ICU_${data_upcase}")
  371. message(STATUS "${data} data: ${${data_lib}}")
  372. unset(data_upcase)
  373. unset(data_lib)
  374. endforeach()
  375. foreach(component IN LISTS ICU_FIND_COMPONENTS)
  376. string(TOUPPER "${component}" component_upcase)
  377. set(component_lib "ICU_${component_upcase}_LIBRARIES")
  378. set(component_found "${component_upcase}_FOUND")
  379. message(STATUS "${component} library found: ${${component_found}}")
  380. message(STATUS "${component} library: ${${component_lib}}")
  381. unset(component_upcase)
  382. unset(component_lib)
  383. unset(component_found)
  384. endforeach()
  385. message(STATUS "----------------")
  386. endif()
  387. unset(icu_programs)