linux编译静态
你说的静态库和动态库吧?编译速度没有太大的区别,在实际运行时,静态库运行较快,而动态库内地函数由于在实际使用到时才加载到内存,所以运行较慢。动态库的好处是只要保持接口不变,就可以在程序运行时进行动态库的切换。
‘贰’ Linux下的静态链接库和动态链接库有什么区别
学习Linux动态链接库是一个绕不开的话题。动态链接库与静态链接库之间存在着显着的区别。静态链接库在编译链接时,将库文件的代码全部加入到可执行文件中,生成的文件较大,但运行时无需库文件。静态库后缀名为.a。相反,动态链接库在程序运行时才被载入内存,节省了资源,并解决了静态库在更新、部署和发布时的麻烦。动态库的后缀名为.so,gcc/g++在编译时默认使用动态库。
通过生成动态库的步骤,可以了解如何将多个文件编译成一个动态库。创建一个头文件和三个.cpp文件,然后将这几个文件编译成动态库libdynamic.so。通过命令行参数,-shared和-fPIC选项来生成动态链接库。在调用动态链接库时,使用链接命令来创建可执行文件,参数-L和-ldynamic用于查找库文件。
在测试链接时,可能会遇到ld提示找不到库文件的问题。解决方法之一是编辑/etc/ld.so.conf文件,添加库文件所在目录,并通过ldconfig更新缓存文件。静态库的编译过程同样重要,通过ar命令创建静态库文件,并使用nm命令查看文件内容。
动态链接库的优点在于进程间的资源共享,可以避免重复加载相同库函数,大大节省了系统的内存资源。C的标准库就是动态链接库,使得系统中所有运行的程序共享同一代码段。在编写程序时,可以选择何时链接动态链接库函数,根据需求进行加载,从而节省系统资源。
动态链接库在程序运行过程中根据需要加载特定功能,避免了一次性加载所有可能用到的函数,降低了内存占用。例如,在处理不同文件类型时,只在确定文件类型后才加载相应的读写函数,避免了未使用的函数占用内存。
总之,动态链接库和静态链接库在编译和运行时具有不同的特点和优势。选择何时使用动态链接库取决于具体应用需求和资源优化目标。理解两者之间的区别有助于更有效地利用资源,提高程序性能。
‘叁’ linux动态库和静态库的区别
静态库:这类库的名字一般是libxxx.a,xxx为库的名字。利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。
动态库:这类库的名字一般是libxxx.M.N.so,同样的xxx为库的名字,M是库的主版本号,N是库的副版本号。当然也可以不要版本号,但名字必须有。相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。linux系统有几个重要的目录存放相应的函数库,如/lib /usr/lib。
当要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。然而,对动态库而言,就不是这样。动态库会在执行程序内留下一个标记指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。
‘肆’ linux静态库和共享库的区别
linux下的库有两种:静态库和共享库(动态库)。二者的不同点在于代码被载入的时刻不同。
静态库在程序编译时会被连接到目标代码中,目标程序运行时将不再需要该动态库,移植方便,体积较大,但是浪费空间和资源,因为所有相关的对象文件与牵涉到的库被链接合成一个可执行文件。
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入,因此体积较小,可以实现进程间的资源共享,甚至可以真正做到链接载入完全由程序员在程序代码中控制,另外将一些程序的升级变得简单,但是在程序运行时需要动态库存在。
‘伍’ linux 静态库和动态库编译的区别
Linux库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。例如:libhello.so libhello.a
为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: libhello.so.1.0,由于程序连接默认以.so为文件后缀名。所以为了使用这些库,通常使用建立符号连接的方式。
ln -s libhello.so.1.0 libhello.so.1
ln -s libhello.so.1 libhello.so
动态库和静态库的区别:
当要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。然而,对动态库而言,就不是这样。动态库会在执行程序内留下一个标记‘指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。
两种库的编译产生方法:
第一步要把源代码编绎成目标代码。以下面的代码hello.c为例,生成hello库:
/* hello.c */
#include
void sayhello()
{
printf("hello,world\n");
}
用gcc编绎该文件,在编绎时可以使用任何全法的编绎参数,例如-g加入调试代码等:
gcc -c hello.c -o hello.o
1.连接成静态库
连接成静态库使用ar命令,其实ar是archive的意思
$ar cqs libhello.a hello.o
2.连接成动态库
生成动态库用gcc来完成,由于可能存在多个版本,因此通常指定版本号:
$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o
另外再建立两个符号连接:
$ln -s libhello.so.1.0 libhello.so.1
$ln -s libhello.so.1 libhello.so
这样一个libhello的动态连接库就生成了。最重要的是传gcc -shared 参数使其生成是动态库而不是普通执行程序。
-Wl 表示后面的参数也就是-soname,libhello.so.1直接传给连接器ld进行处理。实际上,每一个库都有一个soname,当连接器发现它正在查找的程序库中有这样一个名称,连接器便会将soname嵌入连结中的二进制文件内,而不是它正在运行的实际文件名,在程序执行期间,程序会查找拥有 soname名字的文件,%B
‘陆’ linux下使用nm指令查看静态库/动态库编译内容
在Linux环境下,当你遇到链接库问题时,深入理解库的编译内容变得尤为重要。这时,nm指令就成为一个有效的工具,帮助我们揭示静态库和动态库内的编译细节。
首先,对于静态库,我们可以使用命令
nm -g libname.a
执行后,如图所示,它会列出静态库中的全局变量和函数接口,让你清晰地看到库的内部结构。
而对于动态库,其查看方式为
nm -g libname.so
同样会显示出动态库的编译内容,包括函数和符号,这对于定位和修复与库相关的bug时非常有用。
因此,在链接第三方库或处理bug时,记得利用nm指令来记录和分析库的编译内容,它能提供宝贵的线索和信息。