libiconv and MacOS

2020-08-10 08:19发布

问题:

I am trying to compile GCC 4.5.1 in Mac OS X Lion.

I have a problem with libiconv. First it complained about undefined symbols for architecture x86_64, which were: _iconv, _iconv_open and _iconv_close. I found out that MacPorts version of libiconv rename those to: _libiconv, _libiconv_open and _libiconv_close. So I linked to the Mac OS native libiconv in /usr/lib instead of the MacPorts library in /opt/local/lib.

Undefined symbols for architecture x86_64:
"_iconv", referenced from:
  _convert_using_iconv in libcpp.a(charset.o)
  __nl_find_msg in libintl.a(dcigettext.o)
 (maybe you meant: __cpp_destroy_iconv, _cpp_init_iconv )
"_iconv_close", referenced from:
  __cpp_destroy_iconv in libcpp.a(charset.o)
  __cpp_convert_input in libcpp.a(charset.o)
  __nl_free_domain_conv in libintl.a(loadmsgcat.o)
"_iconv_open", referenced from:
  _init_iconv_desc in libcpp.a(charset.o)
  __nl_init_domain_conv in libintl.a(loadmsgcat.o)

However, after doing that, I tried to rebuild it from the beginning (cleaning and everything), but then it complained at a different point about undefined symbols, but this time _libiconv, _libiconv_open and _libiconv_close.

Undefined symbols for architecture x86_64:
  "_libiconv", referenced from:
    _identifier_to_locale in libbackend.a(pretty-print.o)
  "_libiconv_close", referenced from:
    _identifier_to_locale in libbackend.a(pretty-print.o)
  "_libiconv_open", referenced from:
    _identifier_to_locale in libbackend.a(pretty-print.o)

Is there any idea about how I can deal with this? I have found some solutions uninstalling libiconv from MacPorts, but I don't want to do it, as I have many ports depending on it.

回答1:

I solved it by:

$ sudo port -f deactivate libiconv
$ ...build my project...
$ sudo port activate libiconv

There's probably a better way but I'm not using GCC directly, so this helps as a temporary workaround.



回答2:

I solve this by including two libiconv from both /usr/lib and /opt/local/lib. This is a hacky way to solve, if anyone has better solution, please post. Suppose [gcc-src] is the source directory of gcc. What I did is as following:

  1. In /usr/lib, copy libiconv.* as libiconv1.*
  2. Go to [gcc-src]/gcc/Makefile.in
    change LIBINTL = @LIBINTL@ to LIBINTL = @LIBINTL@ -L/opt/local/lib -liconv -L/usr/lib -liconv1
  3. Configure by: CC=gcc-mp-4.7 CXX=g++-mp-4.7 ../gcc-4.7.2/configure --with-gmp=/opt/local --enable-languages=c,c++ --enable-checking=release —prefix=[gcc-src] <- must be absolute address. I use a macport-made gcc and g++. Maybe using gcc and g++ from system work too.
  4. make
  5. make install The binary will be at [gcc-src]/bin/


回答3:

Looks like your make clean didn't actually remove libbackend.a from the build directory; you were still trying to link with the old version of your code compiled against MacPorts. Manually running rm libbackend.a (or make distclean or make spotless or whatever is supposed to really clean everything up) probably fixed the problem, right?



回答4:

Even though this is an old thread, the solution below might help someone searching historic questions for help. It is a simple one-line command that will fix the problem using sed to correct all of the iconv function references.

$ tar xf gcc-6.4.0.tar.gz
$ cd gcc=6.4.0
$ # convert iconv(..)       --> _libiconv(..)
$ # convert iconv_open(..)  --> _libiconv_open(..)
$ # convert iconv_close(..) --> _libiconv_close(..)
$ LC_ALL=C time \
    sed -i.bak -e 's@\(iconv[^\(]*(\)@_lib\1@g' \
    $(grep -l -r 'iconv[^\(]*(' . 2>/dev/null)

I used the above solution for this project: https://github.com/jlinoff/gcc-6.4.0-boost-1.66.



回答5:

New answer for old question. The short answer is you have multiple iconv libs on your system. There are a ton of related questions on stackoverflow that don't really answer the underlying problem, so I created an answer over here that explains what's happening in depth and how to resolve.