trouble with find_package(iconv) and include(FindIconv) on AIX

I have discovered (while building Doxygen) that the iconv test fails on AIX with g++ because of incorrect (for AIX) linking. I took the test’s code:

(python-env-nepal) robb@nepal:/raid/proj/procyon/checkouts-procyon/robb/dle-sandbox/conan-doxygen_installer (master)$ echo "#include <iconv.h>

 int main() {
    iconv(iconv_t(-1), 0, 0, 0, 0);
 }" > iconv_test.cpp

Build without adding iconv at link time -

(python-env-nepal) robb@nepal:/raid/proj/procyon/checkouts-procyon/robb/dle-sandbox/conan-doxygen_installer (master)$ g++ -o ictest iconv_test.cpp
ld: 0711-317 ERROR: Undefined symbol: .libiconv
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
collect2: error: ld returned 8 exit status

Now just specify -liconv on the link - which works -

(python-env-nepal) robb@nepal:/raid/proj/procyon/checkouts-procyon/robb/dle-sandbox/conan-doxygen_installer (master)$ g++ -o ictest iconv_test.cpp -liconv

The link command as produced by CMake (3.18.0 in this case)

(python-env-nepal) robb@nepal:/raid/proj/procyon/checkouts-procyon/robb/dle-sandbox/conan-doxygen_installer (master)$ /opt/freeware/bin/g++ -maix64 -pthread -maltivec -mvsx -DICONV_COMPILES -Wl,-bnoipath iconv_test.cpp -o ictest -Wl,-blibpath:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/pthread/ppc64:/opt/freeware/lib/pthread/ppc64:/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8:/opt/freeware/lib:/usr/lib:/lib /usr/lib/libiconv.a
ld: 0711-317 ERROR: Undefined symbol: .libiconv
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
collect2: error: ld returned 8 exit status

Here, specifying the full path to the shared library (/usr/lib/libiconv.a is an archive with three shared objects: 32-bit, 64-bit and an older 32-bit version).

Seems like IMPORTED_LIBNAME should be used on AIX then? @brad.king?

When using -liconv, which library file does the linker choose?

Oh, surprise! It’s not using /usr/lib/libiconv.a when it’s specified as -liconv

(python-env-nepal) robb@nepal:/raid/proj/procyon/checkouts-procyon/robb/dle-sandbox/test (develop-18)$ g++ -o iconv_test -maix64 -pthread iconv_test.cpp -liconv
(python-env-nepal) robb@nepal:/raid/proj/procyon/checkouts-procyon/robb/dle-sandbox/test (develop-18)$ ldd iconv_test
iconv_test needs:
/usr/lib/libc.a(shr_64.o)
/usr/lib/libpthreads.a(shr_xpg5_64.o)
/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/…/…/…/libiconv.a(libiconv.so.2)
/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/pthread/ppc64/libgcc_s.a(shr.o)
/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/8/pthread/ppc64/libstdc++.a(libstdc++.so.6)
/unix
/usr/lib/libcrypt.a(shr_64.o)
(python-env-nepal) robb@nepal:/raid/proj/procyon/checkouts-procyon/robb/dle-sandbox/test (develop-18)$ g++ -o iconv_test -maix64 -pthread iconv_test.cpp -L/usr/lib -liconv
ld: 0711-317 ERROR: Undefined symbol: .libiconv
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
collect2: error: ld returned 8 exit status

Thanks. If you’re using the /opt/freeware compilers, I suggest also adding that prefix to CMAKE_PREFIX_PATH, either as an environment variable or as -DCMAKE_PREFIX_PATH=/opt/freeware. That will tell CMake’s find operations to prefer that directory over others on the system.