当前位置: 首页 > 编程日记 > 正文

pkg-config工具在实际工程中的用法

在如今这个开源的环境里,想要开发某个功能,我们都会下意识的上网搜索有没有开源库,如果有开源库,那么好,下载下来给它编译好,使用。但是在使用过程中,你是否遇到不知如何将第三方库编译,链接到自己的工程中?怎么改makefile就是改不好?是否看到开源库lib/中pkgconfig文件夹,想都没想这是干什么用的,打开.pc文件也不知所云?那么好,今天我就总结下开源库中pkgconfig文件夹中.pc文件的作用,以及如何用pkg-config工具将开源库集成到自己的工程中去。

1、pkg-config工具的作用

    pkg-config简单的说就是向用户提供相应库的路径,版本号,头文件路径等信息的综合调用程序。笔者使用的是Ubuntu系统,我们以OpenEXR库为例看看pkg-config运行的结果,在shell命令行输入:

显示信息为:-I/usr/include/OpenEXR -lIlmImf -lImath -lHalf -lIex -lIexMath -lIlmThread -lpthread
这是什么呀?
-I/usr/include/OpenEXR 这不就是我们用gcc编译时的CFLAGS参数吗?
-lIlmImf -lImath -lHalf -lIex -lIexMath -lIlmThread -lpthread这些不就是gcc在链接时使用的LDFLAGS参数吗?

因此当我们需要在自己的工程中编译链接时只需要合理的使用pkg-config工具,把上面那些参数加入到gcc的参数里即可,这个就是pkg-config工具的核心作用,它会检查你的库,产生相应信息,为你集成某个第三方库提供便利。

2、*.pc文件解析

    我们知道,第三方库的使用主要涉及头文件的路径设置,库的路径设置以及动态库的环境变量设置。一般来讲,第三方库都会提供一个*.pc 文件,pkg-config程序通过读取这个*.pc的文件,获取了库的头文件位置和库的路径等信息,然后告知编译器,实现库的自动使用。一般来说,*.pc文件的大体内容如下格式(以笔者最近使用的SQLite3为例):

其中,

  • prefix一般是指定库的默认安装路径
  • exec_prefix一般是指库的另外指定的安装路径
  • inludedir指定库的头文件路径
  • libdir指定库的lib文件的路径
  • Name指定库的名称,比如笔者使用的SQLite数据库
  • Description表示库的描述
  • Version是版本号
  • Cflags是gcc链接头文件的指令,以-I紧接头文件路径设置
  • Libs是gcc链接lib文件的指令, 是-L紧接lib文件路径,-l紧接所使用的lib的名字。
3、如何编译链接到你的工程?

    这里讲的是工程,我只讲干货,编译单个程序例子网上有很多,就不赘述了。这里注意,使用pkg-config工具提取库的编译和链接参数需要有两个基本前提:
1)库本身按章的时候必须提供一个.pc文件。没有这个文件的说明库不支持pkg-config工具;
2)pkg-config必须要知道去哪找.pc文件;
 
    对于支持pkg-config工具的库来说,库文件的搜索路径实际就是对.pc文件的搜索路径,一般系统的默认搜索路在/usr/lib/pkgconfig 中,库的头文件一般在/usr/include中。而个人使用的第三方库,不能每次编译后都装到/usr目录下吧。所以私有工程在编译链接第三方库时可以通过环境变量PKG_CONFIG_PATH来设置,pkg-config工具将按照设置路径的先后顺序进行搜索,直到找到指定的.pc文件为止。
   所以在私有工程的makefile中,先修改环境变量:

export PKG_CONFIG_PATH=/home/水笙/sqlite-autoconf-3130000/build_result/lib/pkgconfig:$PKG_CONFIG_PATH

环境变量设置好后,设置CFLAGS:

CFLAGS += `pkg-config --cflags sqlite3`

这里注意要用``将命令包起来。

然后设置LDFLAGS:
LDFLAGS += `pkg-config --libs sqlite3`

基本通过这三步,工程就可以正确的编译链接第三方库了。

4、运行时指明共享库搜索路径

    我们知道,库分为静态库和共享库。静态库.a就是一些.o文件的集合,编译链接后就集成到了你的应用程序中。而共享库,是在程序运行的时才被使用的,其搜索路径是在系统中预先设置的,对于处于搜索路劲之外的库,使用的时候必须设置好环境变量LD_LIBRARY_PATH,否则应用程序找不到,笔者将sqlite3库放到了应用程序文件夹的./lib中,在启动应用前调用下面这句:

export LD_LIBRARY_PATH="./lib"

笔者建议,最好将其写在你的启动脚本里。

相关文章:

linux中pipe

调用pipe函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读端一个写端,然后通过filedes参数传出给用户程序两个文件描述符,filedes[0]指向管道的读端,filedes[1]指向管道的写端(很好记就像0是标准输入1是标准输出一样)。所以管道在用户程序看起来就像一个打开的文通r…

