本节介绍如何制作自己的函数库、安装这个函数库,以及在一个应用工程中如何使用这个函数库。其中用到了工具pkg-config.
一、 pkg-config
1. 为何要用pkg-config
你在 Unix 或 Linux 下开发过软件吗?写完一个程序,编译运行完全正常,在你本机上工作得好好的,你放到源代码管理系统中。然后,告诉你的同事说,你可以取下来用了。这时,你长长的出了一口气,几天的工作没有白费,多么清新的空气啊,你开始飘飘然了。
“Hi,怎么编译不过去?”你还沉浸在那种美妙的感觉之中,双臂充满着力量,似乎没有什么问题能难倒你的。正在此时,那个笨蛋已经冲着你嚷开了。
“不会吧,我这边好好的!”表面上你说得很客气,其实,你心里已经骂开了,真笨,不知道脑子干嘛用的。也许,你想的没错,上次,他犯了一个简单的错误,不是你一去就解决了吗。
他喊三次之后,你不得不放下你手上的工作,刚才那种美妙的感觉已经消失得无影无踪了,要不是你把情绪控制得很好,一肚子气就要撒在他身上了。你走到他的电脑前,键入 make,优雅的按下回车。怎么可能出错呢?你信心十足。然而,屏幕上的结果多少有点让人脸红,该死的,libxxx.so 怎么会让不到呢?
你在/usr目录中查找 libxxx.so,一切都逃不过你的眼睛。奇怪,libxxx.so 怎么在 /usr/local/lib 下,不是应该在 /usr/lib 下的吗?这你可不能怪别人,别人想安装在哪里都行,下次还可能安装到 /lib 目录下呢。
以上的场景并非虚构,我都经历过好几次,明明在本机上好好的,在别人的机器上连编译都过不去。可能两人的操作系统一模一样,需要的库都安装上,只是由于个人 喜好不同,安装在不同的目录而已。遇到这种情况,每次都技巧性的绕过去了,用的补丁型的方法,心里老惦记其它地方能不能工作。
pkg-config为解决以上问题提供了一个优美方案。从此,你再也不为此担忧了。
2. pkg-config简介
pkg-config 是一个提供从源代码中编译软件时查询已安装的库时使用的统一接口的计算机软件。pkg-config原本是设计用于Linux的,但现在在各个版本的BSD、windows、Mac OS X和Solaris上都有着可用的版本。
它输出已安装的库的各个信息,包括:
C或C++编译器需要的参数
链接器需要的参数
已安装软件包的版本信息
工作原理
当安装一个库时(从RPM,deb或其他二进制包管理系统),会包括一个后缀名为pc的文件,它会同其他.pc文件一起放入一个文件夹(依赖与你的系统设置)。
在这个文件里包含有数个条目。这些条目通常包含用于其他使用这个库的程序编译时需要的库设置,以及头文件的位置,版本信息和一个简介。
这是一个用于libpng的.pc文件的样例:
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${exec_prefix}/include
Name: libpng12
Description: Loads and saves PNG files
Version: 1.2.8
Libs: -L${libdir} -lpng12 -lz
Cflags: -I${includedir}/libpng12
这个文件告诉我们这些库可以在/usr/local/lib找到,头文件可以在/usr/local/include里找到,库的名字是libpng12并且版本号是1.2.8。它也提供了用于编译依赖于libpng的源代码时需要的链接器参数。
这儿是一个编译时使用pkg-config的样例:
gcc -o test test.c $(pkg-config --libs --cflags libpng)
二、制作自己的函数库
1. 开始时,只有我自己写的一些.c和.h文件,放在base/src/下
2. 在base和base/src下创建Makefile.am文件
base/Makefile.am
SUBDIRS=src pkgconfigdir=${libdir}/pkgconfig pkgconfig_DATA=base.pc
pkgconfig不是关键字;
dir表示要安装的目录;_DATA表示要安装的文件(两者配合使用)。这里指定了pc文件要被安装到哪里
libdir会被换成base.pc.in中相应的值(它最终由./configure --prefix=...指定的值确定)
base/src/Makefile.am
lib_LTLIBRARIES=libbase.la libbase_la_SOURCES= darray.c \ darray.h \ dlist.c \ dlist.h \ darray_iterator.h \ dlist_iterator.h \ hash_table.c \ hash_table.h \ invert.c \ iterator.h \ linear_container_darray.c \ linear_container_darray.h \ linear_container_dlist.c \ linear_container_dlist.h \ linear_container.h \ queue.c \ queue.h \ sort.c \ sort.h \ stack.c \ stack.h \ typedef.h libbase_la_LDFLAGS=-lpthread noinst_PROGRAMS=darray_test dlist_test darray_test_SOURCES=darray.c darray_test_CFLAGS=-DDARRAY_TEST dlist_test_SOURCES=dlist.c dlist_test_CFLAGS=-DDLIST_TEST basedir=$(includedir)/base base_HEADERS=darray.h dlist.h iterator.h linear_container_dlist.h typedef.h \ darray_iterator.h dlist_iterator.h linear_container_darray.h \ linear_container.h EXTRA_DIST=\ linear_container_test.c \ invert_ng.c \ darray_iterator.c \ dlist_iterator.c \ test_helper.c
lib_LTLIBRARIES=libbase.la 共享库用扩展名.la可以同时生成共享库和静态库。
libbase_la_SOURCES=... libbase.la编译时需要的源文件
libbase_la_LDFLAGS=-lpthread libbase.la链接时需要的参数
noinst_PROGRAMS=darray_test dlist_test 关键字noinst_PROGRAMS指定不需要安装的的可执行文件
darray_test_SOURCES=darray.c darray.c --编译--> darray_test
darray_test_CFLAGS=-DDARRAY_TEST 编译和预处理darray.c时需要的参数
basedir=$(includedir)/base
base_HEADERS=darray.h dlist.h iterator.h ... 配套使用,将_HEADERS列出的头文件安装到dir路径
注: $(includedir)在base.pc.in中指定
3.定制configure.in
#autoscan
autom4te: configure.ac: no such file or directory
autoscan: /usr/bin/autom4te failed with exit status: 1
#ls
autoscan.log configure.scan Makefile.am src
#mv configure.scan configure.in
将configure.in稍作修改
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) #AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_INIT(base, 0.1, chuanwang66@163.com) #修改 AC_CONFIG_SRCDIR([src/typedef.h]) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE(base, 0,1) #新增 # Checks for programs. AC_PROG_CC AC_PROG_LIBTOOL #新增 # Checks for libraries. # FIXME: Replace `main' with a function in `-lpthread': AC_CHECK_LIB([pthread], [main]) # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([stdlib.h string.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_INLINE AC_TYPE_SIZE_T # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT
相关推荐
"android播放器未完待续"这个标题暗示我们将探讨如何在Android系统中构建一个功能完善的音乐播放器,以及可能遇到的问题和解决方案。让我们深入研究一下。 首先,Android音乐播放器的基础是媒体库服务。Android提供...
在大数据实战第一部分中,我们将探索大数据处理的关键概念和技术,这些技术在当今信息化社会中扮演着至关重要的角色。大数据不仅仅是关于海量数据,更是关于如何高效地处理这些数据以获取有价值的洞察。在这个实战...
综合以上信息,我们可以得知这是一个使用cocos2dx开发的手机网游项目,由个人开发者或团队进行创作,并且正处于持续开发阶段。游戏可能已经具备了基本的游戏机制和视觉表现,但还有待完善和扩展。通过提供的视频文件...
例如,在例18中提到,如果一个活动需要8个人在10天±2天内完成,那么如果只用一个人,这个活动将需要64到96人天,这可以帮助项目经理决定是否需要增加或减少人力资源。 总的来说,掌握PERT技术对于系统集成项目管理...
供热工程设计是一项复杂且细致的工作,它涉及到建筑物的舒适性、能源效率以及环境保护等多个方面。本文档将详细阐述某宿舍楼的楼层采暖系统的设计方案、设计依据、供暖热负荷计算、散热器的选型与安装、管路布置以及...
1. **周报全文**:一份详细阐述本周A股市场表现、关键经济数据、政策动态、行业热点及未来预期的报告,可能包括文字分析、图表和数据。 2. **市场分析**:针对不同板块(如金融、科技、消费等)的深度分析,预测...
正确配置路径是使用探针的关键,这涉及到了数据库连接信息和第三方库的位置。`index.php`和`include`目录中的文件构成了探针的核心,提供了收集和展示环境信息的功能。虽然这个探针的描述标记为"未完待续,仅供参考...
EOS开发入门之cleos命令解读(未完待续)1
C++是一种高级编程语言,它在20世纪80年代初作为面向对象程序设计语言的代表出现,是对C语言的扩展。C++的设计思想强调了结构化程序设计和面向对象特性,包括封装性、继承性和多态性。 结构化程序设计,又称为面向...
根据给定文件的信息,我们可以提炼出一系列关于项目管理和系统集成的知识点。下面是对这些知识点的详细阐述: ### 1. 项目信息收集的重要性 - **情境背景**:项目管理过程中,项目经理需要收集有关项目的各种信息...
9--[小黑点的旅行(未完待续)].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码9--[小黑点的旅行(未完待续)].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码9--[小黑点的旅行(未完待续)].zip...
2010年是中国水泥行业发展的一个关键节点,当时行业经历了快速增长,此后,政策调整、环保压力以及市场需求变化等因素对水泥产业产生了深远影响。这份报告旨在通过对过去十年的回顾,为业界提供对当前市场及未来预测...
在"WebBrowser的各种使用方法(未完待续)(XE8+WIN7)"这个主题中,我们将深入探讨WebBrowser控件的使用技巧及其在XE8版本下的应用。 1. **安装与添加WebBrowser控件** 在Delphi XE8中,首先确保你的系统已经安装了...
2012年12月21-22日,由杭州安恒信息技术有限公司与人人网联合主办2012...本届论坛主要内容将围绕WEB应用防护的技术体系建设和产品服务创新,尤其针对互联网重要基础行业应用展开讨论,打造安全体系方舟迎接末日安全。
图书管理系统是一种现代化的图书馆管理系统,旨在提高图书馆的管理效率和服务质量,提供一个综合的图书管理平台,满足图书馆的各种需求,包括读者管理、借阅管理、图书管理和查询等功能。 2. 可行性研究的前提 2.1...
笔记和注释的未完待续状态表明,这是一个持续更新的资源,旨在跟进行业的最新进展。 一、Python基础 Python是一种高级编程语言,以其简洁明了的语法和强大的库支持而闻名。在机器学习中,Python提供了丰富的库如...
未完工程及遗留问题清单(表格模板、XLS格式).XLS
《建筑工程资料管理》是建筑工程行业中一个重要的学习领域,它涵盖了工程项目的全生命周期,从施工到竣工,再到后期的维护管理,都涉及到大量的资料管理工作。这些资料不仅是工程质量、安全的记录,也是项目审计、...
包括业主选择设计案和设计单位的方式、建筑业企业工程经理资质管理制度的过渡、工程控制的核心任务、供货的工程管理工作、动态关系、合同关系、...工程风险、施工本钱管理措施、施工本钱构成、验收申请和工程变更价款等...
后勤仓库信息化管理系统的设计和实施是一个系统工程,涉及到多个层面,包括需求分析、系统设计、数据库构建、软件开发以及后期的维护和优化。通过科学合理的信息化管理,可以大大提高后勤仓库的工作效率,降低运营...