1# Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2# file Copyright.txt or https://cmake.org/licensing for details. 3 4#[=======================================================================[.rst: 5FindIconv 6--------- 7 8.. versionadded:: 3.11 9 10This module finds the ``iconv()`` POSIX.1 functions on the system. 11These functions might be provided in the regular C library or externally 12in the form of an additional library. 13 14The following variables are provided to indicate iconv support: 15 16.. variable:: Iconv_FOUND 17 18 Variable indicating if the iconv support was found. 19 20.. variable:: Iconv_INCLUDE_DIRS 21 22 The directories containing the iconv headers. 23 24.. variable:: Iconv_LIBRARIES 25 26 The iconv libraries to be linked. 27 28.. variable:: Iconv_VERSION 29 30 .. versionadded:: 3.21 31 32 The version of iconv found (x.y) 33 34.. variable:: Iconv_VERSION_MAJOR 35 36 .. versionadded:: 3.21 37 38 The major version of iconv 39 40.. variable:: Iconv_VERSION_MINOR 41 42 .. versionadded:: 3.21 43 44 The minor version of iconv 45 46.. variable:: Iconv_IS_BUILT_IN 47 48 A variable indicating whether iconv support is stemming from the 49 C library or not. Even if the C library provides `iconv()`, the presence of 50 an external `libiconv` implementation might lead to this being false. 51 52Additionally, the following :prop_tgt:`IMPORTED` target is being provided: 53 54.. variable:: Iconv::Iconv 55 56 Imported target for using iconv. 57 58The following cache variables may also be set: 59 60.. variable:: Iconv_INCLUDE_DIR 61 62 The directory containing the iconv headers. 63 64.. variable:: Iconv_LIBRARY 65 66 The iconv library (if not implicitly given in the C library). 67 68.. note:: 69 On POSIX platforms, iconv might be part of the C library and the cache 70 variables ``Iconv_INCLUDE_DIR`` and ``Iconv_LIBRARY`` might be empty. 71 72.. note:: 73 Some libiconv implementations don't embed the version number in their header files. 74 In this case the variables ``Iconv_VERSION*`` will be empty. 75 76#]=======================================================================] 77 78include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake) 79if(CMAKE_C_COMPILER_LOADED) 80 include(${CMAKE_CURRENT_LIST_DIR}/CheckCSourceCompiles.cmake) 81elseif(CMAKE_CXX_COMPILER_LOADED) 82 include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXSourceCompiles.cmake) 83else() 84 # If neither C nor CXX are loaded, implicit iconv makes no sense. 85 set(Iconv_IS_BUILT_IN FALSE) 86endif() 87 88# iconv can only be provided in libc on a POSIX system. 89# If any cache variable is already set, we'll skip this test. 90if(NOT DEFINED Iconv_IS_BUILT_IN) 91 if(UNIX AND NOT DEFINED Iconv_INCLUDE_DIR AND NOT DEFINED Iconv_LIBRARY) 92 cmake_push_check_state(RESET) 93 # We always suppress the message here: Otherwise on supported systems 94 # not having iconv in their C library (e.g. those using libiconv) 95 # would always display a confusing "Looking for iconv - not found" message 96 set(CMAKE_FIND_QUIETLY TRUE) 97 # The following code will not work, but it's sufficient to see if it compiles. 98 # Note: libiconv will define the iconv functions as macros, so CheckSymbolExists 99 # will not yield correct results. 100 set(Iconv_IMPLICIT_TEST_CODE 101 " 102 #include <stddef.h> 103 #include <iconv.h> 104 int main() { 105 char *a, *b; 106 size_t i, j; 107 iconv_t ic; 108 ic = iconv_open(\"to\", \"from\"); 109 iconv(ic, &a, &i, &b, &j); 110 iconv_close(ic); 111 } 112 " 113 ) 114 if(CMAKE_C_COMPILER_LOADED) 115 check_c_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN) 116 else() 117 check_cxx_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN) 118 endif() 119 cmake_pop_check_state() 120 else() 121 set(Iconv_IS_BUILT_IN FALSE) 122 endif() 123endif() 124 125set(_Iconv_REQUIRED_VARS) 126if(Iconv_IS_BUILT_IN) 127 set(_Iconv_REQUIRED_VARS _Iconv_IS_BUILT_IN_MSG) 128 set(_Iconv_IS_BUILT_IN_MSG "built in to C library") 129else() 130 set(_Iconv_REQUIRED_VARS Iconv_LIBRARY Iconv_INCLUDE_DIR) 131 132 find_path(Iconv_INCLUDE_DIR 133 NAMES "iconv.h" 134 DOC "iconv include directory") 135 set(Iconv_LIBRARY_NAMES "iconv" "libiconv") 136 mark_as_advanced(Iconv_INCLUDE_DIR) 137 138 find_library(Iconv_LIBRARY 139 NAMES iconv libiconv 140 NAMES_PER_DIR 141 DOC "iconv library (if not in the C library)") 142 mark_as_advanced(Iconv_LIBRARY) 143endif() 144 145# NOTE: glibc's iconv.h does not define _LIBICONV_VERSION 146if(Iconv_INCLUDE_DIR AND EXISTS "${Iconv_INCLUDE_DIR}/iconv.h") 147 file(STRINGS ${Iconv_INCLUDE_DIR}/iconv.h Iconv_VERSION_DEFINE REGEX "_LIBICONV_VERSION (.*)") 148 149 if(Iconv_VERSION_DEFINE MATCHES "(0x[A-Fa-f0-9]+)") 150 set(Iconv_VERSION_NUMBER "${CMAKE_MATCH_1}") 151 # encoding -> version number: (major<<8) + minor 152 math(EXPR Iconv_VERSION_MAJOR "${Iconv_VERSION_NUMBER} >> 8" OUTPUT_FORMAT HEXADECIMAL) 153 math(EXPR Iconv_VERSION_MINOR "${Iconv_VERSION_NUMBER} - (${Iconv_VERSION_MAJOR} << 8)" OUTPUT_FORMAT HEXADECIMAL) 154 155 math(EXPR Iconv_VERSION_MAJOR "${Iconv_VERSION_MAJOR}" OUTPUT_FORMAT DECIMAL) 156 math(EXPR Iconv_VERSION_MINOR "${Iconv_VERSION_MINOR}" OUTPUT_FORMAT DECIMAL) 157 set(Iconv_VERSION "${Iconv_VERSION_MAJOR}.${Iconv_VERSION_MINOR}") 158 endif() 159 160 unset(Iconv_VERSION_DEFINE) 161 unset(Iconv_VERSION_NUMBER) 162endif() 163 164include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) 165find_package_handle_standard_args(Iconv 166 REQUIRED_VARS ${_Iconv_REQUIRED_VARS} 167 VERSION_VAR Iconv_VERSION) 168 169if(Iconv_FOUND) 170 if(Iconv_IS_BUILT_IN) 171 set(Iconv_INCLUDE_DIRS "") 172 set(Iconv_LIBRARIES "") 173 else() 174 set(Iconv_INCLUDE_DIRS "${Iconv_INCLUDE_DIR}") 175 set(Iconv_LIBRARIES "${Iconv_LIBRARY}") 176 endif() 177 if(NOT TARGET Iconv::Iconv) 178 add_library(Iconv::Iconv INTERFACE IMPORTED) 179 set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${Iconv_INCLUDE_DIRS}") 180 set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_LINK_LIBRARIES "${Iconv_LIBRARIES}") 181 endif() 182endif() 183