创建静态库时嵌入所有外部引用 [英] Embed all external references when creating a static library

查看:135
本文介绍了创建静态库时嵌入所有外部引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为包装我的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 ++。a if -static)。



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

  gcc -Ilib -Llib main.c -lib 


解决方案

在Linux上,共享库可以通过链接其他共享库。所以你可以使用 -fPIC 编译所有的源代码(包括C包装代码)将所有这些文件合并到一个共享库中,链接需要的库,例如 <.c $ c> *。pic.o files / p>

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


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



Parma Polyhedra Library ,它在C中包含一个 libppl_c.so ,包装一个 libppl.so 在C ++中。使用 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 )。改为建立共享库。



你不能在静态库上做同样的事情,因为静态库仅仅是一系列对象文件,仅此而已。 (你梦想的依赖信息没有元数据空间)。

I need to create a wrapper library for C code that wraps my C++ library. Is there a way to create that wrapper library in such a way, that the user needs to link only this wrapper library and doesn't have to include all the (C++) libraries on the linker command line as well?

The structure of my test project looks like this:

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

The main.c is an example C application that uses my library. The lib.h and lib.cc files are the wrapper library containing the C bindings. My C++ library resides in the cpp subfolder.

At the moment I have it working by using the following chain of commands:

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

However, as you can see the linker step of the user needs to include the C++ libraries used in my C++ library. In this case the libstdc++.so (or libstdc++.a if -static is used).

I'd like to include all C++ libraries in my libib.a such that the user can simply use the following command for compilation:

gcc -Ilib -Llib main.c -lib

解决方案

On Linux, shared libraries can be made by also linking other shared libraries inside them. So you could

  1. Compile all source code (including the C wrapping code) with -fPIC into *.pic.o files
  2. Merge all these files into a shared library linking needed libraries, e.g.

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

Then you can use simply your libmy.so as gcc main.o -L. -lmy and this will link the other libraries.

Look for example at Parma Polyhedra Library, it has a libppl_c.so in C wrapping a libppl.so in C++. Use ldd to list the dependent libraries:

 % 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)

This is on Debian/Sid/AMD64

A general advice is to avoid building static libraries (using ar and possibly ranlib). Build shared libraries instead.

You cannot do equivalent things on static libraries because a static library is simply a sequence of object files, nothing more. (there is no metadata space for the dependency information you dream about).

这篇关于创建静态库时嵌入所有外部引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