位置: 编程技术 - 正文

理解 pkg-config 工具(linux编译辅助工具)(pkg-config命令)

编辑:rootadmin

推荐整理分享理解 pkg-config 工具(linux编译辅助工具)(pkg-config命令),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:pkg_config,pkg-config search path,pkg_prog_pkg_config,pkgconfig的使用,pkg_prog_pkg_config,pkg_config_path,pkg_config_path,pkg_config_libdir,内容如对您有帮助,希望把文章链接给更多的朋友!

你在 Unix 或 Linux 下开发过软件吗?写完一个程序,编译运行完全正常,在你本机上工作得好好的,你放到源代码管理系统中。然后,告诉你的同事说,你可以取下来用了。这时,你长长的出了一口气,几天的工作没有白费,多么清新的空气啊,你开始飘飘然了。

“Hi,怎么编译不过去?”你还沉浸在那种美妙的感觉之中,双臂充满着力量,似乎没有什么问题能难倒你的。正在此时,那个笨蛋已经冲着你嚷开了。

“不会吧,我这边好好的!”表面上你说得很客气,其实,你心里已经骂开了,真笨,不知道脑子干嘛用的。也许,你想的没错,上次,他犯了一个简单的错误,不是你一去就解决了吗。

他喊三次之后,你不得不放下你手上的工作,刚才那种美妙的感觉已经消失得无影无踪了,要不是你把情绪控制得很好,一肚子气就要撒在他身上了。你走到他的电脑前,键入 make,优雅的按下回车。怎么可能出错呢?你信心十足。然而,屏幕上的结果多少有点让人脸红,该死的,libxxx.so 怎么会让不到呢?

你在/usr目录中查找 libxxx.so,一切都逃不过你的眼睛。奇怪,libxxx.so 怎么在 /usr/local/lib 下,不是应该在 /usr/lib 下的吗?这你可不能怪别人,别人想安装在哪里都行,下次还可能安装到 /lib 目录下呢。

以上的场景并非虚构,我都经历过好几次,明明在本机上好好的,在别人的机器上连编译都过不去。可能两人的操作系统一模一样,需要的库都安装上,只是由于个人 喜好不同,安装在不同的目录而已。遇到这种情况,每次都技巧性的绕过去了,用的补丁型的方法,心里老惦记其它地方能不能工作。

今天我们要介绍的 pkg-config,为解决以上问题提供了一个优美方案。从此,你再也不为此担忧了。pkg-config提供了下面几个功能:

检查库的版本号。如果所需要的库的版本不满足要求,它会打印出错误信息,避免链接错误版本的库文件。 获得编译预处理参数,如宏定义,头文件的位置。 获得链接参数,如库及依赖的其它库的位置,文件名及其它一些连接参数。 自动加入所依赖的其它库的设置。 这一切都自动的,库文件安装在哪里都没关系!

在使用前,我们说说 pkg-config 的原理,pkg-config 并非精灵,可以凭空得到以上信息。事实上,为了让pkg-config可以得到这些信息,要求库的提供者,提供一个.pc文件。比如gtk+-2.0的pc文件内容如下:

复制代码代码如下:prefix=/usrexec_prefix=/usrlibdir=/usr/libincludedir=/usr/includetarget=x</p><p>gtk_binary_version=2.4.0gtk_host=i-redhat-linux-gnu</p><p>Name: GTK+Description: GIMP Tool Kit (${target} target)Version: 2.6.7Requires: gdk-${target}-2.0 atkLibs: -L${libdir} -lgtk-${target}-2.0Cflags: -I${includedir}/gtk-2.0

这个文件一般放在 /usr/lib/pkgconfig/ 或者 /usr/local/lib/pkgconfig/ 里,当然也可以放在其它任何地方,如像 X 相关的pc文件是放在 /usr/XR6/lib/pkgconfig 下的。为了让pkgconfig可以找到你的pc文件,你要把pc文件所在的路径,设置在环境变量 PKG_CONFIG_PATH 里。

