svn commit: r254273 - in head: . include lib lib/libc/iconv lib/libiconv_compat lib/libkiconv share/mk sys/sys tools/build/mk

Peter Wemm peter at wemm.org
Sun Aug 18 22:47:17 UTC 2013


On 8/17/13 3:34 PM, Dimitry Andric wrote:
> On Aug 13, 2013, at 09:15, Peter Wemm <peter at FreeBSD.org> wrote:
>> Author: peter
>> Date: Tue Aug 13 07:15:01 2013
>> New Revision: 254273
>> URL: http://svnweb.freebsd.org/changeset/base/254273
>>
>> Log:
>>  The iconv in libc did two things - implement the standard APIs, the GNU
>>  extensions and also tried to be link time compatible with ports libiconv.
>>  This splits that functionality and enables the parts that shouldn't
>>  interfere with the port by default.
>>
>>  WITH_ICONV (now on by default) - adds iconv.h, iconv_open(3) etc.
>>  WITH_LIBICONV_COMPAT (off by default) adds the libiconv_open etc API, linker
>>  symbols and even a stub libiconv.so.3 that are good enough to be able
>>  to 'pkg delete -f libiconv' on a running system and reasonably expect it
>>  to work.
>>
>>  I have tortured many machines over the last few days to try and reduce
>>  the possibilities of foot-shooting as much as I can.  I've successfully
>>  recompiled to enable and disable the libiconv_compat modes, ports that use
>>  libiconv alongside system iconv etc.  If you don't enable the
>>  WITH_LIBICONV_COMPAT switch, they don't share symbol space.
>>
>>  This is an extension of behavior on other system.  iconv(3) is a standard
>>  libc interface and libiconv port expects to be able to run alongside it on
>>  systems that have it.
> 
> Unfortunately I expect this will break many ports, when the libiconv
> port is installed.  A simple example is the following:
> 
>   #include <iconv.h>
> 
>   int main(void)
>   {
>     iconv_t ic = iconv_open("UTF-8", "ISO-8859-1");
>     iconv_close(ic);
>     return 0;
>   }
> 
> If you compile this on a system after r254273 with -I/usr/local/include,
> and the libiconv port installed, it will result in:
> 
>   $ cc -I/usr/local/include iconv-test.c -o iconv-test
>   /tmp/iconv-test-I1ltw1.o: In function `main':
>   iconv-test.c:(.text+0x21): undefined reference to `libiconv_open'
>   iconv-test.c:(.text+0x2f): undefined reference to `libiconv_close'
>   cc: error: linker command failed with exit code 1 (use -v to see invocation)
> 
> This is because libiconv's iconv.h does:
> 
>   #define iconv_open libiconv_open
>   ...
>   #define iconv_close libiconv_close
> 
> and so on for most of its functions.

Yep, but since <iconv.h> is a standard include file, even on Linux systems.
 Autoconf/libtool/etc know this, that's why it typically compiles and links
like this:

cc -I/usr/local/include -L/usr/local/lib iconv-test.c -liconv

I'm sure there are exceptions though.

Random linux box (ubuntu fwiw):

peter at bit1:~$ readelf -a  /lib/x86_64-linux-gnu/libc-2.15.so  |grep iconv
  1554: 00220c0    45 FUNC    GLOBAL DEFAULT   12 iconv_close@@GLIBC_2.2.5
  1745: 0021f10   418 FUNC    GLOBAL DEFAULT   12 iconv@@GLIBC_2.2.5
  1764: 0021d00   523 FUNC    GLOBAL DEFAULT   12 iconv_open@@GLIBC_2.2.5
peter at bit1:~$ grep '^extern' /usr/include/iconv.h
extern iconv_t iconv_open (__const char *, __const char *);
extern size_t iconv (iconv_t, char **__restrict,
extern int iconv_close (iconv_t);

If you mix includes and libraries like in your example, it would fail on
linux too.  However, linux tends to not add libiconv to the mix.

peter at bit1:~$ find / -mount -name 'libiconv*'
peter at bit1:~$ uname -a
Linux bit1 3.2.0-37-generic #58-Ubuntu SMP Thu Jan 24 15:28:10 UTC 2013
x86_64 x86_64 x86_64 GNU/Linux

The WITH_LIBICONV_COMPAT switch can be turned on - that adds the
libiconv_open etc aliases.  It was intended as a transition aid though - it
was intended to make 'pkg delete -f libiconv' on a running system keep working.

I compile my personal systems like this:

Index: Mk/Uses/iconv.mk
===================================================================
--- Mk/Uses/iconv.mk	(revision 324679)
+++ Mk/Uses/iconv.mk	(working copy)
@@ -16,6 +16,8 @@
 IGNORE=	USES=iconv does not require args
 .endif

+.if !exists(/usr/include/iconv.h)
 LIB_DEPENDS+=	libiconv.so.3:${PORTSDIR}/converters/libiconv
+.endif

 .endif

.. and keep libiconv completely off them.  There's a couple of other ports
with it hard coded in, but this covers most of them.  eg: glib20, epic5,
unzip, php-iconv.

-- 
Peter Wemm - peter at wemm.org; peter at FreeBSD.org; peter at yahoo-inc.com; KI6FJV
UTF-8: for when a ' just won\342\200\231t do.
<brueffer> ZFS must be the bacon of file systems.
<brueffer> "everything's better with ZFS"

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 260 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freebsd.org/pipermail/freebsd-ports/attachments/20130818/d3637d9b/attachment.sig>


More information about the freebsd-ports mailing list