FindIconv prefers libc Iconv over libiconv, but it's very easy to accidentally include the libiconv header
When searching for iconv, FindIconv.cmake searches for a built-in iconv first, then the libiconv library. This means that if the built-in iconv is found, the library version will be ignored even if it also exists. This can cause problems, as if the library version was installed via the system package manager, e.g. this FreeBSD package, its header will be sitting in /usr/local/include
, right next to the headers of many other libraries. If any of those other libraries are used, /usr/local/include
will be added as an include directory, and #include <iconv.h>
will pick up that header instead of the libc one. The two iconv headers use a define that points at different function names depending on whether the header is from libc or libiconv, which means that if the libiconv header is used but libiconv isn't linked against, the build will fail with a linking error.
An example of this issue can be seen on this FreeBSD build of Dolphin from when I tried to switch over to find_package(Iconv)
from a manual library/header search: https://dolphin.ci/#/builders/13/builds/10945
I think it would be better to always search for a non-libc iconv, and only use the libc one if no other iconv is found. This already seems hinted at with the comment "Even if the C library provides iconv(), the presence of an external libiconv implementation might lead to this being false.", but isn't actually done.