gcc 混合连接动态库和静态库

本文详细介绍了GCC环境下如何混合使用动态库与静态库,包括建库、编译、链接过程中的关键步骤及常见错误处理方法。重点强调了使用-Wl,-Bstatic与-Wl,-Bdynamic参数的重要性,以及如何正确配置参数以实现动态库与静态库的灵活组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我记得静态库混合动态库要加特殊指令的,你可以试试这样:
gcc -g -lstdc++ -g -WI,-Bdynamic -L. -lmy  -WI,-Bstatic -L. -lmy -o test.exe main.cc

 

http://www.cnblogs.com/diyunpeng/archive/2011/06/16/2083085.html

GCC动态库和静态库混合使用

今天,一个同事编译静态库,我也趁此机会在温习一下,先google一下,然后在自己实验。

首先,在网上抄个例子,内容如下:

复制代码
:建静态库
/*   hellos.h  */
#ifndef _HELLO_S_H
#define _HELLO_S_H

void printS( char * str);

#endif

/*   hellos.c  */
#include
" hellos.h "

void printS( char * str) {
  printf(
" print in static way: %s " , str);
}

输入命令:
gcc
- c - o hellos.o hellos.c
ar cqs libhellos.a hellos.o
于是得到了 libhellos.a这么一个静态链接库

:主程序
/*   main.c  */
#include
< stdio.h >
#include
" hellos.h "

main() {
 
char * text = " Hello World!\n " ;
  printS(text);
}
编译链接:
gcc
- o hello main.c - static - L. - lhellos
然后运行hello可以看到输出
print
in static way: Hello World !
删除 libhellos.a和 hellos.
* 后, 程序仍然正常运行。
复制代码
下面再来看 动态链接
:建动态库
/*   hellod.h  */
#ifndef _HELLO_D_H
#define _HELLO_D_H

void printD( char * str);

#endif

/*   hellod.c  */
#include
" hellod.h "

void printD( char * str) {
  printf(
" print in dynamic way: %s " , str);
}

输入命令:
gcc
- shared - o libhellod.so hellod.c
于是得到了 libhellod.so 这么一个动态链接库

: 主程序
/*   main.c  */
#include
< stdio.h >
#include
" hellod.h "

main() {
 
char * text = " Hello World!\n " ;
  printD(text);
}
编译链接:
gcc
- o hello main.c - L. - lhellod
复制代码
复制代码

原文中存在一定错误,我已经修订,并且最会运行的话,需要设置动态库执行路径

否则出现下述错误:

  ./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory

当设定了LD_LIBRARY_PATH或者放在/usr/lib和/lib后,又出现下面的错误:

   ./hello: error while loading shared libraries: /usr/lib/libhello.so: cannot restore segment prot after reloc: Permission denied

这是SELinux引起的,修改如下:

chcon -t texrel_shlib_t /usr/lib/libhello.so

之后,运行,OK。

下面说一下混合编程:

复制代码
/*   main.c  */
#include
< stdio.h >
#include
" hellos.h "
#include
" hellod.h "

main() {
 
char * text = " Hello World!\n " ;
  printS(text);
  printD(text);
}
复制代码

上面的文章又说错了,自己google一下,某人如下说:

在应用程序需要连接外部库的情况下,linux默认对库的连接是使用动态库,在找不到动态库的情况下再选择静态库。使用方式为:

gcc test.cpp -L. -ltestlib

如果当前目录有两个库libtestlib.so libtestlib.a 则肯定是连接libtestlib.so。如果要指定为连接静态库则使用:

gcc test.cpp -L. -static -ltestlib

使用静态库进行连接。

当对动态库与静态库混合连接的时候,使用-static会导致所有的库都使用静态连接的方式。这时需要作用-Wl的方式:

gcc test.cpp -L. -Wl,-Bstatic -ltestlib  -Wl,-Bdynamic -ltestlib

【本段文字来自:http://blog.youkuaiyun.com/lapal/archive/2010/04/13/5482277.aspx

在转他说的:http://blog.youkuaiyun.com/tenfyguo/archive/2010/07/15/5737974.aspx

至此,解决该类问题。

附带几篇不错的文章:

http://blog.163.com/xychenbaihu@yeah/blog/static/13222965520101023104745738/

http://www.cublog.cn/u3/119070/showart_2379190.html

