| # Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| # file LICENSE.rst or https://cmake.org/licensing for details. | |
| #[=======================================================================[.rst: | |
| FindIconv | |
| --------- | |
| .. versionadded:: 3.11 | |
| Finds the ``iconv()`` POSIX.1 functions on the system: | |
| .. code-block:: cmake | |
| find_package(Iconv [<version>] [...]) | |
| Iconv functions might be provided in the standard C library or externally | |
| in the form of an additional library. | |
| Imported Targets | |
| ^^^^^^^^^^^^^^^^ | |
| This module provides the following :ref:`Imported Targets`: | |
| ``Iconv::Iconv`` | |
| Target encapsulating the iconv usage requirements, available only if iconv is | |
| found. | |
| Result Variables | |
| ^^^^^^^^^^^^^^^^ | |
| This module defines the following variables: | |
| ``Iconv_FOUND`` | |
| Boolean indicating whether the (requested version of) iconv support was | |
| found. | |
| ``Iconv_VERSION`` | |
| .. versionadded:: 3.21 | |
| The version of iconv found (x.y). | |
| .. note:: | |
| Some libiconv implementations don't embed the version in their header files. | |
| In this case the variables ``Iconv_VERSION*`` will be empty. | |
| ``Iconv_VERSION_MAJOR`` | |
| .. versionadded:: 3.21 | |
| The major version of iconv. | |
| ``Iconv_VERSION_MINOR`` | |
| .. versionadded:: 3.21 | |
| The minor version of iconv. | |
| ``Iconv_INCLUDE_DIRS`` | |
| The include directories containing the iconv headers. | |
| ``Iconv_LIBRARIES`` | |
| The iconv libraries to be linked. | |
| Cache Variables | |
| ^^^^^^^^^^^^^^^ | |
| The following cache variables may also be set: | |
| ``Iconv_IS_BUILT_IN`` | |
| A boolean variable indicating whether iconv support is stemming from the C | |
| standard library or not. Even if the C library provides ``iconv()``, the | |
| presence of an external ``libiconv`` implementation might lead to this being | |
| false. | |
| ``Iconv_INCLUDE_DIR`` | |
| The directory containing the iconv headers. | |
| ``Iconv_LIBRARY`` | |
| The iconv library (if not implicitly given in the C library). | |
| .. note:: | |
| On POSIX platforms, iconv might be part of the C library and the cache | |
| variables ``Iconv_INCLUDE_DIR`` and ``Iconv_LIBRARY`` might be empty. | |
| Examples | |
| ^^^^^^^^ | |
| Finding iconv and linking it to a project target: | |
| .. code-block:: cmake | |
| find_package(Iconv) | |
| target_link_libraries(project_target PRIVATE Iconv::Iconv) | |
| #]=======================================================================] | |
| cmake_policy(PUSH) | |
| cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n> | |
| include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake) | |
| if(CMAKE_C_COMPILER_LOADED) | |
| include(${CMAKE_CURRENT_LIST_DIR}/CheckCSourceCompiles.cmake) | |
| elseif(CMAKE_CXX_COMPILER_LOADED) | |
| include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXSourceCompiles.cmake) | |
| else() | |
| # If neither C nor CXX are loaded, implicit iconv makes no sense. | |
| set(Iconv_IS_BUILT_IN FALSE) | |
| endif() | |
| # iconv can only be provided in libc on a POSIX system. | |
| # If any cache variable is already set, we'll skip this test. | |
| if(NOT DEFINED Iconv_IS_BUILT_IN) | |
| if(UNIX AND NOT DEFINED Iconv_INCLUDE_DIR AND NOT DEFINED Iconv_LIBRARY) | |
| cmake_push_check_state(RESET) | |
| # We always suppress the message here: Otherwise on supported systems | |
| # not having iconv in their C library (e.g. those using libiconv) | |
| # would always display a confusing "Looking for iconv - not found" message | |
| set(CMAKE_FIND_QUIETLY TRUE) | |
| # The following code will not work, but it's sufficient to see if it compiles. | |
| # Note: libiconv will define the iconv functions as macros, so CheckSymbolExists | |
| # will not yield correct results. | |
| set(Iconv_IMPLICIT_TEST_CODE | |
| " | |
| #include <stddef.h> | |
| #include <iconv.h> | |
| int main(void) { | |
| char *a, *b; | |
| size_t i, j; | |
| iconv_t ic; | |
| ic = iconv_open(\"to\", \"from\"); | |
| iconv(ic, &a, &i, &b, &j); | |
| iconv_close(ic); | |
| } | |
| " | |
| ) | |
| if(CMAKE_C_COMPILER_LOADED) | |
| check_c_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN) | |
| else() | |
| check_cxx_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN) | |
| endif() | |
| cmake_pop_check_state() | |
| else() | |
| set(Iconv_IS_BUILT_IN FALSE) | |
| endif() | |
| endif() | |
| set(_Iconv_REQUIRED_VARS) | |
| if(Iconv_IS_BUILT_IN) | |
| set(_Iconv_REQUIRED_VARS _Iconv_IS_BUILT_IN_MSG) | |
| set(_Iconv_IS_BUILT_IN_MSG "built in to C library") | |
| else() | |
| set(_Iconv_REQUIRED_VARS Iconv_LIBRARY Iconv_INCLUDE_DIR) | |
| find_path(Iconv_INCLUDE_DIR | |
| NAMES "iconv.h" | |
| PATH_SUFFIXES | |
| gnu-libiconv # GNU libiconv on Alpine Linux has header in a subdirectory. | |
| DOC "iconv include directory") | |
| set(Iconv_LIBRARY_NAMES "iconv" "libiconv") | |
| mark_as_advanced(Iconv_INCLUDE_DIR) | |
| find_library(Iconv_LIBRARY | |
| NAMES iconv libiconv | |
| NAMES_PER_DIR | |
| DOC "iconv library (if not in the C library)") | |
| mark_as_advanced(Iconv_LIBRARY) | |
| endif() | |
| # NOTE: glibc's iconv.h does not define _LIBICONV_VERSION | |
| if(Iconv_INCLUDE_DIR AND EXISTS "${Iconv_INCLUDE_DIR}/iconv.h") | |
| file(STRINGS ${Iconv_INCLUDE_DIR}/iconv.h Iconv_VERSION_DEFINE REGEX "_LIBICONV_VERSION (.*)") | |
| if(Iconv_VERSION_DEFINE MATCHES "(0x[A-Fa-f0-9]+)") | |
| set(Iconv_VERSION_NUMBER "${CMAKE_MATCH_1}") | |
| # encoding -> version number: (major<<8) + minor | |
| math(EXPR Iconv_VERSION_MAJOR "${Iconv_VERSION_NUMBER} >> 8" OUTPUT_FORMAT HEXADECIMAL) | |
| math(EXPR Iconv_VERSION_MINOR "${Iconv_VERSION_NUMBER} - (${Iconv_VERSION_MAJOR} << 8)" OUTPUT_FORMAT HEXADECIMAL) | |
| math(EXPR Iconv_VERSION_MAJOR "${Iconv_VERSION_MAJOR}" OUTPUT_FORMAT DECIMAL) | |
| math(EXPR Iconv_VERSION_MINOR "${Iconv_VERSION_MINOR}" OUTPUT_FORMAT DECIMAL) | |
| set(Iconv_VERSION "${Iconv_VERSION_MAJOR}.${Iconv_VERSION_MINOR}") | |
| endif() | |
| unset(Iconv_VERSION_DEFINE) | |
| unset(Iconv_VERSION_NUMBER) | |
| endif() | |
| include(FindPackageHandleStandardArgs) | |
| find_package_handle_standard_args(Iconv | |
| REQUIRED_VARS ${_Iconv_REQUIRED_VARS} | |
| VERSION_VAR Iconv_VERSION) | |
| if(Iconv_FOUND) | |
| if(Iconv_IS_BUILT_IN) | |
| set(Iconv_INCLUDE_DIRS "") | |
| set(Iconv_LIBRARIES "") | |
| else() | |
| set(Iconv_INCLUDE_DIRS "${Iconv_INCLUDE_DIR}") | |
| set(Iconv_LIBRARIES "${Iconv_LIBRARY}") | |
| endif() | |
| if(NOT TARGET Iconv::Iconv) | |
| add_library(Iconv::Iconv INTERFACE IMPORTED) | |
| set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${Iconv_INCLUDE_DIRS}") | |
| set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_LINK_LIBRARIES "${Iconv_LIBRARIES}") | |
| endif() | |
| endif() | |
| cmake_policy(POP) |