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

时间:2012-08-30 10:38:42

标签: 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绑定的包装器库。我的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(或libstdc ++。使用if -static)。

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

gcc -Ilib -Llib main.c -lib

1 个答案:

答案 0 :(得分:0)

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

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

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

  3. 然后,您只需将libmy.so用作gcc main.o -L. -lmy,这将链接其他库。

    Parma Polyhedra Library查找示例,它在C中包含libppl_c.so的{​​{1}}。使用libppl.so列出依赖库:

    ldd

    这是在Debian / Sid / AMD64

    一般建议是避免构建静态库(使用 % 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) 和可能ar)。改为构建共享库。

    你不能在静态库上做同等的事情,因为静态库只是一个目标文件序列,仅此而已。 (您梦寐以求的依赖关系信息没有元数据空间。)