Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to build a static lib of iconv on OSX without libiconv symbol names?

I am trying to build gnu iconv on OSX as a static library. This is not a problem, it builds fine with

./configure --enable-static
make clean && make

but when I run nm on libiconv.a, I get the following results

...
_libiconv
_libiconv_open_
_libiconv_close_
...

This is problematic, because I want to build libxml2 using this library, and it requires the following symbols

iconv
iconv_open
iconv_close

Looking through the header file, it seems like the difference between these two symbol names is whether LIBICONV_PLUG is defined. But when I run make as

make clean && make CPPFLAGS=-DLIBICONV_PLUG

I get errors because several things are not defined, such as ICONV_GET_DISCARD_ILSEQ and ICONV_SET_HOOKS. Looking through the header file again, these are only defined if LIBICONV_PLUG is not defined.

My question is, am I using LIBICONV_PLUG correctly? Is there some other way to get a static library with the symbols I need? Should I go through the undefined symbols and define them myself by hand?

like image 784
Sossisos Avatar asked Feb 06 '23 18:02

Sossisos


1 Answers

There are three possible ways to build and use GNU libiconv. In all three cases, the symbols that it defines for use by a C or C++ program (through the header file) are 'iconv_open', 'iconv', 'iconv_close'.

  • The normal one is that, at object file level, it defines symbols 'libiconv_open' etc., so as not to conflict with the operating system's standard libraries. The mapping between the symbol at C level and at object file level happens in <iconv.h>.

    You will get a link error if you use the system's <iconv.h> with the GNU libiconv.{so,dylib,a} or vice versa. This is a feature, because the two have slightly different features (OS X libiconv.dylib supports an encoding named "UTF-8-MAC", whereas GNU libiconv has a number of improvements and fixes) and mismatch can lead to trouble.

  • If you are a system vendor, you can build GNU libiconv in such a way that it defines 'iconv_open' instead of 'libiconv_open', etc. This is achieved through a simple edit of iconv.h.

    Or, specifically on OS X, you can pick the libiconv from https://opensource.apple.com/ and compile it for yourself. But be aware that this version is based on GNU libiconv 1.11, that is, it is quite old.

  • As explained in GNU libiconv's README, the LIBICONV_PLUG flag creates a library that will override the functionality in the system; this works only on GNU, Solaris, and OSF/1.

In your case, where you only want to have GNU libiconv be used by some free software package (such as libxml2), the simplest way is to take the first approach, and during compilation of that package, use -I and -L options to make it find the GNU libiconv header file and library.

In fact, libxml2 makes this easy: its configure script already has an option --with-iconv=prefix, through which you specify the directory hierarchy in which you have installed GNU libiconv (the header file in prefix/include/ and the object file in prefix/lib/); the configure script will then synthesize the appropriate -I and -L options.

like image 107
Bruno Haible Avatar answered Feb 08 '23 14:02

Bruno Haible