使用 pkg-config 的 –cflags 参数可以给出在编译时所需要的选项,而 –libs 参数可以给出连接时的选项。例如,假设一个 sample.c 的程序用到了 Glib 库,就可以这样编译:复制代码代码如下:$ gcc -c `pkg-config –cflags glib-2.0` sample.c然后这样连接:复制代码代码如下:$ gcc sample.o -o sample `pkg-config –libs glib-2.0`或者上面两步也可以合并为以下一步:复制代码代码如下:$ gcc sample.c -o sample `pkg-config –cflags –libs glib-2.0`可以看到:由于使用了 pkg-config 工具来获得库的选项,所以不论库安装在什么目录下,都可以使用相同的编译和连接命令,带来了编译和连接界面的统一。使用 pkg-config 工具提取库的编译和连接参数有两个基本的前提:

库本身在安装的时候必须提供一个相应的 .pc 文件(不这样做的库说明不支持 pkg-config 工具的使用)。 pkg-config 必须知道要到哪里去寻找此 .pc 文件。 GTK+ 及其依赖库支持使用 pkg-config 工具,所以剩下的问题就是如何告诉 pkg-config 到哪里去寻找库对应的 .pc 文件,这也是通过设置搜索路径来解决的。

对于支持 pkg-config 工具的 GTK+ 及其依赖库来说,库的头文件的搜索路径的设置变成了对 .pc 文件搜索路径的设置。.pc 文件的搜索路径是通过环境变量 PKG_CONFIG_PATH 来设置的,pkg-config 将按照设置路径的先后顺序进行搜索,直到找到指定的 .pc 文件为止。

安装完 Glib 后,在 bash 中应该进行如下设置:复制代码代码如下:$ export PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig:$PKG_CONFIG_PATH可以执行下面的命令检查是否 /opt/gtk/lib/pkgconfig 路径已经设置在 PKG_CONFIG_PATH 环境变量中:复制代码代码如下:$ echo $PKG_CONFIG_PATH

这样设置之后,使用 glib 库的其它程序或库在编译的时候 pkg-config 就知道首先要到 /opt/gtk/lib/pkgconfig 这个目录中去寻找 glib-2.0.pc 了(GTK+ 和其它的依赖库的 .pc 文件也将拷贝到这里,也会首先到这里搜索它们对应的 .pc 文件)。之后,通过 pkg-config 就可以把其中库的编译和连接参数提取出来供程序在编译和连接时使用。

另外还需要注意的是:环境变量的设置只对当前的终端窗口有效。如果到了没有进行上述设置的终端窗口中,pkg-config 将找不到新安装的 glib-2.0.pc 文件、从而可能使后面进行的安装(如 glib 之后的 Atk 的安装)无法进行。

理解 pkg-config 工具(linux编译辅助工具)(pkg-config命令)

在我们采用的安装方案中,由于是使用环境变量对 GTK+ 及其依赖库进行的设置,所以当系统重新启动、或者新开一个终端窗口之后,如果想使用新安装的 GTK+ 库,需要如上面那样重新设置 PKG_CONFIG_PATH 和 LD_LIBRARY_PATH 环境变量。

这种使用 GTK+ 的方法,在使用之前多了一个对库进行设置的过程。虽然显得稍微繁琐了一些,但却是一种最安全的使用 GTK+ 库的方式,不会对系统上已经存在的使用了 GTK+ 库的程序(比如 GNOME 桌面)带来任何冲击。

为了使库的设置变得简单一些,可以把下面的这两句设置保存到一个文件中(比如 set_gtk-2. 文件):

复制代码代码如下:export PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig:$PKG_CONFIG_PATHexport LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH

之后,就可以用下面的方法进行库的设置了(其中的 source 命令也可以用 . 代替):

复制代码代码如下:$ source set_gtk-2.

只有在用新版的 GTK+ 库开发应用程序、或者运行使用了新版 GTK+ 库的程序的时候,才有必要进行上述设置。

如果想避免使用 GTK+ 库之前上述设置的麻烦,可以把上面两个环境变量的设置在系统的配置文件中(如 /etc/profile)或者自己的用户配置文件中(如 ~/.bash_profile) ;库的搜索路径也可以设置在 /etc/ld.so.conf 文件中,等等。这种设置在系统启动时会生效,从而会导致使用 GTK+ 的程序使用新版的 GTK+ 运行库,这有可能会带来一些问题。当然,如果你发现用新版的 GTK+ 代替旧版没有什么问题的话,使用这种设置方式是比较方便的。

库文件在连接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:

