linux 生成库,linux软件安装包
其实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如何解决动态库的版本控制
3.共享库,小版本升级,即接口不变.
当升级小版本时,共享库的soname是不变的,所以需要重新把soname的那个连接文件指定新版本就可以。调用ldconfig命令,系统会帮你做修改那个soname link文件,并把它指向新的版本呢。这时候你的应用程序就自动升级了。
4.共享库,主版本升级,即接口发生变化。
当升级主版本时,共享库的soname就会加1.比如libhello.so.0.0.0变为 libhello.so.1.0.0.这时候再运行ldconfig文件,就会发现生成两个连接文件。
ln-s libhello.so.0----libhello.so.0.0.0
ln-s libhello.so.1-----libhello.so.1.0.0
尽管共享库升级,但是你的程序依旧用的是旧的共享库,并且两个之间不会相互影响。
问题是如果更新的共享库只是增加一些接口,并没有修改已有的接口,也就是向前兼容。但是这时候它的主版本号却增加1.如果你的应用程序想调用新的共享库,该怎么办?简单,只要手工把soname文件修改,使其指向新的版本就可以。(这时候ldconfig文件不会帮你做这样的事,因为这时候soname和real name的版本号主板本号不一致,只能手动修改)。
比如: ln-s libhello.so.0--- libhello.so.1.0.0
但是有时候,主版本号增加,接口发生变化,可能向前不兼容。这时候再这样子修改,就会报错,“xx”方法找不到之类的错误。
总结一下,Linux系统是通过共享库的三个不同名字,来管理共享库的多个版本。 real name就是共享库的实际文件名字,soname就是共享库加载时的用的文件名。在生成共享库的时候,编译器将soname绑定到共享库的文件头里,二者关联起来。在应用程序引用共享库时,其通过link name来完成,link时将按照系统指定的目录去搜索link名字找到共享库,并将共享库的soname写在应用程序的头文件里。当应用程序加载共享库时,就会通过soname在系统指定的目录(path or LD_LIBRARY)去寻找共享库。
当共享库升级时,分为两种。一种是主板本不变,升级小版本和build号。在这种情况下,系统会通过更新soname( ldconfig来维护),来使用新的版本号。这中情况下,旧版本就没有用,可以删掉。
另外一种是主版本升级,其意味着库的接口发生变化,当然,这时候不能覆盖已有的soname。系统通过增加一个soname(ldconfig-p里面增加一项),使得新旧版本同时存在。原有的应用程序在加载时,还是根据自己头文件的旧soname去寻找老的库文件。
这是一个trick的地方。第一系统将会在生成库的时候,就没有soname放到库的头里面。从而应用程序连接时候,就把linkname放到应用程序依赖库里面。或者换句话说就是,soname这时候不带版本号。有时候有人直接利用这点来升级应用程序,比如,新版本的库,直接拷贝到系统目录下,就会覆盖掉已经存在的旧的库文件,直接升级。这个给程序员很大程度的便利性,如果一步小心,就会调到类似windows的Dll hell陷阱里面。建议不要这样做。
【Note】
1.指定共享库加载的路径。LD_LIBRARY_PATH优先于 path环境变量。
2. ldd可以查看程序,或者共享库依赖的库的路径
3. nm查看共享库暴露的接口
4. ldconfig可以自动生成soname的连接文件。并提供catch加速查找。
5.readelf可以查看动态库的信息,比如依赖的库,本身的soname。
6. objdump与readelf类似。
7 ld The GUN linker
8. ld.so dynamic linker or loader
9. as the portable GNU assembley
Linux环境下搭建composer私服及memory_limit问题
介绍如何在Linux环境下搭建Composer私有服务器,解决memory_limit问题。
在开始前,先熟悉Composer相关操作。
安装步骤如下:
1.访问Composer下载页面获取安装命令。
2.常见用法包括安装、更新和卸载包。
搭建步骤:
1.创建项目文件夹。
2.配置satis.json文件,定义私有仓库。
3.执行构建命令生成仓库。
4.配置NGINX服务器。
在NGINX配置文件中,确保PHP和php-fpm安装并启动。
搭建完成后,通过访问/composer.xxx.com>即可使用私有仓库。
在项目配置中,将私有Composer源添加到composer.json文件中。
发布过程中遇到内存限制问题,常见原因包括:
1.开发者未在个人电脑配置公共Composer源。
2.项目中同时配置了公共和私有源。
3.执行composer install时出现内存不足错误。
解决方案包括:
1.修改composer install命令为php-d memory_limit=-1/usr/local/bin/composer install。
2.在项目配置中删除第三方公共源。
核心问题可能是第三方源的重复依赖,而非内存限制。配置源时应考虑优先级问题。
关于Composer版本管理,可以设置软连接或使用特定命令。
若有疑问或建议,请随时分享。