http://blog.youkuaiyun.com/tenfyguo/archive/2010/07/15/5737974.aspx

http://www.linuxeden.com/html/develop/20100326/94297.html

http://blog.youkuaiyun.com/JsuFcz/archive/2009/11/07/4784038.aspx『pS:这小子的文章前面的还好,后面可给我害惨了】

 

http://blog.youkuaiyun.com/lapal/article/details/5482277

 

 

在应用程序需要连接外部库的情况下,linux默认对库的连接是使用动态库,在找不到动态库的情况下再选择静态库。使用方式为:

gcc test.cpp -L. -ltestlib

如果当前目录有两个库libtestlib.so libtestlib.a 则肯定是连接libtestlib.so。如果要指定为连接静态库则使用:

gcc test.cpp -L. -static -ltestlib

使用静态库进行连接。

当对动态库与静态库混合连接的时候,使用-static会导致所有的库都使用静态连接的方式。这时需要作用-Wl的方式:

gcc test.cpp -L. -Wl,-Bstatic -ltestlib  -Wl,-Bdynamic -ltestlib

另外还要注意系统的运行库使用动态连接的方式,所以当动态库在静态库前面连接时,必须在命令行最后使用动态连接的命令才能正常连接

,如:

gcc test.cpp -L. -Wl,-Bdynamic -ltestlib -Wl,-Bstatic -ltestlib  -Wl,-Bdynamic

 

http://blog.sina.com.cn/s/blog_4cb133e5010009zx.html

关于GCC中同时使用动态和静态库链接的操作参数和解释

作者:梁华勇

在我们开发的一个系统中,由于动态链接其中的一个动态库时,编译时没有问题,而运行时不能进行,如果将该库静态连接时,运行却没有问题。具体什么原因,一直没有搞清楚,权且当作暂时的解决办法。
如何同时 同时使用动态和静态库链接,同事周楠提供了一个参数的用法,在GCC指令参数中具体参数如下:
-Wl,-Bstatic -L/usr/local/sqlite-arm-linux/.libs -lsqlite -Wl,-Bdynamic -L/usr/local/arm/3.3.2/lib
具体用途解释:sqlite库静态连接,其它库动态连接。
-Wl,-Bstatic 与-Wl,-Bdynamic参数,从字面意义上可以理解,有静态和动态的意思,但是具体的真正规则在查找了GCC的原版手册上有说明。
原文:

Note - if the linker is being invoked indirectly, via a compiler driver (eg gcc) then all the linker command line options should be prefixed by -Wl, (or whatever is appropriate for the particular compiler driver) like this:

 gcc -Wl,--startgroup foo.o bar.o -Wl,--endgroup

This is important, because otherwise the compiler driver program may silently drop the linker options, resulting in a bad link.

实际上主要针对隐式应用LINKER的参数,用“-Wl,”来标识,,“--startgroup foo.o bar.o -Wl,--endgroup”表示一组,,-Bstatic -Bdynamic 作为关键字与-WL,不可分,在GCC连接库时,默认链接是动态链接,现在用上面的指令限制在链接sqlite库时采用静态链接。

-Bstatic 还有三个写法: -dn和-non_shared 和-static

-Bdynamic 还有两个写法:-dy-call_shared

上面参数“-L/usr/local/sqlite-arm-linux/.libs ”放不放在-Wl,...之间无所谓,因为它只是提供了sqlite动静态库的位置。可以改成下面的参数形式,更直观。

-L/usr/local/sqlite-arm-linux/.libs -L/usr/local/arm/3.3.2/lib -Wl,-dn -lsqlite -Wl,-dy

-Wl,-dn 和 -Wl,-dy成对出现才能起到标题所说的作用。

关于-Wl,后面的参数还有很多,全部明白我也不能。

还有一个问题值得注意,在-Wl,后面不能有空格,否则会出错!

关于-Wl,option 说明还有一段说明

GCC命令参数的英文原文

-Wl,option

Pass option as an option to the linker. If option contains commas, it is split into multiple options at the commas.

传递参数option作为linker的一个参数,如果option包含逗号,将在逗号处分割成几个参数。

例如:

-Wl,-dn –lsqlite

-dn 开始静态链接

-lsqlite 静态链接sqlite库

静态链接完后,然后需要动态链接

-Wl,-dy

重新开始动态链接。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值