When compiling some packages from source on Mac OSX, I get the following iconv error:
Undefined symbols for architecture x86_64:
"_iconv", referenced from:
"_iconv_close", referenced from:
"_iconv_open", referenced from:
or I get:
Undefined symbols for architecture x86_64:
"_libiconv", referenced from:
"_libiconv_open", referenced from:
"_libiconv_close", referenced from:
Why does this happen and how can I get around this dependency or, more generally, figure out what is going on and how to fix it?
I had the same problem trying to install
cargo-tree
:My solution was ot to disable
libiconv
from MacPorts:Then installation succeeded.
You may need to activate
libiconv
back if some of you Macports applications are not working:I have run into this problem over multiple years / upgrades of Mac OSX. I have thoroughly read through all the various answers, of which there are many. This answer is what I wish I had had when I started this journey, so I hope it helps.
What's happening:
You have two, possibly three, versions of iconv installed:
Whatever program you're compiling/running isn't finding the one it wants.
This can happen for (at least) 3 reasons:
What to do about it:
Your job is to get whatever you're running/compiling to find the right version of iconv before the others. You can do this in a couple of ways.
When compiling, you can try including a "
--with-iconv=<dir>
" and or "--with-iconv-dir=<dir>
" or "--with-libiconv-prefix=<dir>
" directive when running "configure" to point to the right version. If that doesn't work, you'll need to take a more direct approach like editing the Makefile directly.My personal preference is to contain these kinds of changes just to the project having the problem so it doesn't have a cascading impact on unrelated projects later on. For me, that means editing the Makefile created by "configure" and including the iconv lib dir directly in an LDFLAGS entry (or similar) in the Makefile. When you pass "configure" a "
--with-iconv=
" directive, it's supposed to do that but I have found it doesn't always work because the Makefile will include some other lib dir before the one you want.What you are after here is the ordering. You want your iconv lib dir to show up before other lib dirs in the "cc" compile command, so check the output when "make" is run (verbose mode). Also, you could just replace "-liconv" with the absolute path to the lib file itself (i.e., "path/to/iconv/lib/libiconv.dylib" with no -L, no -l).
In addition, if you see this in a lib path in the Makefile
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib
then put it last in that list of library paths and make sure the path to the correct iconv lib dir is before it. Same for this one on the -I include paths:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include
Potentially, you could also just go in the unwanted iconv lib dirs and move them to another place (note: this won't work for the MacOSX versions because they're protected by the system).
How to debug this problem on your system:
export V=1
" on the command line and then run configure and make in that same shell window).--with-iconv=<path-to-iconv-dir>
" as a param for ./configure would take care of this but sometimes it's not guaranteed that the generated Makefile will include you iconv path before another library path that picks up some other iconv files, so you might need to edit the Makefile to really force it to look exactly where you want it to look first.otool -L <executable/dylib>
will show you what libraries a binary is linking to.xcrun --show-sdk-path
" and then going to that directory where you will find /include and /lib directories. Explained here: https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes#3035624DYLD_LIBRARY_PATH and LD_LIBRARY_PATH
tl;dr: don't do it.
In an effort to get your compile to work, you might have added a new path to DYLD_LIBRARY_PATH or LD_LIBRARY_PATH (in ~/.bash_profile or similar) pointing to the GNU iconv libs in order to "help" the linker find things. This will come back to bite you at another time/day when something completely unrelated to what you're doing now is looking for the MacOSX iconv libs and instead pulls in the GNU libiconv libs. So I leave DYLD_LIBRARY_PATH and LD_LIBRARY_PATH alone when it comes to iconv. For other projects that I compile from source, like OpenSSL, yes, I do change DYLD_LIBRARY_PATH and LD_LIBRARY_PATH because so far there haven't been any conflicts on MacOSX.
Finally, here is a MacPorts support thread discussing this issue that is very illuminating about why this problem exists at all: https://trac.macports.org/ticket/57821