1 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 #[=======================================================================[.rst:
10 This module finds the ``iconv()`` POSIX.1 functions on the system.
11 These functions might be provided in the regular C library or externally
12 in the form of an additional library.
14 The following variables are provided to indicate iconv support:
16 .. variable:: Iconv_FOUND
18 Variable indicating if the iconv support was found.
20 .. variable:: Iconv_INCLUDE_DIRS
22 The directories containing the iconv headers.
24 .. variable:: Iconv_LIBRARIES
26 The iconv libraries to be linked.
28 .. variable:: Iconv_VERSION
30 .. versionadded:: 3.21
32 The version of iconv found (x.y)
34 .. variable:: Iconv_VERSION_MAJOR
36 .. versionadded:: 3.21
38 The major version of iconv
40 .. variable:: Iconv_VERSION_MINOR
42 .. versionadded:: 3.21
44 The minor version of iconv
46 .. variable:: Iconv_IS_BUILT_IN
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.
52 Additionally, the following :prop_tgt:`IMPORTED` target is being provided:
54 .. variable:: Iconv::Iconv
56 Imported target for using iconv.
58 The following cache variables may also be set:
60 .. variable:: Iconv_INCLUDE_DIR
62 The directory containing the iconv headers.
64 .. variable:: Iconv_LIBRARY
66 The iconv library (if not implicitly given in the C library).
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.
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.
76 #]=======================================================================]
79 cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
81 include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
82 if(CMAKE_C_COMPILER_LOADED)
83 include(${CMAKE_CURRENT_LIST_DIR}/CheckCSourceCompiles.cmake)
84 elseif(CMAKE_CXX_COMPILER_LOADED)
85 include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXSourceCompiles.cmake)
87 # If neither C nor CXX are loaded, implicit iconv makes no sense.
88 set(Iconv_IS_BUILT_IN FALSE)
91 # iconv can only be provided in libc on a POSIX system.
92 # If any cache variable is already set, we'll skip this test.
93 if(NOT DEFINED Iconv_IS_BUILT_IN)
94 if(UNIX AND NOT DEFINED Iconv_INCLUDE_DIR AND NOT DEFINED Iconv_LIBRARY)
95 cmake_push_check_state(RESET)
96 # We always suppress the message here: Otherwise on supported systems
97 # not having iconv in their C library (e.g. those using libiconv)
98 # would always display a confusing "Looking for iconv - not found" message
99 set(CMAKE_FIND_QUIETLY TRUE)
100 # The following code will not work, but it's sufficient to see if it compiles.
101 # Note: libiconv will define the iconv functions as macros, so CheckSymbolExists
102 # will not yield correct results.
103 set(Iconv_IMPLICIT_TEST_CODE
111 ic = iconv_open(\"to\", \"from\");
112 iconv(ic, &a, &i, &b, &j);
117 if(CMAKE_C_COMPILER_LOADED)
118 check_c_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN)
120 check_cxx_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN)
122 cmake_pop_check_state()
124 set(Iconv_IS_BUILT_IN FALSE)
128 set(_Iconv_REQUIRED_VARS)
129 if(Iconv_IS_BUILT_IN)
130 set(_Iconv_REQUIRED_VARS _Iconv_IS_BUILT_IN_MSG)
131 set(_Iconv_IS_BUILT_IN_MSG "built in to C library")
133 set(_Iconv_REQUIRED_VARS Iconv_LIBRARY Iconv_INCLUDE_DIR)
135 find_path(Iconv_INCLUDE_DIR
137 DOC "iconv include directory")
138 set(Iconv_LIBRARY_NAMES "iconv" "libiconv")
139 mark_as_advanced(Iconv_INCLUDE_DIR)
141 find_library(Iconv_LIBRARY
144 DOC "iconv library (if not in the C library)")
145 mark_as_advanced(Iconv_LIBRARY)
148 # NOTE: glibc's iconv.h does not define _LIBICONV_VERSION
149 if(Iconv_INCLUDE_DIR AND EXISTS "${Iconv_INCLUDE_DIR}/iconv.h")
150 file(STRINGS ${Iconv_INCLUDE_DIR}/iconv.h Iconv_VERSION_DEFINE REGEX "_LIBICONV_VERSION (.*)")
152 if(Iconv_VERSION_DEFINE MATCHES "(0x[A-Fa-f0-9]+)")
153 set(Iconv_VERSION_NUMBER "${CMAKE_MATCH_1}")
154 # encoding -> version number: (major<<8) + minor
155 math(EXPR Iconv_VERSION_MAJOR "${Iconv_VERSION_NUMBER} >> 8" OUTPUT_FORMAT HEXADECIMAL)
156 math(EXPR Iconv_VERSION_MINOR "${Iconv_VERSION_NUMBER} - (${Iconv_VERSION_MAJOR} << 8)" OUTPUT_FORMAT HEXADECIMAL)
158 math(EXPR Iconv_VERSION_MAJOR "${Iconv_VERSION_MAJOR}" OUTPUT_FORMAT DECIMAL)
159 math(EXPR Iconv_VERSION_MINOR "${Iconv_VERSION_MINOR}" OUTPUT_FORMAT DECIMAL)
160 set(Iconv_VERSION "${Iconv_VERSION_MAJOR}.${Iconv_VERSION_MINOR}")
163 unset(Iconv_VERSION_DEFINE)
164 unset(Iconv_VERSION_NUMBER)
167 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
168 find_package_handle_standard_args(Iconv
169 REQUIRED_VARS ${_Iconv_REQUIRED_VARS}
170 VERSION_VAR Iconv_VERSION)
173 if(Iconv_IS_BUILT_IN)
174 set(Iconv_INCLUDE_DIRS "")
175 set(Iconv_LIBRARIES "")
177 set(Iconv_INCLUDE_DIRS "${Iconv_INCLUDE_DIR}")
178 set(Iconv_LIBRARIES "${Iconv_LIBRARY}")
180 if(NOT TARGET Iconv::Iconv)
181 add_library(Iconv::Iconv INTERFACE IMPORTED)
182 set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${Iconv_INCLUDE_DIRS}")
183 set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_LINK_LIBRARIES "${Iconv_LIBRARIES}")