创建静态库时嵌入所有外部引用 [英] Embed all external references when creating a static library
问题描述
我需要为包装我的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包装代码)将所有这些文件合并到一个共享库中,链接需要的库,例如
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
- Compile all source code (including the C wrapping code) with
-fPIC
into*.pic.o
files 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屋!