mirror of
https://github.com/Kitware/CMake.git
synced 2025-05-08 22:37:04 +08:00

- Added examples section. - Added some basic descriptions to components. - Variables described as done in other similar find modules.
451 lines
15 KiB
CMake
451 lines
15 KiB
CMake
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
# file LICENSE.rst or https://cmake.org/licensing for details.
|
|
|
|
#[=======================================================================[.rst:
|
|
FindICU
|
|
-------
|
|
|
|
.. versionadded:: 3.7
|
|
|
|
Finds the International Components for Unicode (ICU) libraries and programs.
|
|
|
|
.. versionadded:: 3.11
|
|
Support for static libraries on Windows.
|
|
|
|
Components
|
|
^^^^^^^^^^
|
|
|
|
This module supports the following components:
|
|
|
|
``data``
|
|
Finds the ICU Data library. On Windows, this library component is named
|
|
``dt``, otherwise any of these component names may be used, and the
|
|
appropriate platform-specific library name will be automatically selected.
|
|
|
|
``i18n``
|
|
Finds the ICU Internationalization library. On Windows, this library
|
|
component is named ``in``, otherwise any of these component names may be used,
|
|
and the appropriate platform-specific library name will be automatically
|
|
selected.
|
|
|
|
``io``
|
|
Finds the ICU Stream and I/O (Unicode stdio) library.
|
|
|
|
``le``
|
|
Finds the deprecated ICU Layout Engine library, which has been removed as of
|
|
ICU version 58.
|
|
|
|
``lx``
|
|
Finds the ICU Layout Extensions Engine library, used for paragraph layout.
|
|
|
|
``test``
|
|
Finds the ICU test suits.
|
|
|
|
``tu``
|
|
Finds the ICU Tool Utility library.
|
|
|
|
``uc``
|
|
Finds the base ICU Common and Data libraries. This library is required by
|
|
all other ICU libraries and is recommended to include when working with ICU
|
|
components.
|
|
|
|
At least one component should be specified for this module to successfully find
|
|
ICU:
|
|
|
|
.. code-block:: cmake
|
|
|
|
find_package(ICU COMPONENTS <components>...)
|
|
|
|
Imported Targets
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
This module provides the following :ref:`Imported Targets`:
|
|
|
|
``ICU::<component>``
|
|
|
|
Target encapsulating the usage requirements for the specified ICU component,
|
|
available only if that component is found. The ``<component>`` should be
|
|
written in lowercase, as listed above. For example, use ``ICU::i18n`` for the
|
|
Internationalization library.
|
|
|
|
Result Variables
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
This module defines the following variables:
|
|
|
|
``ICU_FOUND``
|
|
Boolean indicating whether the main programs and libraries were found.
|
|
``ICU_INCLUDE_DIRS``
|
|
The include directories containing the ICU headers.
|
|
``ICU_LIBRARIES``
|
|
Component libraries to be linked.
|
|
``ICU_VERSION``
|
|
The version of the ICU release found.
|
|
|
|
ICU programs are defined in the following variables:
|
|
|
|
``ICU_GENCNVAL_EXECUTABLE``
|
|
The path to the ``gencnval`` executable.
|
|
``ICU_ICUINFO_EXECUTABLE``
|
|
The path to the ``icuinfo`` executable.
|
|
``ICU_GENBRK_EXECUTABLE``
|
|
The path to the ``genbrk`` executable.
|
|
``ICU_ICU-CONFIG_EXECUTABLE``
|
|
The path to the ``icu-config`` executable.
|
|
``ICU_GENRB_EXECUTABLE``
|
|
The path to the ``genrb`` executable.
|
|
``ICU_GENDICT_EXECUTABLE``
|
|
The path to the ``gendict`` executable.
|
|
``ICU_DERB_EXECUTABLE``
|
|
The path to the ``derb`` executable.
|
|
``ICU_PKGDATA_EXECUTABLE``
|
|
The path to the ``pkgdata`` executable.
|
|
``ICU_UCONV_EXECUTABLE``
|
|
The path to the ``uconv`` executable.
|
|
``ICU_GENCFU_EXECUTABLE``
|
|
The path to the ``gencfu`` executable.
|
|
``ICU_MAKECONV_EXECUTABLE``
|
|
The path to the ``makeconv`` executable.
|
|
``ICU_GENNORM2_EXECUTABLE``
|
|
The path to the ``gennorm2`` executable.
|
|
``ICU_GENCCODE_EXECUTABLE``
|
|
The path to the ``genccode`` executable.
|
|
``ICU_GENSPREP_EXECUTABLE``
|
|
The path to the ``gensprep`` executable.
|
|
``ICU_ICUPKG_EXECUTABLE``
|
|
The path to the ``icupkg`` executable.
|
|
``ICU_GENCMN_EXECUTABLE``
|
|
The path to the ``gencmn`` executable.
|
|
|
|
ICU component libraries are defined in the following variables:
|
|
|
|
``ICU_<COMPONENT>_FOUND``
|
|
Boolean indicating whether the ICU component was found; The ``<COMPONENT>``
|
|
should be written in uppercase.
|
|
``ICU_<COMPONENT>_LIBRARIES``
|
|
Libraries for component; The ``<COMPONENT>`` should be written in uppercase.
|
|
|
|
ICU datafiles are defined in the following variables:
|
|
|
|
``ICU_MAKEFILE_INC``
|
|
The path to the ``Makefile.inc`` file.
|
|
``ICU_PKGDATA_INC``
|
|
The path to the ``pkgdata.inc`` file.
|
|
|
|
Cache Variables
|
|
^^^^^^^^^^^^^^^
|
|
|
|
The following cache variables may also be set:
|
|
|
|
``ICU_<PROGRAM>_EXECUTABLE``
|
|
The path to executable ``<PROGRAM>``; The ``<PROGRAM>`` should be written in
|
|
uppercase. These variables correspond to the ICU program result variables
|
|
listed above.
|
|
``ICU_INCLUDE_DIR``
|
|
The directory containing the ICU headers.
|
|
``ICU_<COMPONENT>_LIBRARY``
|
|
The library for the ICU component. The ``<COMPONENT>`` should be written in
|
|
uppercase.
|
|
|
|
Hints
|
|
^^^^^
|
|
|
|
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.
|
|
|
|
.. note::
|
|
|
|
In most cases, none of the above variables will need to be set, unless
|
|
multiple versions of ICU are available and a specific version is required.
|
|
|
|
Examples
|
|
^^^^^^^^
|
|
|
|
Finding ICU components and linking them to a project target:
|
|
|
|
.. code-block:: cmake
|
|
|
|
find_package(ICU COMPONENTS i18n io uc)
|
|
target_link_libraries(project_target PRIVATE ICU::i18n ICU::io ICU::uc)
|
|
#]=======================================================================]
|
|
|
|
cmake_policy(PUSH)
|
|
cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
|
|
# Written by Roger Leigh <rleigh@codelibre.net>
|
|
|
|
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(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}_FOUND")
|
|
set(component_found_compat "${component_upcase}_FOUND")
|
|
set(component_found_compat2 "ICU_${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") # noqa: spellcheck disable-line
|
|
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)
|
|
set("${component_found_compat2}" ON)
|
|
list(APPEND ICU_LIBRARY "${${component_cache}}")
|
|
endif()
|
|
mark_as_advanced("${component_found}")
|
|
mark_as_advanced("${component_found_compat}")
|
|
mark_as_advanced("${component_found_compat2}")
|
|
set("${component_cache}" "${${component_cache}}" PARENT_SCOPE)
|
|
set("${component_found}" "${${component_found}}" PARENT_SCOPE)
|
|
set("${component_found_compat}" "${${component_found_compat}}" PARENT_SCOPE)
|
|
set("${component_found_compat2}" "${${component_found_compat2}}" PARENT_SCOPE)
|
|
endforeach()
|
|
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()
|
|
endfunction()
|
|
|
|
_ICU_FIND()
|
|
|
|
include(FindPackageHandleStandardArgs)
|
|
find_package_handle_standard_args(ICU
|
|
REQUIRED_VARS
|
|
ICU_INCLUDE_DIR
|
|
ICU_LIBRARY
|
|
VERSION_VAR
|
|
ICU_VERSION
|
|
HANDLE_COMPONENTS
|
|
FAIL_MESSAGE
|
|
"Failed to find all ICU components"
|
|
)
|
|
|
|
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()
|
|
|
|
unset(icu_programs)
|
|
cmake_policy(POP)
|