原文链接
https://www.zhihu.com/question/22940048
作者:qin meng
链接:https://www.zhihu.com/question/22940048/answer/222625910
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
gcc使用-Wl
传递连接器参数,ld
使用-Bdynamic
强制连接动态库,-Bstatic
强制连接静态库。所以部分静态,部分动态连接这么写:
gcc ... -Wl,-Bstatic -l<your-static-lib> -Wl,-Bdynamic -l<your-dynamic-lib> ...
举个例子,你想静态连接libA.a
同时动态连接libB.so
,(先保证你的连接路径-L里面能找到对应的静态或者动态库),这么写:
gcc ... -Wl,-Bstatic -lA -Wl,-Bdynamic -lB ...
这里需要注意,强制静态或者动态连接标记之后的链接库都将按照前面最近的一个标记进行链接,所以如果后面出现了一个libC
,没有指定连接标记,那么libC
将会被动态连接:
gcc ... -Wl,-Bstatic -lA -Wl,-Bdynamic -lB ... -lC
如果参数里面没指定强制的连接方式标记,那么gcc
将按照默认的优先级去链接,优先动态链接,所以如果你这么写,且同时存在libC.so
和libC.a
那么libC
将被动态链接:
gcc ... -lC
由于-B
连接标记会改变默认连接方式,所以在Makefile
里面如果有人这么干:
LIBS += -Wl,-Bstatic -lC
那么他后面的LIBS+=
的库就都只能以静态方式连接了,有时候这是不行的,因为没有静态库,所以会有人这么应对:
LIBS += -Wl,-Bdynamic -lD
这样就改回来了。但是这种胡乱改的行为是非常不好的,比较好的行为应该这样:
LIBS += -l<auto-link-lib> STATIC_LIBS += -l<static-lib> DYN_LIBS += -l<dynamic-lib> LDFLAGS := ${LIBS} -Wl,-Bstatic ${STATIC_LIBS} -Wl,-Bdynamic ${DYN_LIBS}
这样当你不关心怎么连接的时候用LIBS,当你想静态连接的时候用STATIC_LIBS,当你想动态连接的时候用DYN_LIBS。
作者:杨博东
链接:https://www.zhihu.com/question/22940048/answer/250351399
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
最高票qin meng的答案我编译出现这个错误:
/usr/bin/ld: cannot find -lgcc_s /usr/bin/ld: cannot find -lc /usr/bin/ld: cannot find -lgcc_s collect2: error: ld returned 1 exit status
然后搜到了gcc
参数加上 -Wl,-Bdynamic -lgcc_s
可以解决,最后我强制链接静态链接libfunc.a
(我的目录下同时有 libfunc.a
和 libfunc.so
):
gcc main.c -Wl,-Bstatic -lfunc -L. -Wl,-Bdynamic -lgcc_s
有关 gcc_s : https://gcc.gnu.org/onlinedocs/gccint/Libgcc.html
还有一种方法是直接指定静态链接的库全名:
gcc main.c -l:libfunc.a -L // 这样也是静态链接libfunc.a