Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libgit2-sys is looking up iconv in /opt but git2 only searches system folders #180

Closed
learnopengles opened this issue Jan 17, 2017 · 7 comments

Comments

@learnopengles
Copy link

learnopengles commented Jan 17, 2017

Re: rust-lang/cargo#3538

I get the following linker error when compiling anything that depends on libgit2-sys:

the linker error:

 = note: Undefined symbols for architecture x86_64:
  "_iconv", referenced from:
      _git_path_iconv in liblibgit2_sys-ce5bbe4559aebb33.rlib(path.c.o)
     (maybe you meant: _git_path_iconv_init_precompose, _git_path_iconv , _git_path_iconv_clear )
  "_iconv_close", referenced from:
      _git_path_iconv_clear in liblibgit2_sys-ce5bbe4559aebb33.rlib(path.c.o)
  "_iconv_open", referenced from:
      _git_path_iconv_init_precompose in liblibgit2_sys-ce5bbe4559aebb33.rlib(path.c.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Here is my config:

macOS 10.12.2
Xcode 8.2.1
git version 2.10.1 (Apple Git-78)
CMake and openssl installed via MacPorts.

Example:

sudo port install cmake
sudo port install openssl
export OPENSSL_INCLUDE_DIR=/opt/local/include
export OPENSSL_LIB_DIR=/opt/local/lib
cargo clean
cargo install dinghy


When compiling the C code for libgit2-sys-0.6.6:
-- Found Iconv: -L/usr/lib -liconv

Then when running rustc on libgit2-sys-0.6.6/lib.rs:

-L native=/opt/local/lib

Where there is also an iconv.

The user can fix this by forcing git2 to search /opt/local as follows:

CMAKE_PREFIX_PATH=/opt/local/ cargo build

However, this is decidedly not user-friendly nor easily googleable (well, now it might be).

@nickolay
Copy link

nickolay commented Oct 29, 2018

Thanks for sharing this, it helped me figure out my similar problem.

Since this is something that seems to come up regularly, I thought I'd share the details of my situation in the hope it will be useful to the person who lands here from Google... The solution that worked for me is at the bottom of this comment.

(Note that you can disable the default-features of git2-rs (as suggested here), if you're OK with losing openssl-based functionality - accessing git/https URLs I think?)


I was getting the same error after cmake was removed from the git2's build process in alexcrichton@76f4b74

I also have macports-installed OpenSSL, which openssl-sys detects and instructs Cargo to use by printing cargo:rustc-link-search=native=/opt/local/lib. (It also prints a cargo:include=/opt/local/include, but that doesn't affect libgit2-sys.)

libgit2-sys then proceeds to build using the system's libiconv (I think, since it doesn't provide any specific include paths):

running: "cc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" 
  "-I" "/Users/nickolay/dev/rust-gitrs-test/target/debug/build/libgit2-sys-39caed737c6b60db/out/include" 
  "-I" "libgit2/src" "-I" "libgit2/deps/http-parser" "-I" "libgit2/deps/regex"
  "-I" "/Users/nickolay/dev/rust-gitrs-test/target/debug/build/libssh2-sys-ec69abc68765cfa3/out/include"
  "-fvisibility=hidden" "-o" "/Users/nickolay/dev/rust-gitrs-test/target/debug/build/libgit2-sys-39caed737c6b60db/out/build/libgit2/src/path.o" "-c" "libgit2/src/path.c"

Checking the output indicates that it expects symbols like _iconv_close:

$ nm /Users/nickolay/dev/rust-gitrs-test/target/debug/build/libgit2-sys-39caed737c6b60db/out/build/libgit2/src/path.o \
  | grep -i iconv_close
             U _iconv_close

But the final binary is linked with the /opt/local/lib in the search path (coming from the cargo:rustc-link-search mentioned above, as I understand):

rustc --crate-name rust_gitrs_test src/main.rs --color never --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=9a7c6007e3604ecb -C extra-filename=-9a7c6007e3604ecb --out-dir /Users/nickolay/dev/rust-gitrs-test/target/debug/deps -C incremental=/Users/nickolay/dev/rust-gitrs-test/target/debug/incremental -L dependency=/Users/nickolay/dev/rust-gitrs-test/target/debug/deps --extern git2=/Users/nickolay/dev/rust-gitrs-test/target/debug/deps/libgit2-ce9d2986be756790.rlib 
  -L native=/Users/nickolay/dev/rust-gitrs-test/target/debug/build/libgit2-sys-39caed737c6b60db/out/build
  -L native=/Users/nickolay/dev/rust-gitrs-test/target/debug/build/libssh2-sys-ec69abc68765cfa3/out/build
  -L native=/opt/local/lib

And since there's a libiconv library there, the default paths are not searched. But as the macports' version exports different symbols, I end up with the linker error:

$ nm /opt/local/lib/libiconv.a | grep -i iconv_close
0000000000002338 T _libiconv_close
00000000000f96a8 S _libiconv_close.eh

Removing the -L native=/opt/local/lib as well as adding -L /usr/lib before it (for example via RUSTFLAGS='-L /usr/lib' cargo build) fixes the error.

[edit] but adding RUSTFLAGS='-L /usr/lib' to cargo build wasn't a good idea, it started causing other linker failures recently, so I ended up with this gross hack:

mkdir ~/dev/rust/iconv-hack
ln -s /usr/lib/libiconv.* ~/dev/rust/iconv-hack/

OPENSSL_DIR="/opt/local/" RUSTFLAGS='-L /Users/nickolay/dev/rust/iconv-hack/' cargo build

[edit2] Using pkg_config as detailed below is a better solution.

@nickolay
Copy link

nickolay commented Oct 29, 2018

Note that you can disable the default-features of git2-rs (as suggested here), if you're OK with losing openssl-based functionality [...]

Ah, apparently openssl-sys is not the only one adding macports to the library search path, ncurses-rs does it too. Will doing what it does - running pkg_config and using the include directory returned from that - fail in a different, yet painful way?

[edit] Turns out this is already implemented. You can opt in by setting an environment variable LIBGIT2_SYS_USE_PKG_CONFIG:

port install openssl libgit2 pkgconfig
LIBGIT2_SYS_USE_PKG_CONFIG=1 cargo ...

[edit2] As of 2020, specifying LIBGIT2_SYS_USE_PKG_CONFIG is no longer required, you just have to ensure the up-to-date versions of openssl, libgit2, and pkgconfig are installed in macports.

@alexcrichton
Copy link
Member

I'm going to close this since this isn't something that this library itself has tons of control over unfortunately.

@crlf0710
Copy link
Member

Just meet exactly this error today. My solution is install libgit2 with macports, and then set the environment variable LIBGIT2_SYS_USE_PKG_CONFIG=1 so this crate will pick it up.

@nickolay
Copy link

I had this error again. Turns out git2-rs 0.13+ no longer requires the LIBGIT2_SYS_USE_PKG_CONFIG hack, but changed the libgit2 requirement to be >= 1.0.0. Fixed it by running port selfupdate / port upgrade libgit2 after asking for libgit2 1.0.x to be added to macports.

@vtenfys
Copy link

vtenfys commented Feb 19, 2021

Copy of my comment #263 (comment) since this issue is also relevant:

I think this should be re-opened as I've also encountered the issue when attempting to install cargo-edit and cargo-outdated on macOS Big Sur, with libiconv installed via MacPorts.

Setting RUSTFLAGS as suggested in #263 (comment) did not work for me since this version of macOS does not provide /usr/lib/libiconv.a however the following workaround was successful: https://stackoverflow.com/a/34140282/4247209

Also, installing libgit2 with MacPorts and setting LIBGIT2_SYS_USE_PKG_CONFIG=1 did not fix the issue.

I don't have any libiconv files in my /usr/lib folder (arm64 macOS 11.3 Beta 2) so perhaps this is why the problem is occurring for me but not others? Presumably the builtin version is located somewhere else on my version of macOS which has a different search priority to /usr/lib

@vtenfys
Copy link

vtenfys commented Feb 19, 2021

Ah:

According to the macOS Big Sur 11 Beta Release Notes, "the system ships with a built-in dynamic linker cache of all system-provided libraries. As part of this change, copies of dynamic libraries are no longer present on the filesystem."

from https://lapcatsoftware.com/articles/bigsur.html

I presume this would explain why the problem has arisen again on macOS 11 after it was previously fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants