linux - 创建静态库时嵌入所有外部引用

标签 linux gcc shared-libraries static-libraries ld

我需要为 C 代码创建一个包装器库来包装我的 C++ 库。有没有办法以这样的方式创建包装器库,即用户只需要链接此包装器库,而不必在链接器命令行上包含所有(C++)库?

我的测试项目的结构如下所示:

.
├── lib
│   ├── cpp
│   │   ├── print.cc
│   │   └── print.h
│   ├── lib.cc
│   ├── lib.h
└── main.c

main.c 是使用我的库的示例 C 应用程序。 lib.h 和 lib.cc 文件是包含 C 绑定(bind)的包装器库。我的 C++ 库位于 cpp 子文件夹中。

目前我通过使用以下命令链使其工作:

cd lib
g++ -c lib.cc
ar rcs libib.a lib.o
cd ..
gcc -Ilib -Llib main.c -lib -lstdc++

但是,正如您所看到的,用户的链接器步骤需要包含我的 C++ 库中使用的 C++ 库。在本例中为 libstdc++.so(如果使用 -static,则为 libstdc++.a)。

我想将所有 C++ 库包含在我的 libib.a 中,以便用户可以简单地使用以下命令进行编译:

gcc -Ilib -Llib main.c -lib

最佳答案

在 Linux 上,共享库可以通过链接其中的其他共享库来创建。所以你可以

  1. 使用 -fPIC 将所有源代码(包括 C 包装代码)编译为 *.pic.o 文件
  2. 将所有这些文件合并到链接所需库的共享库中,例如

    g++ -shared *.pic.o -o libmy.so -lQt -lrt -lstdc++

然后你可以简单地使用你的libmy.so作为gcc main.o -L。 -lmy 这将链接其他库。

例如查看 Parma Polyhedra Library ,它有一个 C 语言的 libppl_c.so ,包装了 C++ 语言的 libppl.so 。使用ldd列出依赖库:

 % ldd /usr/lib/x86_64-linux-gnu/libppl_c.so.4
linux-vdso.so.1 =>  (0x00007fffa17cf000)
libppl.so.9 => /usr/local/lib/libppl.so.9 (0x00007fcfec5f1000)
libpwl.so.5 => /usr/local/lib/libpwl.so.5 (0x00007fcfec3ed000)
libgmpxx.so.4 => /usr/lib/x86_64-linux-gnu/libgmpxx.so.4 (0x00007fcfec1c5000)
libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fcfebf56000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fcfebc4f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fcfeb9cc000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcfeb645000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fcfeb42f000)
libgmp.so.3 => /usr/lib/libgmp.so.3 (0x00007fcfeb1d2000)
/lib64/ld-linux-x86-64.so.2 (0x00007fcfecf11000)

这是在 Debian/Sid/AMD64 上

一般建议是避免构建静态库(使用 ar 和可能的 ranlib)。相反,构建共享库。

您无法对静态库执行相同的操作,因为静态库只是一系列目标文件,仅此而已。 (没有元数据空间来存放您梦想的依赖信息)。

关于linux - 创建静态库时嵌入所有外部引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12195000/

相关文章:

c - 无效读取大小 4 错误 C 编程

c - 无法使用命令提示符执行 SSH\

c++ - g++ 不产生调试符号

linux - 漂亮的递归目录和文件打印

c - 如何找到文件系统 block 大小?

linux - 我可以在Linux中编辑GCC的打印输出吗?

android - 如何在 Ubuntu 中使用 Android 共享库

linker - 为什么不能像静态链接一样将 DLL 与 EXE 结合起来?

c - 用于大小分析的 GCC 工具?

通过 Eclipse CDT 创建共享库