Merge topic 'cxx-checks-tolerate-unused-arguments'
[kiteware-cmake.git] / Modules / FindIconv.cmake
blob879ff16f32cedd21d2ead1988eb7c93b486a0364
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:
5 FindIconv
6 ---------
8 .. versionadded:: 3.11
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).
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.
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.
76 #]=======================================================================]
78 cmake_policy(PUSH)
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)
86 else()
87   # If neither C nor CXX are loaded, implicit iconv makes no sense.
88   set(Iconv_IS_BUILT_IN FALSE)
89 endif()
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
104       "
105       #include <stddef.h>
106       #include <iconv.h>
107       int main(void) {
108         char *a, *b;
109         size_t i, j;
110         iconv_t ic;
111         ic = iconv_open(\"to\", \"from\");
112         iconv(ic, &a, &i, &b, &j);
113         iconv_close(ic);
114       }
115       "
116     )
117     if(CMAKE_C_COMPILER_LOADED)
118       check_c_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN)
119     else()
120       check_cxx_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN)
121     endif()
122     cmake_pop_check_state()
123   else()
124     set(Iconv_IS_BUILT_IN FALSE)
125   endif()
126 endif()
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")
132 else()
133   set(_Iconv_REQUIRED_VARS Iconv_LIBRARY Iconv_INCLUDE_DIR)
135   find_path(Iconv_INCLUDE_DIR
136     NAMES "iconv.h"
137     DOC "iconv include directory")
138   set(Iconv_LIBRARY_NAMES "iconv" "libiconv")
139   mark_as_advanced(Iconv_INCLUDE_DIR)
141   find_library(Iconv_LIBRARY
142     NAMES iconv libiconv
143     NAMES_PER_DIR
144     DOC "iconv library (if not in the C library)")
145   mark_as_advanced(Iconv_LIBRARY)
146 endif()
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}")
161   endif()
163   unset(Iconv_VERSION_DEFINE)
164   unset(Iconv_VERSION_NUMBER)
165 endif()
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)
172 if(Iconv_FOUND)
173   if(Iconv_IS_BUILT_IN)
174     set(Iconv_INCLUDE_DIRS "")
175     set(Iconv_LIBRARIES "")
176   else()
177     set(Iconv_INCLUDE_DIRS "${Iconv_INCLUDE_DIR}")
178     set(Iconv_LIBRARIES "${Iconv_LIBRARY}")
179   endif()
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}")
184   endif()
185 endif()
187 cmake_policy(POP)