# Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. #[=======================================================================[.rst: FindICU ------- .. versionadded:: 3.7 Find the International Components for Unicode (ICU) libraries and programs. This module supports multiple components. Components can include any of: ``data``, ``i18n``, ``io``, ``le``, ``lx``, ``test``, ``tu`` and ``uc``. Note that on Windows ``data`` is named ``dt`` and ``i18n`` is named ``in``; any of the names may be used, and the appropriate platform-specific library name will be automatically selected. .. versionadded:: 3.11 Added support for static libraries on Windows. This module reports information about the ICU installation in several variables. General variables:: ICU_VERSION - ICU release version ICU_FOUND - true if the main programs and libraries were found ICU_LIBRARIES - component libraries to be linked ICU_INCLUDE_DIRS - the directories containing the ICU headers Imported targets:: ICU:: Where ```` is the name of an ICU component, for example ``ICU::i18n``; ```` is lower-case. ICU programs are reported in:: ICU_GENCNVAL_EXECUTABLE - path to gencnval executable ICU_ICUINFO_EXECUTABLE - path to icuinfo executable ICU_GENBRK_EXECUTABLE - path to genbrk executable ICU_ICU-CONFIG_EXECUTABLE - path to icu-config executable ICU_GENRB_EXECUTABLE - path to genrb executable ICU_GENDICT_EXECUTABLE - path to gendict executable ICU_DERB_EXECUTABLE - path to derb executable ICU_PKGDATA_EXECUTABLE - path to pkgdata executable ICU_UCONV_EXECUTABLE - path to uconv executable ICU_GENCFU_EXECUTABLE - path to gencfu executable ICU_MAKECONV_EXECUTABLE - path to makeconv executable ICU_GENNORM2_EXECUTABLE - path to gennorm2 executable ICU_GENCCODE_EXECUTABLE - path to genccode executable ICU_GENSPREP_EXECUTABLE - path to gensprep executable ICU_ICUPKG_EXECUTABLE - path to icupkg executable ICU_GENCMN_EXECUTABLE - path to gencmn executable ICU component libraries are reported in:: ICU__FOUND - ON if component was found; ```` is upper-case. ICU__LIBRARIES - libraries for component; ```` is upper-case. ICU datafiles are reported in:: ICU_MAKEFILE_INC - Makefile.inc ICU_PKGDATA_INC - pkgdata.inc This module reads hints about search results from:: ICU_ROOT - the root of the ICU installation The environment variable ``ICU_ROOT`` may also be used; the ICU_ROOT variable takes precedence. The following cache variables may also be set:: ICU_

_EXECUTABLE - the path to executable

; ``

