Posts Tagged ‘libiconv’

libiconv from OS X and Mac Port, and change of Xcode behavior

I have an old project for converting wrongly encoded Korean to properly encode to properly encoded one in mp3 files.

However due to file system corruption while in upgrading to OS X 10.11.6,  I had to rebuild the project again. I found out that I had another project for the same purpose to use different ID3 library. I didn’t remember which project was correct one.

I finally identified the correct one, but had some issues. It was built previously without a problem, but it failed this time. It could be due to changes in Xcode. Yes. there is such change. I will talk about that after taking about difference of libiconv from OS X and Mac Port.

When tried to build, it complaint _iconv, _iconv_open, _iconv_close were missing.
I recalled that there was difference between libiconv from OS X and Mac Port, and there was a comment I wrote for that, but didn’t remember its detailed reasoning for that.

stackoverflow.com/questions/27392085/cant-link-to-iconv-on-os-x

So, I googled and found the stack overflow question above, and it made me recall what problem it had completely.

So,  this time I would like to record it here.

This is the result with libiconv from Mac Port.

JongAms-Mac-mini:lib jongampark$ nm -m  libiconv.2.dylib | grep iconv

0000000000002db1 (__TEXT,__text) external _libiconv
0000000000002dd3 (__TEXT,__text) external _libiconv_close
000000000000158c (__TEXT,__text) external _libiconv_open

This is the result with libiconv from OS X.

JongAms-Mac-mini:lib jongampark$ nm -m /usr/lib/libiconv.dylib | grep iconv

000000000000301c (__TEXT,__text) external _iconv
000000000000336d (__TEXT,__text) external _iconv_canonicalize
000000000000303e (__TEXT,__text) external _iconv_close
0000000000001c41 (__TEXT,__text) external _iconv_open

So, the difference is that the ones from Mac Port have _lib is prefixed while the ones from OS X don’t.

Also, the included iconv.h file should match with the library file.


Finally I would like to talk about the changes of Xcode behavior.

With a version of 7.x.x, Apple changed that default libraries and header files could be searched without specifying them. Especially, if a library, for example, /usr/lib/libiconv.dylib is linked using the build phase, Xcode didn’t require the /usr/lib is added to the library search path. It was new behavior at that time.

However, they changed it again from some version of Xcode later than the version mentioned above. So, the library path should be set to include /usr/lib.
Without that, even though the /usr/lib/libiconv.dylib is linked by build phase setting (Link Binary with libraries ), Xcode couldn’t find that it’s in /usr/lib.

Apple doesn’t document this kind of changes, and it gives headache.
I wonder why Apple keeps changing from one behavior to the other behavior from time to time. If they keep changing to a newer behavior, it could be understandable, although I don’t like it. However, they are kind of going forward and backward.

This is small difference, but can affect big way.
Apple should document this kind thing and handle this seriously.

libiconv from MacPort and OS X framework

Somehow libiconv has given me lots of headache since I knew its existence.

Today, I ran into a problem with it. (again!)
Although I linked libiconv from OS X framework and included its header files, it complaint in building.

It somehow said there is no _iconv, _iconv_open and _iconv_close defined.
I wonder why and started to think that it may somehow confused with the libconv from MacPort.
Since I’ve used Unix, which is late 80’s, I had questions on libiconv and others. There are libraries of which official page say that the latest version is 1.4.2, for example. But strangely on my Linux machine or Sun machine I used, there are lib<the_library>.2.x.x.a or lib<the_library>.2.so.
Where the 2.x version comes from?

It’s also same with libiconv. The official page says its latest version is 1.14, but somehow Mac OS X has libiconv.2.dylib.
Header files are a little different. But they are anyway the same, iconv, iconv_open and iconv_close.
Then it should be able to find it.

However, this is what’s there.

symbols in libiconv from MacPort
JongAms-MacBookPro:opt jongp$ nm -a local/lib/libiconv.2.dylib | grep iconv
00000000000f90c0 D __libiconv_version
0000000000003000 T _iconv_canonicalize
0000000000002760 T _libiconv
0000000000002790 T _libiconv_close
0000000000001350 T _libiconv_open
00000000000027a0 T _libiconv_open_into
0000000000017980 t _libiconv_relocate
00000000000fa7a8 b _libiconv_relocate.initialized.b
00000000000178c0 T _libiconv_set_relocation_prefix
0000000000002cc0 T _libiconvctl
0000000000002dd0 T _libiconvlist
symbols in libiconv from OS X framework
JongAms-MacBookPro:opt jongp$ nm -a /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/lib/libiconv.2.dylib  | grep iconv
00000000000f26c0 S ___iconv_2VersionNumber
00000000000f2690 S ___iconv_2VersionString
00000000000f60f0 D __libiconv_version
0000000000002f1f T _iconv
000000000000325d T _iconv_canonicalize
0000000000002f41 T _iconv_close
0000000000001c59 T _iconv_open
0000000000002f4e T _iconvctl
0000000000003064 T _iconvlist
00000000000158e2 T _libiconv_relocate
000000000001582d T _libiconv_set_relocation_prefix

It’s very odd.
Anyway, although the /opt/local/lib, the library path of MacPort is included in the library search path in my Xcode project, but what is actually linked by adding explicitly using Link Binary with Libraries phase of Xcode target project was the one from OS X framework.
Then Xcode should try to link with the version instead of the one from Mac Port.

However, in the messages, it just linked with this option : -liconv.2.
But it couldn’t . Somehow the libiconv from Mac Port still preventd the linkage. (again, MacPort version is not 2, but 1.x )
So, I had to remove /opt/local/lib. Then it linked without a problem.

It’s odd that why there are two different versions on Internet. But even though it is if the library is set to be linked using Xcode “Link Binary with Library”, shouldn’t Xcode or its linker abide by that specific one more strictly? It should try to link the libraries set to be linked such way first.