在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。 在 /etc/ld.so.conf 文件中添加库的搜索路径。 将自己可能存放库文件的路径都加入到 /etc/ld.so.conf 中是明智的选择。( ^_^)

添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:

复制代码代码如下:/usr/XR6/lib/usr/local/lib/opt/lib

需要注意的是:第二种搜索路径的设置方式对于程序连接时的库(包括共享库和静态库)的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。这是 因为为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,所以是直接读取库列表文件 /etc/ld.so.cache 从中进行搜索的。/etc/ld.so.cache 是一个非文本的数据文件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig 命令要以 root 权限执行)。因此,为了保证程序执行时对库的定位,在 /etc/ld.so.conf 中进行了库搜索路径的设置之后,还必须要运行 /sbin/ldconfig 命令更新 /etc/ld.so.cache 文件之后才可以。ldconfig ,简单的说,它的作用就是将 /etc/ld.so.conf 列出的路径下的库文件缓存到/etc/ld.so.cache以供使用。因此当安装完一些库文件(例如刚安装好 glib 或者修改 ld.so.conf 增加新的库路径)后,需要运行一下 /sbin/ldconfig 使所有的库文件都被缓存到 ld.so.cache 中,如果没做,即使库文件明明就在 /usr/lib 下的,也是不会被使用的,结果编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂 computer 蠢猪一个。 (^_^)

在程序连接时,对于库文件(静态库和共享库)的搜索路径,除了上面的设置方式之外,还可以通过 -L 参数显式指定。因为用 -L 设置的路径将被优先搜索,所以在连接的时候通常都会以这种方式直接指定要连接的库的路径。

前面已经说明过了,库搜索路径的设置有两种方式:在环境变量 LD_LIBRARY_PATH 中设置以及在 /etc/ld.so.conf 文件中设置。其中,第二种设置方式需要 root 权限,以改变 /etc/ld.so.conf 文件并执行 /sbin/ldconfig 命令。而且,当系统重新启动后,所有的基于 GTK2 的程序在运行时都将使用新安装的 GTK+ 库。不幸的是,由于 GTK+ 版本的改变,这有时会给应用程序带来兼容性的问题,造成某些程序运行不正常。为了避免出现上面的这些情况,在 GTK+ 及其依赖库的安装过程中对于库的搜索路径的设置将采用第一种方式进行。这种设置方式不需要 root 权限,设置也简单:复制代码代码如下:$ export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH可以用下面的命令查看 LD_LIBRAY_PATH 的设置内容:复制代码代码如下:$ echo $LD_LIBRARY_PATH

最后,我来总结一下,PKG_CONFIG_PATH 主要指明.pc文件的所在路径,这样 pkg-config 工具就可以根据.pc文件的内容动态生成编译和连接选项,比如 Cflags (编译用)和 Libs (连接用),如果使用的是动态链接库,那么程序在连接和运行时,一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,对于处于默认库搜索路径之外的库,系统管理员可以设置 LD_LIBRARY_PATH 环境变量或在 /etc/ld.so.conf 文件中添加库的搜索路径。值得说明的是,使用 gcc 连接时的选项,如果不用 pkg-config 工具,需要显示的声明连接的动态链接库名。使用 gcc 的同学可以查看下面的注意事项。

Linux 系统中,为了让动态链接库能被系统中其它程序共享,其名字应符合 lib*.so.* 这种格式。如果某个动态链接库不符合此格式,则 Linux 的动态链接库自动装入程序(ld)将搜索不到此链接库,其它程序也无法共享之。格式中,第一个*通常表示为简写的库名,第二个*通常表示为该库的版本号。如在我的系统中,基本C动态链接库的名字为 libc.so.6,线程 pthread 动态链接库的名字为 libpthread.so.0 等等。如果没有指定版本号,比如 libmy.so ,这也是符合要求的格式。

gcc 命令几个重要选项:

-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号,不用该标志外部程序无法连接。相当于一个可执行文件)。 -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。 -L.:表示要连接的库在当前目录中。 -lmy:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称(libmy.so)。 当然如果有 root 权限的话,可以修改 /etc/ld.so.conf 文件,然后调用 /sbin/ldconfig 来达到同样的目的,不过如果没有 root 权限,那么只能采用输出 LD_LIBRARY_PATH 的方法了。

