How do I link glibc's implementation of iconv?

12,527

Your program seems fine and compiles fine on my system (Mandriva Linux 2010.1).

I find the libiconv_* references in your compile log worrisome, though. Are you sure that the iconv.h version that gets included comes from glibc and not from a separate libiconv implementation, such as GNU libiconv? It sounds as if it adds a lib prefix to all iconv functions to avoid symbol collisions with the iconv implementation of the C library that came with the system.

Having to explicitly link to libiconv points to a separate iconv implementation too - glibc does not need it.

EDIT:

For the record, I just verified that using the iconv.h header file from libiconv without explicitly linking against it will produce exactly the result that you are seeing - it renames all iconv functions by adding a lib prefix to their names.

Share:
12,527
x-x
Author by

x-x

Updated on June 06, 2022

Comments

  • x-x
    x-x almost 2 years

    The GNU C library provides an implementation of iconv - how do I use it?

    Simple program:

    #include <iconv.h>
    
    int main( int argc, char **argv ) {
            iconv_t cd = iconv_open( "UTF-8", "ISO-8859-1" );
            iconv_close( cd );
            return 0;
    }
    

    Compile and link:

    $ gcc -Wall iconv.c -o iconv
    /tmp/ccKAfXNg.o: In function `main':
    iconv.c:(.text+0x19): undefined reference to `libiconv_open'
    iconv.c:(.text+0x29): undefined reference to `libiconv_close'
    collect2: ld returned 1 exit status
    

    List the symbols to show they exist!

    $ nm -D /lib/libc-2.12.1.so | grep iconv
    00017920 T iconv
    00017ae0 T iconv_close
    00017720 T iconv_open
    

    If I install the GNU libiconv library to /usr/local and link with -liconv it works. How do I link with the glibc implementation of iconv?

    EDIT: More information as requested from the comments:

    List all iconv.h files in /usr (1 match)

    $ find /usr/ | grep "iconv\.h"
    /usr/include/iconv.h
    

    Reinstall libc6-dev to ensure the correct header is installed.

    $ dpkg -S /usr/include/iconv.h 
    libc6-dev: /usr/include/iconv.h
    $ apt-get install --reinstall libc6-dev
    Reading package lists... Done                                                                                                                                                                                                                  
    Building dependency tree                                                                                                                                                                                                                       
    Reading state information... Done                                                                                                                                                                                                              
    0 upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 0 not upgraded.                                                                                                                                                                  
    Need to get 0B/4,910kB of archives.                                                                                                                                                                                                            
    After this operation, 0B of additional disk space will be used.                                                                                                                                                                                
    (Reading database ... 143458 files and directories currently installed.)                                                                                                                                                                       
    Preparing to replace libc6-dev 2.12.1-0ubuntu10.1 (using .../libc6-dev_2.12.1-0ubuntu10.1_i386.deb) ...                                                                                                                                        
    Unpacking replacement libc6-dev ...                                                                                                                                                                                                            
    Setting up libc6-dev (2.12.1-0ubuntu10.1) ...
    

    Compile and link again with suggested preprocessor option:

    $ gcc -Wall -DLIBICONV_PLUG iconv.c -o iconv
    /tmp/ccKAfXNg.o: In function `main':
    iconv.c:(.text+0x19): undefined reference to `libiconv_open'
    iconv.c:(.text+0x29): undefined reference to `libiconv_close'
    collect2: ld returned 1 exit status
    

    Output from gcc -H:

    $ gcc -H iconv.c 
    . /usr/include/iconv.h
    .. /usr/include/features.h
    ... /usr/include/bits/predefs.h
    ... /usr/include/sys/cdefs.h
    .... /usr/include/bits/wordsize.h
    ... /usr/include/gnu/stubs.h
    .... /usr/include/bits/wordsize.h
    .... /usr/include/gnu/stubs-32.h
    .. /usr/lib/gcc/i686-linux-gnu/4.4.5/include/stddef.h
    Multiple include guards may be useful for:
    /usr/include/bits/predefs.h
    /usr/include/gnu/stubs-32.h
    /usr/include/gnu/stubs.h
    /usr/lib/gcc/i686-linux-gnu/4.4.5/include/stddef.h
    

    pastbin copy of /usr/include/iconv.h

    Fixed: Reboot fixed the issue. I suspect a cached copy of libiconv was causing the conflicts, even though it was deleted from disk.

  • x-x
    x-x over 13 years
    I did install libiconv to /usr/local to test it, but have since removed it with a 'make uninstall' - no traces left that I can see.
  • thkala
    thkala over 13 years
    @DrTwox: can you verify which iconv.h gets included?
  • Logan Capaldo
    Logan Capaldo over 13 years
    @DrTwox you can perform the verification by making use of the -H option to gcc. It will print the path of the files included.
  • thkala
    thkala over 13 years
    @DrTwox: Does adding -DLIBICONV_PLUG to your compiler options fix it without -liconv? If it does, then you are using the iconv.h version from libiconv.
  • x-x
    x-x about 13 years
    The computer froze, I reset, it worked. I still don't know what the problem was. Though I uninstalled libiconv from /usr/local, and confirmed it was all deleted, all clues point to the system still seeing the wrong header - stale cache perhaps? I don't understand the deep-down magic of Linux to figure it out myself.