linux - 由于对 gcry-* 符号的许多未定义引用,无法链接 git2-rs
问题描述
环境
- Linux(Pop!_OS,如果这很重要,这意味着它几乎是 Ubuntu)。
$ cargo --version
cargo 1.41.0 (626f0f40e 2019-12-03)
$ rustc --version
rustc 1.41.0 (5e1a79984 2020-01-27)
我做了什么
$ cargo new xxx
Created binary (application) `xxx` package
我编辑Cargo.toml
成这样:
[package]
name = "xxx"
version = "0.1.0"
authors = ["Martin Marconcini <xxx@xxx.com>"]
edition = "2018"
[dependencies]
git2 = "0.12.0"
并且main.rs
:
use git2::Repository;
fn main() {
println!("Hello, world!");
let repo = match Repository::open("fake/path") {
Ok(repo) => repo,
Err(e) => panic!("Failed to init {}", e),
};
}
问题
我知道fake/path
这行不通,但我希望程序在运行时能够构建、链接和恐慌。相反,当我进行货物运行时,这是我得到的:
$ cargo run
Updating crates.io index
Compiling libc v0.2.67
Compiling pkg-config v0.3.17
Compiling autocfg v1.0.0
Compiling smallvec v1.2.0
Compiling matches v0.1.8
Compiling bitflags v1.2.1
Compiling log v0.4.8
Compiling cfg-if v0.1.10
Compiling percent-encoding v2.1.0
Compiling openssl-probe v0.1.2
Compiling unicode-bidi v0.3.4
Compiling unicode-normalization v0.1.12
Compiling jobserver v0.1.21
Compiling idna v0.2.0
Compiling cc v1.0.50
Compiling url v2.1.1
Compiling libz-sys v1.0.25
Compiling openssl-sys v0.9.54
Compiling libssh2-sys v0.2.16
Compiling libgit2-sys v0.11.0+0.99.0
Compiling git2 v0.12.0
Compiling xxx v0.1.0 (/home/martin/dev/rust/xxx)
warning: unused variable: `repo`
--> src/main.rs:6:9
|
6 | let repo = match Repository::open("/fake/path") {
| ^^^^ help: consider prefixing with an underscore: `_repo`
|
= note: `#[warn(unused_variables)]` on by default
error: linking with `cc` failed: exit code: 1
|
= note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620.1g3apxivazecmby1.rcgu.o" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620.1ktaa7mhzl12qb8s.rcgu.o" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620.1of15nz9rghhwcp.rcgu.o" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620.1pzhxyvu6x3rpyd4.rcgu.o" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620.1xjrgwir8ul0gxyn.rcgu.o" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620.236nnnkop2p1q7o.rcgu.o" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620.346upd227a1u5o1x.rcgu.o" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620.4vpli3o8gp9bo7bb.rcgu.o" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620.fjvxd6ccfznqzmo.rcgu.o" "-o" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620" "/home/martin/dev/rust/xxx/target/debug/deps/xxx-fe6ac189d82a9620.2bpv5j881nolkdhg.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-nodefaultlibs" "-L" "/home/martin/dev/rust/xxx/target/debug/deps" "-L" "/home/martin/dev/rust/xxx/target/debug/build/libgit2-sys-9a380c1f1af1ff52/out/build" "-L" "/usr/lib/x86_64-linux-gnu" "-L" "/home/martin/dev/rust/xxx/target/debug/build/libssh2-sys-76c9f6db4b487643/out/build" "-L" "/usr/lib/x86_64-linux-gnu" "-L" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/home/martin/dev/rust/xxx/target/debug/deps/libgit2-e4070b896a12b23e.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/libopenssl_probe-02ad0051245c142f.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/liburl-752d8a16592303c8.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/libpercent_encoding-3f375297ed36a953.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/libidna-a849b89d54cc2589.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/libunicode_normalization-81788f9135a21d94.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/libsmallvec-e36b82e338fe18d3.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/libunicode_bidi-901a064d2af6777d.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/libmatches-ccee7833d11c4363.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/liblog-aba47d2dbe489265.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/libcfg_if-fd0f59c38961bb3a.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/liblibgit2_sys-b077f325e2a7224c.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/liblibssh2_sys-187467b0efb35c13.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/libopenssl_sys-b21cd1cefc781387.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/liblibz_sys-c72b1cae7b178c73.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/liblibc-a68ece9bb60c0ea2.rlib" "/home/martin/dev/rust/xxx/target/debug/deps/libbitflags-468acf5fe2f3e68a.rlib" "-Wl,--start-group" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-9d59e25e2eb2384d.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-4affccee0db9d60e.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-cd6b495608e342d1.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-347d88a586b28b4c.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace-46f3dc0b263b900a.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-6789aa6fbcfdf14c.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-9f9436f1ab051941.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-ad8ec269e6d86d01.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-3699f95d33475c27.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-fe798441633702e1.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-979288990efe6065.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-2181f1e1dd7399d7.rlib" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-b8952fd765001238.rlib" "-Wl,--end-group" "/home/martin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-e99fedbd2b621435.rlib" "-Wl,-Bdynamic" "-lz" "-lssl" "-lcrypto" "-lz" "-lutil" "-ldl" "-lutil" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
= note: /usr/bin/ld: /home/martin/dev/rust/xxx/target/debug/deps/liblibssh2_sys-187467b0efb35c13.rlib(libgcrypt.o): in function `_libssh2_rsa_new':
(.text+0x48): undefined reference to `gcry_sexp_build'
/usr/bin/ld: (.text+0x77): undefined reference to `gcry_sexp_build'
/usr/bin/ld: /home/martin/dev/rust/xxx/target/debug/deps/liblibssh2_sys-187467b0efb35c13.rlib(libgcrypt.o): in function `_libssh2_rsa_sha1_verify':
(.text+0xcb): undefined reference to `gcry_md_hash_buffer'
/usr/bin/ld: (.text+0xe8): undefined reference to `gcry_sexp_build'
/usr/bin/ld: (.text+0x103): undefined reference to `gcry_sexp_build'
/usr/bin/ld: (.text+0x118): undefined reference to `gcry_pk_verify'
/usr/bin/ld: (.text+0x123): undefined reference to `gcry_sexp_release'
/usr/bin/ld: (.text+0x12d): undefined reference to `gcry_sexp_release'
/usr/bin/ld: (.text+0x166): undefined reference to `gcry_sexp_release'
/usr/bin/ld: /home/martin/dev/rust/xxx/target/debug/deps/liblibssh2_sys-187467b0efb35c13.rlib(libgcrypt.o): in function `_libssh2_dsa_new':
(.text+0x1cc): undefined reference to `gcry_sexp_build'
/usr/bin/ld: (.text+0x203): undefined reference to `gcry_sexp_build'
/usr/bin/ld: /home/martin/dev/rust/xxx/target/debug/deps/liblibssh2_sys-187467b0efb35c13.rlib(libgcrypt.o): in function `_libssh2_rsa_sha1_sign':
(.text+0x73f): undefined reference to `gcry_sexp_build'
/usr/bin/ld: (.text+0x757): undefined reference to `gcry_pk_sign'
/usr/bin/ld: (.text+0x763): undefined reference to `gcry_sexp_release'
/usr/bin/ld: (.text+0x77d): undefined reference to `gcry_sexp_find_token'
/usr/bin/ld: (.text+0x79d): undefined reference to `gcry_sexp_nth_data'
/usr/bin/ld: /home/martin/dev/rust/xxx/target/debug/deps/liblibssh2_sys-187467b0efb35c13.rlib(libgcrypt.o): in function `_libssh2_dsa_sha1_sign':
(.text+0x87c): undefined reference to `gcry_sexp_build'
/usr/bin/ld: (.text+0x896): undefined reference to `gcry_pk_sign'
/usr/bin/ld: (.text+0x8a2): undefined reference to `gcry_sexp_release'
/usr/bin/ld: (.text+0x8d0): undefined reference to `gcry_sexp_find_token'
/usr/bin/ld: (.text+0x8f3): undefined reference to `gcry_sexp_nth_data'
/usr/bin/ld: (.text+0x937): undefined reference to `gcry_sexp_release'
/usr/bin/ld: (.text+0x946): undefined reference to `gcry_sexp_release'
/usr/bin/ld: (.text+0x985): undefined reference to `gcry_sexp_release'
/usr/bin/ld: (.text+0x998): undefined reference to `gcry_sexp_find_token'
/usr/bin/ld: (.text+0x9b2): undefined reference to `gcry_sexp_nth_data'
/usr/bin/ld: /home/martin/dev/rust/xxx/target/debug/deps/liblibssh2_sys-187467b0efb35c13.rlib(libgcrypt.o): in function `_libssh2_dsa_sha1_verify':
(.text+0xa62): undefined reference to `gcry_md_hash_buffer'
/usr/bin/ld: (.text+0xa84): undefined reference to `gcry_sexp_build'
/usr/bin/ld: (.text+0xab2): undefined reference to `gcry_sexp_build'
/usr/bin/ld: (.text+0xac9): undefined reference to `gcry_pk_verify'
/usr/bin/ld: (.text+0xad4): undefined reference to `gcry_sexp_release'
/usr/bin/ld: (.text+0xade): undefined reference to `gcry_sexp_release'
/usr/bin/ld: (.text+0xb16): undefined reference to `gcry_sexp_release'
/usr/bin/ld: /home/martin/dev/rust/xxx/target/debug/deps/liblibssh2_sys-187467b0efb35c13.rlib(libgcrypt.o): in function `_libssh2_cipher_init':
(.text+0xb5a): undefined reference to `gcry_cipher_get_algo_keylen'
/usr/bin/ld: (.text+0xb6c): undefined reference to `gcry_cipher_open'
/usr/bin/ld: (.text+0xb7f): undefined reference to `gcry_cipher_setkey'
/usr/bin/ld: (.text+0xba4): undefined reference to `gcry_cipher_get_algo_blklen'
/usr/bin/ld: (.text+0xbb8): undefined reference to `gcry_cipher_setiv'
/usr/bin/ld: (.text+0xbc5): undefined reference to `gcry_cipher_close'
/usr/bin/ld: (.text+0xbd1): undefined reference to `gcry_cipher_setctr'
/usr/bin/ld: /home/martin/dev/rust/xxx/target/debug/deps/liblibssh2_sys-187467b0efb35c13.rlib(libgcrypt.o): in function `_libssh2_cipher_crypt':
(.text+0xc02): undefined reference to `gcry_cipher_encrypt'
/usr/bin/ld: (.text+0xc11): undefined reference to `gcry_cipher_decrypt'
/usr/bin/ld: /home/martin/dev/rust/xxx/target/debug/deps/liblibssh2_sys-187467b0efb35c13.rlib(global.o): in function `libssh2_init':
(.text+0x38): undefined reference to `gcry_control'
collect2: error: ld returned 1 exit status
我已经在网上搜索了答案,但似乎大多数 git2-rs 结果甚至都没有谈论这个,这可能意味着我缺少
-dev
依赖项或其他东西。我已经看到了git2-rs 的官方 GitHub 存储库,并用 a 编译它
cargo build
并且它工作。已经运行了这两个命令:
$ pkg-config --libs openssl -lssl -lcrypto
和
$ pkg-config --cflags openssl
^ 这个没有产生我认为预期的输出。
我接下来看哪里?我的猜测是我缺少一个库,或者我拥有的版本不一样。
解决方案
我想通了(经过一些实验和运气)。
整个问题闻起来像是ld
git 使用 SSH 连接所需的 C libssl 库的链接过程的问题。
Pop!_OS 以包含许多“需要开发”的东西而闻名,所以我很肯定我拥有所有这些(我做到了)。
我是如何解决的?
我看了看/etc/ld.so.conf.d/
目录。那里有一些“.conf”文件。x86_64-linux-gnu.conf
指向/usr/lib/x86_64-linux-gnu
,所以我去那里看看哪些库匹配libssh*
。
我找到了这个:
$ ls -ls /usr/lib/x86_64-linux-gnu/libssh*
312 -rw-r--r-- 1 root root 316732 Sep 5 2019 libssh2.a
0 lrwxrwxrwx 1 root root 16 Sep 5 2019 libssh2.so -> libssh2.so.1.0.1
0 lrwxrwxrwx 1 root root 16 Sep 5 2019 libssh2.so.1 -> libssh2.so.1.0.1
184 -rw-r--r-- 1 root root 186856 Sep 5 2019 libssh2.so.1.0.1
1040 -rw-r--r-- 1 root root 1061468 Dec 10 16:24 libssh.a
0 lrwxrwxrwx 1 root root 22 Dec 10 16:24 libssh-gcrypt.so.4 -> libssh-gcrypt.so.4.8.1
552 -rw-r--r-- 1 root root 564760 Dec 10 16:24 libssh-gcrypt.so.4.8.1
0 lrwxrwxrwx 1 root root 11 Dec 10 16:24 libssh.so -> libssh.so.4
0 lrwxrwxrwx 1 root root 15 Dec 10 16:24 libssh.so.4 -> libssh.so.4.8.1
552 -rw-r--r-- 1 root root 564856 Dec 10 16:24 libssh.so.4.8.1
当将此输出与未出现此问题的新安装的 VM 进行比较时,我注意到libssh2*
VM 中不存在所有文件。
由于链接器错误都在 gcry 中(我认为代表cryPT
),我决定尝试删除这两个版本,只留下一个有效的版本:
$ sudo apt remove libssh2-1-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
libhttp-parser-dev libmbedtls-dev
Use 'sudo apt autoremove' to remove them.
The following packages will be REMOVED:
libgit2-dev libssh2-1-dev
0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
After this operation, 3,700 kB disk space will be freed.
Do you want to continue? [Y/n] y
(Reading database ... 412520 files and directories currently installed.)
Removing libgit2-dev:amd64 (0.27.7+dfsg.1-0.2build1) ...
Removing libssh2-1-dev:amd64 (1.8.0-2.1build1) ...
Processing triggers for man-db (2.8.7-3) ...
这样做之后,我得到了预期的输出:
$ cargo run
warning: unused variable: `repo`
--> src/main.rs:6:9
|
6 | let repo = match Repository::open("fakerepo") {
| ^^^^ help: consider prefixing with an underscore: `_repo`
|
= note: `#[warn(unused_variables)]` on by default
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/xxx`
Hello, world!
thread 'main' panicked at 'Failed to init failed to resolve path 'fakerepo': No such file or directory; class=Os (2); code=NotFound (-3)', src/main.rs:8:19
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
如果我初始化一个 git repo 并再次运行它,就没有错误,正如预期的那样:
$ mkdir fakerepo; cd fakerepo ; git init ; cd ..
Initialized empty Git repository in /home/martin/dev/rust/xxx/fakerepo/.git/
$ cargo run
warning: unused variable: `repo`
--> src/main.rs:6:9
|
6 | let repo = match Repository::open("fakerepo") {
| ^^^^ help: consider prefixing with an underscore: `_repo`
|
= note: `#[warn(unused_variables)]` on by default
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
Running `target/debug/xxx`
Hello, world!
看来问题是那个图书馆。我将进一步调查以了解它来自哪里(谁安装了它),更重要的是,如何使它成为一个非问题(必须有一种方法来告诉整个构建过程选择哪个库),但这是另一个问题改天。
我做了什么来发现这一点?
VM 技巧是我之前为解决其他问题所做的事情。Linux 在虚拟机上安装非常容易/快速,并且 Gnome Boxes 已经在我的 Pop!_OS 上安装和配置,所以我花了 1 分钟来启动它并在我面前有一个新安装的操作系统(好吧,它不是新鲜的,我必须在虚拟机中下载大约 150 个更新):)
无论如何,我安装了Peppermint OS 。一个超轻的基于 Ubuntu 的发行版,没有太多的障碍,所以它非常适合我的需求。我在 Peppermint OS 上需要做的就是:
sudo apt install pkg-config
sudo apt install libssl-dev
sudo apt install curl
(是的,它没有卷曲)- 安装 Rust (tl;dr:
curl https://sh.rustup.rs -sSf | sh
)
完成此操作后,我能够运行相同的 hello world 项目。当我意识到它正在这个 VM 上运行时,我也在一个 Pop!_OS 19.10 新安装的 VM 上再次这样做了。再一次,它奏效了。(这让我感到惊讶,因为我错误地归咎于“Pop_OS”)。
事实上,这在我很少输入的情况下在两个 VM 上都有效,这促使我继续在我的主机上尝试;我很高兴我做到了。
推荐阅读
- oauth-2.0 - Postman 如何在授权码流中获取 OAuth 2.0 auth token?
- ios - 为什么 UIAlertController 在等待答案时不暂停代码?
- python - 如何按间隔分隔数据框列并绘制
- c++ - arm-none-eabi/bin/ld:“.bss”部分不适合“RAM”区域
- html - 在移动菜单上显示链接标题
- python - 将排名最高的值传递给列表的函数
- python - 从函数中,如何将计算添加到列表中?
- r - 根据百分比制作数据子集
- asp.net-core - 通过中间件没有到达最后一个管道
- angular - 在 Angular 应用程序中多次重试请求