1.《深入理解计算机系统》第七章链接
2.《程序员的自我修养》第4章 静态链接和第7章 动态链接
3. http://blog.jobbole.com/86852/
为了封装代码,简化接口,我们要把已有应用代码封装为动态链接库,应用代码又调用了其他库的文件,
为了减化编译配置,我们希望动态库直接调用其他库,固测试以下四种情况(含测试结论):
静态链接库本身不包含链接信息,在运行可执行程序时不需要静态库
动态链接库本身包含链接信息(U符号,不含T符号),在运行可执行程序时需要动态库(T符号)
ubuntu 16.04 64位
gcc(glibc 64位+32位)
调用关系,以下代码尽量简单明了,只为探索静态连接库和动态链接库的调用关系
#ifndef __FIRST_H_
#define __FIRST_H_
#include
void first();
#endif
#include"first.h"
void first()
{
printf("This is first!\n");
}
#ifndef __SECOND_H_
#define __SECOND_H_
#include
void second();
#endif
#include"first.h"
#include"second.h"
void second()
{
printf("This is second!\n");
first();
}
#include"second.h"
int main()
{
second();
return 0;
}
====================dynamic with static==========================test_ds only depends on libsecond.so
for 32bits linux we don't need -m32
for 64bits linux we need -m32
如果没有-m32 会产生错误:
relocation R_X86_64_32 against `.rodata' can not be used when making a shared object;
https://blog.csdn.net/bailyzheng/article/details/17613435
因为生成静态库时没有加 -fPIC 选项。,需要在生成静态库时加上-fPIC
=================================================================
gcc -m32 -c first.c
【生成】=>first.o
ar -crv libfirst.a first.o
=>libfirst.a
gcc second.c -m32 -fPIC -shared -o libsecond.so -L. -lfirst
=>libsecond.so
sudo gedit /etc/ld.so.conf.d/test.conf
---input absolute path of the dir of libsecond.so
sudo ldconfig
gcc test.c -m32 -o test_ds -L. -lsecond
=>test
./test_ds
=>
This is second!
This is first!
***********************
gcc -fPIC -c first.c
ar -crv libfirst.a first.o
gcc second.c -fPIC -shared -o libsecond.so -L. -lfirst
gcc test.c -o test_ds -L. -lsecond
./test_ds
***********************
======================static with static===================test_ss runs standalone
gcc -c first.c
ar -crv libfirst.a first.o
gcc -c second.c -L. -lfirst
ar -crv libsecond.a second.o
gcc test.c -L. -lsecond -lfirst -o test_ss
./test_ss
=>
This is second!
This is first!
【
nm libfirst.a
first.o:
0000000000000000 T first
U puts
nm libsecond.a
second.o:
U first
U puts
0000000000000000 T second
gcc test.c -L. -lsecond
./libsecond.a(second.o): In function `second':
second.c:(.text+0x14): undefined reference to `first'
collect2: error: ld returned 1 exit status
】
======================dynamic with dynamic===================test_dd depends on libfirst.so libsecond.so
gcc first.c -shared -fPIC -o libfirst.so
[
file libfirst.so
libfirst.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=6fe6c0444eb028ec73283d6016ed7ffb14e36238, not stripped
]
gcc second.c -shared -fPIC -o libsecond.so -L. -lfirst
gcc test.c -L. -lsecond -o test_dd
sudo gedit /etc/ld.so.conf.d/test.conf
---input absolute path of the dir of libsecond.so
sudo ldconfig
./test_dd
=>
This is second!
This is first!
【
nm libfirst.so
0000000000201028 B __bss_start
0000000000201028 b completed.7594
w __cxa_finalize@@GLIBC_2.2.5
00000000000005a0 t deregister_tm_clones
0000000000000630 t __do_global_dtors_aux
0000000000200e08 t __do_global_dtors_aux_fini_array_entry
0000000000201020 d __dso_handle
0000000000200e18 d _DYNAMIC
0000000000201028 D _edata
0000000000201030 B _end
00000000000006b4 T _fini
00000000000006a0 T first
0000000000000670 t frame_dummy
0000000000200e00 t __frame_dummy_init_array_entry
0000000000000748 r __FRAME_END__
0000000000201000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
00000000000006cc r __GNU_EH_FRAME_HDR
0000000000000548 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000200e10 d __JCR_END__
0000000000200e10 d __JCR_LIST__
w _Jv_RegisterClasses
U puts@@GLIBC_2.2.5
00000000000005e0 t register_tm_clones
0000000000201028 d __TMC_END__
nm libsecond.so
0000000000201030 B __bss_start
0000000000201030 b completed.7594
w __cxa_finalize@@GLIBC_2.2.5
00000000000005f0 t deregister_tm_clones
0000000000000680 t __do_global_dtors_aux
0000000000200df8 t __do_global_dtors_aux_fini_array_entry
0000000000201028 d __dso_handle
0000000000200e08 d _DYNAMIC
0000000000201030 D _edata
0000000000201038 B _end
0000000000000710 T _fini
U first
00000000000006c0 t frame_dummy
0000000000200df0 t __frame_dummy_init_array_entry
00000000000007a8 r __FRAME_END__
0000000000201000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
000000000000072c r __GNU_EH_FRAME_HDR
0000000000000588 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000200e00 d __JCR_END__
0000000000200e00 d __JCR_LIST__
w _Jv_RegisterClasses
U puts@@GLIBC_2.2.5
0000000000000630 t register_tm_clones
00000000000006f0 T second
0000000000201030 d __TMC_END__
】
======================static with dynamic===================test_sd depends nothing
gcc first.c -shared -fPIC -o libfirst.so
gcc -c second.c -L. -lfirst
ar crv libsecond.a second.o
gcc test.c -L. -lsecond【该静态链接库不能懈怠动态链接库的信息】
./libsecond.a(second.o): In function `second':
second.c:(.text+0x14): undefined reference to `first'
collect2: error: ld returned 1 exit status
gcc test.c -L. -lsecond -lfirst -o test_sd【works】
=>test_sd
./test_sd
=>
This is second!
This is first!