gcc - 带有未定义符号的静态库?

gcc - A static library with undefined symbols?

我正在尝试使用静态库构建项​​目,这样即使未安装该库也可以使用二进制文件。但是,当我尝试这样做时,我遇到了很多关于未定义符号的错误。

查看库,我发现它有大量未定义的符号,即使它是 .a 静态库:

nm - u /usr/local/lib/libthis.a
....
U EVP_DigestFinal_ex
U EVP_DigestInit_ex
U EVP_DigestUpdate
U EVP_MD_CTX_cleanup
U EVP_MD_CTX_init

那些似乎来自openssl;其他人似乎来自 libbzip2;等等

问题: 1. 为什么静态 (.a) 库依赖于非静态编译的共享对象(例如 libopenssl)? 2.我该如何解决?尝试手动添加 -lssl 似乎不起作用。如何让二进制文件编译并且没有外部依赖?

Why does the static (.a) lib have dependencies on shared objects (e.g. libopenssl) that aren't statically compiled?

几乎您可以构建的每个 静态库都会有未解析的符号,例如

int my_open_for_read(const char *filename)
{
  return open(filename, O_RDONLY);  // unresolved reference to open
}

正如 Marc Glisse 指出的那样,这是一个普通的未解析符号,不是libc.so.

的依赖
  1. How do I solve this?

这里没有问题可以解决。当您 link 您的二进制文件时,您可以决定静态 link 哪些库,动态 link 哪些库。

Trying to manually add -lssl doesn't seem to work.

这应该有效:

gcc main.o -lthis -lssl

可能你做了类似

的事情
gcc main.o -lssl -lthis

这是错误的:link 行 matters.

上的库顺序

How do I get the binary to compile and not have external dependcies?

大多数操作系统都支持使用完全静态的二进制文件。一般来说,这应该 是你的目标:它使得 less 可移植二进制文件,强烈建议不要使用它们。

如果你真的想生成一个完全静态的二进制文件,link 它带有 -static 标志。

Why do you say full static is less portable?

因为they are.

if the user doesn't have the exact same build of the lib, the binary won't be portable with shared libs, but will be portable with static.

这是不正确的:大多数共享库都支持向后兼容,例如libc.so.6 版本 2.22 将愉快地 运行 可执行文件 link 针对 10 年前的版本 2.3.6。

If you do ldd firefox

你在做什么需要注意:

file -L `which /usr/bin/firefox`
/usr/bin/firefox: POSIX shell script, ASCII text executable

如果您查看 shell 脚本,您会发现它调用 /usr/lib/firefox/firefox,并且该二进制文件是动态 linked:

ldd /usr/lib/firefox/firefox
    linux-vdso.so.1 =>  (0x00007ffca278d000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f511731b000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f5117117000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f5116e13000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5116b0d000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f51168f7000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5116532000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f5117757000)