【C++】利用构造函数对类对象进行初始化

运行环境:VS2017 一、对象的初始化 每一个对象都应当在它建立之时就有就有确定的内容,否则就会失去对象的意义。 class Time {int hour 0;int min 0;int sec 0; }; 这种是错误的,类并不是一个实体,并不占储存空间&#xff…

自定义Chrome浏览器

一、全局 自用备份,窗体透明化、要添加对应网站的窗体class到对应的位置 /*主页背景*/ /*https://images.cnblogs.com/cnblogs_com/AardWolf/1350846/o_5900399dcdcbd.jpg*/ /*https://ws4.sinaimg.cn/large/0072Vf1pgy1foxkfzphb2j31hc0u0gvv.jpg*/body { backgrou…

ubuntu添加sudo权限

使用如下命令可以添加到用户组(也可是超级用户组)。 命令如下: sudo usermod -aG 超级用户组名 用户名 例子:sudo usermod -aG sudo username 其中a:表示添加,G:指定组名第二种方法是直接修改&#xff0c…

File.separator

报告“No such file or diretory ”的异常,上传不了。后来发现是文件路径的问题。模拟测试环境是windowstomcat,而正式的的环境是linuxtomcat,文件路径的分隔符在windows系统和linux系统中是不一样。 比如说要在temp目录下建立一个test.txt文…

【C++】对象数组

运行环境:VS2017 对象数组:每个元素都是同类的对象 如果构造函数只有一个参数,在定义数组时可以直接在等号后面的花括号内提供实参。 Student stud[3]{60,70,80}; 如果构造函数有多个参数,则不能用在定义数组时直接提供所有实…

C# 算法系列一基本数据结构

一、简介 作为一个程序员,算法是一个永远都绕不过去的话题,虽然在大学里参加过ACM的比赛,没记错的话,浙江赛区倒数第二,后来不知怎么的,就不在Care他了,但是现在后悔了,非常的后悔!!!如果当时好好学算法的话,现在去理解一些高深的框架可能会很easy,现在随着C#基础和Web技能的提…

git管理大项目或者大文件

git 是追踪代码库演进的最佳选择,并且它能让你与你的同事间高效协作。当你想要追踪的库非常巨大时会发生什么?在这篇文章里,我会尝试着给你一些想法和技巧来恰当地处理不同种类的大仓库。两种大代码库如果仔细想想,大概会有两种导…

window下java开发环境安装

首先请去Java的官网上下载,最好下载最新版本地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 如图,点击下载java platform(JDK),然后选择接受接受协议(Accept …

【ACM】蛇形填数

先判断,再移动,而不是发现越界了再退回来。 #include "stdio.h" #include "string.h" #define maxn 20 int a[maxn][maxn]; int main() {int n, x, y, tot 0;scanf_s("%d", &n);memset(a, 0, sizeof(a));tot a[x …

Mybatis中Oracle和Mysql的Count字段问题

Mybatis中Oracle和Mysql的Count字段问题 我们在进行项目开发时经常会碰到查询总数的问题&#xff0c;所以我们直接是用select count(1) from table来进行查询。那么在Mybatis通常情况下我们是这么写的 <select id"testCount" resultType"int">select…

为什么free()时不需要传指针大小

malloc()和free()是c中两个非常基本的函数&#xff0c;但这种最基本的东西往往都是特别复杂的。malloc和free的原形如下&#xff1a;void *malloc(unsigned int num_bytes); void free(void *ptr);在c的标准中并没有定义这两个函数的具体实现&#xff0c;在我们最常用的gcc中&a…

redis cluster 安装配置

一、redis集群安装配置1、下载redis源码包并下载wget http://download.redis.io/releases/redis-3.0.7.tar.gz $ tar xzf redis-3.0.7.tar.gz $ cd redis-3.0.7 yum -y install gcc gcc-c libstdc-devel #解决相关依赖关系$ make && make install 因我们安装redis 集…

【ACM】汉诺塔

https://blog.csdn.net/xueerfei008/article/details/9904681

什么是机器人底盘 答案在这里!

机器人底盘承载了机器人本身的定位、导航及避障等基本功能&#xff0c;可帮助机器人实现智能行走&#xff0c;以思岚科技的ZEUS为例&#xff0c;内置SLAMWARE高性能自主定位导航模块&#xff0c;用户可根据实际需要搭载不同的应用&#xff0c;可广泛适用于餐厅、商场、银行、办…

嵌入式linux内存使用和性能优化

这本书有两个关切点&#xff1a;系统内存(用户层)和性能优化。 这本书和Brendan Gregg的《Systems Performance》相比&#xff0c;无论是技术层次还是更高的理论都有较大差距。但是这不影响&#xff0c;快速花点时间简单过一遍。 然后在对《Systems Performance》进行详细的学…

【算法导论】插入排序

循环不变式 在数学上阐述了通过循环&#xff08;迭代&#xff0c;递归&#xff09;去计算一个累计的目标值的正确性。 关于循环不变式&#xff0c;我们必须要证明三条性质&#xff1a; 初始化&#xff1a;循环第一次迭代之前&#xff0c;它为真。保持&#xff1a;如果循环的…

gdb+gdbserver

内容摘要 远程调试环境由宿主机GDB和目标机调试stub共同构成&#xff0c;两者通过串口或TCP连接。使用 GDB标准程串行协议协同工作&#xff0c;实现对目标机上的系统内核和上层应用的监控和调试功能。调试stub是嵌入式系统中的一段代码&#xff0c;作为宿主机GDB和目标机调试程…

Android开发技巧——去掉TextView中autolink的下划线

我们知道&#xff0c;在布局文件中设置textview的autolink及其类型&#xff0c;这时textivew上会显示link的颜色&#xff0c;并且文字下面会有一条下划线&#xff0c;表示可以点击。而在我们在点击textview时&#xff0c;应用将根据我们所设置的类型跳转到对应的界面。但是有时…

【算法导论】冒泡排序 选择排序

冒泡排序&#xff1a; //从大到小 void bubble_sort(int array[],int len) {int i,j,t;for(i0;i<len-1;i){for(j0;j<len-1-i;j){if(array[j]<array[j1]){tarray[j];array[j]array[j1];array[j1]t;} }} } 选择排序&#xff1a; //从大到小 void select_sort(int a…

监控平台zabbix高级配置

2019独角兽企业重金招聘Python工程师标准>>> 12月26日任务 19.12 添加自定义监控项目 19.13/19.14 配置邮件告警 19.15 测试告警 19.16 不发邮件的问题处理 添加自定义监控项目 zabbix可以自定义监控项目&#xff0c;满足个性化的需求。例如网站注册量、访问量等具体…

linux内存实际占用分析

作者: 黄永兵/译 出处:51CTO.com 阅读提示&#xff1a;本文是为那些经常疑惑的人准备的&#xff0c;“为什么一个简单的KDE文本编辑器要占用25M内存&#xff1f;”导致大多数人认为许多Linux应用程序&#xff0c;特别是KDE或GNOME程序都象ps报告一样臃肿...【51CTO.com独家译文…

CentOS 6.5 下Vim 配置图解

分享个CentOS 6.5 下Vim 配置图文详解&#xff0c;希望对大家有所帮助。 1. 登录并进入你常用的用户名下&#xff0c;查看其主目录 命令&#xff1a; # su xxx $ cd xxx $ ls -a 2.查看并建立目录和文件 首先看你的主目录~/ 下是否有.vimrc文件&#xff0c;没有就输入指令 $ to…

【ACM】杭电OJ 1106 函数atoi

函数atoi是把字符串转化成整数的函数&#xff0c;头文件为 #include "stdlib.h" e.g. 运行环境&#xff1a;Dev-C 5.11 杭电1106 调用了sort函数&#xff0c;运行的时间相对长一些。 #include "stdio.h" #include "string.h" #include "…

docker-dockerfile

docker文件存储驱动dockerfile镜像构建指令示例dockekr镜像是只读的&#xff0c;对容器修改的内容&#xff0c;一旦容器退出&#xff0c;所有的内容将会丢失。镜像是分层的&#xff0c;最上的一层为读写层&#xff08;写时复制和用时分配&#xff09; 文件系统存储驱动&#xf…

proc/[pid]/maps 文件解释

proc/[pid]/maps 文件解释 查看进程的虚拟地址空间是如何使用的。 该文件有6列&#xff0c;分别为&#xff1a; 地址&#xff1a;库在进程里地址范围 权限&#xff1a;虚拟内存的权限&#xff0c;r读&#xff0c;w写,x,s共享,p私有&#xff1b; 偏移量&#xff1a;库在进程里…

【ACM】UVa 1339

【题目】&#xff1a;给定两个长度相同且不超过100的字符串&#xff0c;判断是否能把其中一个字符串的各个字母重排&#xff0c;然后对26个字母做一一映射&#xff0c;使得两个字符串相同。输入两个字符串&#xff0c;输出“YES”或者“NO”。 【分析】&#xff1a;既然字母可…

springBoot PUT请求接收不了参数的解决办法

2019独角兽企业重金招聘Python工程师标准>>> 做项目的时候&#xff0c;想把接口写标准点&#xff0c;于是在更新内容的时候采用put提交内容&#xff0c;但是提交内容时总是获取不到参数&#xff0c;总是选择参数为null。 首先贴出我的put的方法控制器的代码 和之前的…

七牛云内容审核服务被选为「上海首批人工智能创新产品」

近日&#xff0c;上海人工智能应用场景建设实施计划正式发布&#xff0c;这是全国首次面向人工智能应用场景需求的征集计划。上海 10 大人工智能应用场景、19 个具体点位需求和 60 个人工智能创新产品集中首发&#xff0c;其中&#xff0c;上海七牛信息技术有限公司&#xff08…