linux中bin与sbin目录的作用及区别介绍 在linux系统中,有两个重要的目录:bin与sbin,分别包括/bin、/usr/bin/与/sbin、/usr/sbin/。bin:bin为binary的简写,主要放置系统的必备执行文件,例如:cat、cp、

linux下零拷贝技术介绍 传统的数据传输方式很长一段时间内,数据拷贝的认识仅仅停留在应用程序层,实际上隐藏在背后的数据拷贝行为比想象的要多的多。在传输数据的时

Linux下Android开发环境搭建详细步骤 1、系统环境[android@localhost~]$uname-aLinuxlocalhost.localdomain2.6.-.el6.i#1SMPWedSep::EDTiiiGNU/Linux[android@localhost~]$lsb_release-aLSBVersion::core-4.0-ia:core

标签: pkg-config命令

本文链接地址:https://www.jiuchutong.com/biancheng/360638.html 转载请保留说明!

上一篇:Linux中文件执行中的锁定怪现象解释(linux 文件执行)

下一篇:linux中bin与sbin目录的作用及区别介绍(linux bin和sbin)

  • 融资租赁印花税怎么交
  • 报销金额限制多少
  • 地产企业预缴增值税政策
  • 固定资产折旧准予扣除是什么意思
  • 发票上盖了老税号怎么办
  • 处置使用过的车辆
  • 人工费能不能抵扣进项税
  • 固定资产融资租出计入什么科目
  • 销售退回的增值税怎么处理
  • 企业先租入再出租如何编制会计分录?
  • 收入跨期审计调整分录如何滚调
  • 应付账款多付了会计分录
  • 支付专家劳务费什么意思
  • 计提工资数大于实际支付数怎么办?
  • 个人承担的社保算工资吗
  • 购买设备的增值税是支出吗
  • 广告位租赁交印花税吗
  • 按税收规定计算的扣除额公益性捐赠
  • 计税收入金额是什么意思
  • 股权转让分期收款怎么企业所得税
  • 职工教育经费能抵扣进项税
  • 广西电子税务局申报
  • 销售退回发票怎么处理
  • 在建工程和工程物资在资产负债表
  • 印花税按含税收入还是不含税收入
  • 新员工15号入职交社保吗
  • 库存商品换货的会计分录
  • 6月 全新windows
  • windows10显示未激活怎么办
  • 出租的厂房房产税谁交
  • php核心编程
  • 存货报废会计分录例题
  • php array数组
  • 红字发票冲减的是当月收入吗
  • 生产企业可以抵扣进项税的
  • php实现购物车功能
  • 新所得税会计准则
  • 材料款零头抹掉怎么做凭证
  • 6.824 Lab 1: A simple web proxy
  • 火车票抵扣进项税需要认证吗
  • 房屋发票备注栏怎么填
  • java中的常量是什么意思
  • 建设工程的材料质量检测由谁负责
  • 揭秘蒙娜丽莎25恐怖之处
  • 安装SQL2005的实训体会
  • 股权转让实缴资本4000万如何缴纳
  • 个人所得税逾期申报怎么办
  • 进项税额转出冲回
  • 产品因质量问题换新质保期如何计算
  • 未开票收入转为开票收入
  • 社保退休金计算方法
  • 借分公司的款收据怎么开
  • 支付给劳务人员劳务费需缴纳印花
  • 小规模主营业务成本是否含税
  • 服务类企业主要经营范围
  • 小规模转一般纳税人条件最新政策
  • 材料采购成本包括买价和采购费用
  • 账户与会计科目有什么联系与区别?
  • 微软软件怎么用
  • windowsserver2008r2密码重置
  • 复制电脑系统
  • ubuntu12.04 amd64系统中lamp环境搭建方法
  • linux vmtool
  • linux的ftp命令
  • w7打穿越火线
  • WIN764位系统8G内存识别一半解决办法
  • win8打游戏卡吗
  • Win10打开或关闭系统图标里开怎么灰色的
  • kail Linux系统
  • android opengl绘图
  • ip地址一键切换
  • jquery trigger实现联动的方法
  • js继承的方法
  • 企业吸收合并资质
  • 税务税收预测
  • 税务稽查为什么不问证人
  • 济南社保减免政策2020通知
  • 北京市朝阳区各中学校服照片
  • 出口备案单证管理办法
  • 税控盘在哪领取
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设