| # Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| # file Copyright.txt or https://cmake.org/licensing for details. |
| |
| #[=======================================================================[.rst: |
| FindIconv |
| --------- |
| |
| .. versionadded:: 3.11 |
| |
| This module finds the ``iconv()`` POSIX.1 functions on the system. |
| These functions might be provided in the regular C library or externally |
| in the form of an additional library. |
| |
| The following variables are provided to indicate iconv support: |
| |
| .. variable:: Iconv_FOUND |
| |
| Variable indicating if the iconv support was found. |
| |
| .. variable:: Iconv_INCLUDE_DIRS |
| |
| The directories containing the iconv headers. |
| |
| .. variable:: Iconv_LIBRARIES |
| |
| The iconv libraries to be linked. |
| |
| .. variable:: Iconv_VERSION |
| |
| .. versionadded:: 3.21 |
| |
| The version of iconv found (x.y) |
| |
| .. variable:: Iconv_VERSION_MAJOR |
| |
| .. versionadded:: 3.21 |
| |
| The major version of iconv |
| |
| .. variable:: Iconv_VERSION_MINOR |
| |
| .. versionadded:: 3.21 |
| |
| The minor version of iconv |
| |
| .. variable:: Iconv_IS_BUILT_IN |
| |
| A variable indicating whether iconv support is stemming from the |
| C library or not. Even if the C library provides `iconv()`, the presence of |
| an external `libiconv` implementation might lead to this being false. |
| |
| Additionally, the following :prop_tgt:`IMPORTED` target is being provided: |
| |
| .. variable:: Iconv::Iconv |
| |
| Imported target for using iconv. |
| |
| The following cache variables may also be set: |
| |
| .. variable:: Iconv_INCLUDE_DIR |
| |
| The directory containing the iconv headers. |
| |
| .. variable:: 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. |
| |
| .. note:: |
| Some libiconv implementations don't embed the version number in their header files. |
| In this case the variables ``Iconv_VERSION*`` will be empty. |
| |
| #]=======================================================================] |
| |
| 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" |
| 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(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) |
| 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) |