`` is upper-case. ICU_INCLUDE_DIR - the directory containing the ICU headers ICU__LIBRARY - the library for component ; ```` is upper-case. .. note:: In most cases none of the above variables will require setting, unless multiple ICU versions are available and a specific version is required. Other variables one may set to control this module are:: ICU_DEBUG - Set to ON to enable debug output from FindICU. #]=======================================================================] # Written by Roger Leigh set(icu_programs gencnval icuinfo genbrk icu-config genrb gendict derb pkgdata uconv gencfu makeconv gennorm2 genccode gensprep icupkg gencmn) set(icu_data Makefile.inc pkgdata.inc) # The ICU checks are contained in a function due to the large number # of temporary variables needed. function(_ICU_FIND) # Set up search paths, taking compiler into account. Search ICU_ROOT, # with ICU_ROOT in the environment as a fallback if unset. if(ICU_ROOT) list(APPEND icu_roots "${ICU_ROOT}") else() if(NOT "$ENV{ICU_ROOT}" STREQUAL "") file(TO_CMAKE_PATH "$ENV{ICU_ROOT}" NATIVE_PATH) list(APPEND icu_roots "${NATIVE_PATH}") set(ICU_ROOT "${NATIVE_PATH}" CACHE PATH "Location of the ICU installation" FORCE) endif() endif() # Find include directory list(APPEND icu_include_suffixes "include") find_path(ICU_INCLUDE_DIR NAMES "unicode/utypes.h" HINTS ${icu_roots} PATH_SUFFIXES ${icu_include_suffixes} DOC "ICU include directory") mark_as_advanced(ICU_INCLUDE_DIR) set(ICU_INCLUDE_DIR "${ICU_INCLUDE_DIR}" PARENT_SCOPE) # Get version if(ICU_INCLUDE_DIR AND EXISTS "${ICU_INCLUDE_DIR}/unicode/uvernum.h") file(STRINGS "${ICU_INCLUDE_DIR}/unicode/uvernum.h" icu_header_str REGEX "^#define[\t ]+U_ICU_VERSION[\t ]+\".*\".*") string(REGEX REPLACE "^#define[\t ]+U_ICU_VERSION[\t ]+\"([^ \\n]*)\".*" "\\1" icu_version_string "${icu_header_str}") set(ICU_VERSION "${icu_version_string}") set(ICU_VERSION "${icu_version_string}" PARENT_SCOPE) unset(icu_header_str) unset(icu_version_string) endif() if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit binary directory set(_bin64 "bin64") # 64-bit library directory set(_lib64 "lib64") endif() # Find all ICU programs list(APPEND icu_binary_suffixes "${_bin64}" "bin" "sbin") foreach(program ${icu_programs}) string(TOUPPER "${program}" program_upcase) set(cache_var "ICU_${program_upcase}_EXECUTABLE") set(program_var "ICU_${program_upcase}_EXECUTABLE") find_program("${cache_var}" NAMES "${program}" HINTS ${icu_roots} PATH_SUFFIXES ${icu_binary_suffixes} DOC "ICU ${program} executable" NO_PACKAGE_ROOT_PATH ) mark_as_advanced("${cache_var}") set("${program_var}" "${${cache_var}}" PARENT_SCOPE) endforeach() # Find all ICU libraries list(APPEND icu_library_suffixes "${_lib64}" "lib") set(ICU_REQUIRED_LIBS_FOUND ON) set(static_prefix ) # static icu libraries compiled with MSVC have the prefix 's' if(MSVC) set(static_prefix "s") endif() foreach(component ${ICU_FIND_COMPONENTS}) string(TOUPPER "${component}" component_upcase) set(component_cache "ICU_${component_upcase}_LIBRARY") set(component_cache_release "${component_cache}_RELEASE") set(component_cache_debug "${component_cache}_DEBUG") set(component_found "ICU_${component_upcase}_FOUND") set(component_found_compat "${component_upcase}_FOUND") set(component_libnames "icu${component}") set(component_debug_libnames "icu${component}d") # Special case deliberate library naming mismatches between Unix # and Windows builds unset(component_libnames) unset(component_debug_libnames) list(APPEND component_libnames "icu${component}") list(APPEND component_debug_libnames "icu${component}d") if(component STREQUAL "data") list(APPEND component_libnames "icudt") # Note there is no debug variant at present list(APPEND component_debug_libnames "icudtd") endif() if(component STREQUAL "dt") list(APPEND component_libnames "icudata") # Note there is no debug variant at present list(APPEND component_debug_libnames "icudatad") endif() if(component STREQUAL "i18n") list(APPEND component_libnames "icuin") list(APPEND component_debug_libnames "icuind") endif() if(component STREQUAL "in") list(APPEND component_libnames "icui18n") list(APPEND component_debug_libnames "icui18nd") endif() if(static_prefix) unset(static_component_libnames) unset(static_component_debug_libnames) foreach(component_libname ${component_libnames}) list(APPEND static_component_libnames ${static_prefix}${component_libname}) endforeach() foreach(component_libname ${component_debug_libnames}) list(APPEND static_component_debug_libnames ${static_prefix}${component_libname}) endforeach() list(APPEND component_libnames ${static_component_libnames}) list(APPEND component_debug_libnames ${static_component_debug_libnames}) endif() find_library("${component_cache_release}" NAMES ${component_libnames} HINTS ${icu_roots} PATH_SUFFIXES ${icu_library_suffixes} DOC "ICU ${component} library (release)" NO_PACKAGE_ROOT_PATH ) find_library("${component_cache_debug}" NAMES ${component_debug_libnames} HINTS ${icu_roots} PATH_SUFFIXES ${icu_library_suffixes} DOC "ICU ${component} library (debug)" NO_PACKAGE_ROOT_PATH ) include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) select_library_configurations(ICU_${component_upcase}) mark_as_advanced("${component_cache_release}" "${component_cache_debug}") if(${component_cache}) set("${component_found}" ON) set("${component_found_compat}" ON) list(APPEND ICU_LIBRARY "${${component_cache}}") if (ICU_FIND_REQUIRED_${component}) list(APPEND ICU_LIBS_FOUND "${component} (required): ${${component_cache}}") else() list(APPEND ICU_LIBS_FOUND "${component} (optional): ${${component_cache}}") endif() else() if (ICU_FIND_REQUIRED_${component}) set(ICU_REQUIRED_LIBS_FOUND OFF) list(APPEND ICU_LIBS_NOTFOUND "${component} (required)") else() list(APPEND ICU_LIBS_NOTFOUND "${component} (optional)") endif() endif() mark_as_advanced("${component_found}") mark_as_advanced("${component_found_compat}") set("${component_cache}" "${${component_cache}}" PARENT_SCOPE) set("${component_found}" "${${component_found}}" PARENT_SCOPE) set("${component_found_compat}" "${${component_found_compat}}" PARENT_SCOPE) endforeach() set(_ICU_REQUIRED_LIBS_FOUND "${ICU_REQUIRED_LIBS_FOUND}" PARENT_SCOPE) set(ICU_LIBRARY "${ICU_LIBRARY}" PARENT_SCOPE) # Find all ICU data files if(CMAKE_LIBRARY_ARCHITECTURE) list(APPEND icu_data_suffixes "${_lib64}/${CMAKE_LIBRARY_ARCHITECTURE}/icu/${ICU_VERSION}" "lib/${CMAKE_LIBRARY_ARCHITECTURE}/icu/${ICU_VERSION}" "${_lib64}/${CMAKE_LIBRARY_ARCHITECTURE}/icu" "lib/${CMAKE_LIBRARY_ARCHITECTURE}/icu") endif() list(APPEND icu_data_suffixes "${_lib64}/icu/${ICU_VERSION}" "lib/icu/${ICU_VERSION}" "${_lib64}/icu" "lib/icu") foreach(data ${icu_data}) string(TOUPPER "${data}" data_upcase) string(REPLACE "." "_" data_upcase "${data_upcase}") set(cache_var "ICU_${data_upcase}") set(data_var "ICU_${data_upcase}") find_file("${cache_var}" NAMES "${data}" HINTS ${icu_roots} PATH_SUFFIXES ${icu_data_suffixes} DOC "ICU ${data} data file") mark_as_advanced("${cache_var}") set("${data_var}" "${${cache_var}}" PARENT_SCOPE) endforeach() if(NOT ICU_FIND_QUIETLY) if(ICU_LIBS_FOUND) message(STATUS "Found the following ICU libraries:") foreach(found ${ICU_LIBS_FOUND}) message(STATUS " ${found}") endforeach() endif() if(ICU_LIBS_NOTFOUND) message(STATUS "The following ICU libraries were not found:") foreach(notfound ${ICU_LIBS_NOTFOUND}) message(STATUS " ${notfound}") endforeach() endif() endif() if(ICU_DEBUG) message(STATUS "--------FindICU.cmake search debug--------") message(STATUS "ICU binary path search order: ${icu_roots}") message(STATUS "ICU include path search order: ${icu_roots}") message(STATUS "ICU library path search order: ${icu_roots}") message(STATUS "----------------") endif() endfunction() _ICU_FIND() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(ICU FOUND_VAR ICU_FOUND REQUIRED_VARS ICU_INCLUDE_DIR ICU_LIBRARY _ICU_REQUIRED_LIBS_FOUND VERSION_VAR ICU_VERSION FAIL_MESSAGE "Failed to find all ICU components") unset(_ICU_REQUIRED_LIBS_FOUND) if(ICU_FOUND) set(ICU_INCLUDE_DIRS "${ICU_INCLUDE_DIR}") set(ICU_LIBRARIES "${ICU_LIBRARY}") foreach(_ICU_component ${ICU_FIND_COMPONENTS}) string(TOUPPER "${_ICU_component}" _ICU_component_upcase) set(_ICU_component_cache "ICU_${_ICU_component_upcase}_LIBRARY") set(_ICU_component_cache_release "ICU_${_ICU_component_upcase}_LIBRARY_RELEASE") set(_ICU_component_cache_debug "ICU_${_ICU_component_upcase}_LIBRARY_DEBUG") set(_ICU_component_lib "ICU_${_ICU_component_upcase}_LIBRARIES") set(_ICU_component_found "ICU_${_ICU_component_upcase}_FOUND") set(_ICU_imported_target "ICU::${_ICU_component}") if(${_ICU_component_found}) set("${_ICU_component_lib}" "${${_ICU_component_cache}}") if(NOT TARGET ${_ICU_imported_target}) add_library(${_ICU_imported_target} UNKNOWN IMPORTED) if(ICU_INCLUDE_DIR) set_target_properties(${_ICU_imported_target} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ICU_INCLUDE_DIR}") endif() if(EXISTS "${${_ICU_component_cache}}") set_target_properties(${_ICU_imported_target} PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" IMPORTED_LOCATION "${${_ICU_component_cache}}") endif() if(EXISTS "${${_ICU_component_cache_release}}") set_property(TARGET ${_ICU_imported_target} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) set_target_properties(${_ICU_imported_target} PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX" IMPORTED_LOCATION_RELEASE "${${_ICU_component_cache_release}}") endif() if(EXISTS "${${_ICU_component_cache_debug}}") set_property(TARGET ${_ICU_imported_target} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) set_target_properties(${_ICU_imported_target} PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX" IMPORTED_LOCATION_DEBUG "${${_ICU_component_cache_debug}}") endif() if(CMAKE_DL_LIBS AND _ICU_component STREQUAL "uc") set_target_properties(${_ICU_imported_target} PROPERTIES INTERFACE_LINK_LIBRARIES "${CMAKE_DL_LIBS}") endif() endif() endif() unset(_ICU_component_upcase) unset(_ICU_component_cache) unset(_ICU_component_lib) unset(_ICU_component_found) unset(_ICU_imported_target) endforeach() endif() if(ICU_DEBUG) message(STATUS "--------FindICU.cmake results debug--------") message(STATUS "ICU found: ${ICU_FOUND}") message(STATUS "ICU_VERSION number: ${ICU_VERSION}") message(STATUS "ICU_ROOT directory: ${ICU_ROOT}") message(STATUS "ICU_INCLUDE_DIR directory: ${ICU_INCLUDE_DIR}") message(STATUS "ICU_LIBRARIES: ${ICU_LIBRARIES}") foreach(program IN LISTS icu_programs) string(TOUPPER "${program}" program_upcase) set(program_lib "ICU_${program_upcase}_EXECUTABLE") message(STATUS "${program} program: ${program_lib}=${${program_lib}}") unset(program_upcase) unset(program_lib) endforeach() foreach(data IN LISTS icu_data) string(TOUPPER "${data}" data_upcase) string(REPLACE "." "_" data_upcase "${data_upcase}") set(data_lib "ICU_${data_upcase}") message(STATUS "${data} data: ${data_lib}=${${data_lib}}") unset(data_upcase) unset(data_lib) endforeach() foreach(component IN LISTS ICU_FIND_COMPONENTS) string(TOUPPER "${component}" component_upcase) set(component_lib "ICU_${component_upcase}_LIBRARIES") set(component_found "ICU_${component_upcase}_FOUND") set(component_found_compat "${component_upcase}_FOUND") message(STATUS "${component} library found: ${component_found}=${${component_found}}") message(STATUS "${component} library found (compat name): ${component_found_compat}=${${component_found_compat}}") message(STATUS "${component} library: ${component_lib}=${${component_lib}}") unset(component_upcase) unset(component_lib) unset(component_found) unset(component_found_compat) endforeach() message(STATUS "----------------") endif() unset(icu_programs)