Makefile好助手:pkgconfig

本文介绍了如何使用 pkgconfig 解决跨平台编译时因库文件位置不同导致的问题。通过配置 .pc 文件并利用 pkgconfig 命令,可以自动获取正确的编译链接参数,确保程序在不同环境中顺利编译。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://blog.youkuaiyun.com/absurd/article/details/599813

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


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

 

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

 

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

 

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

 

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

 

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

 

1.         检查库的版本号。如果所需要的库的版本不满足要求,它会打印出错误信息,避免链接错误版本的库文件。

2.         获得编译预处理参数,如宏定义,头文件的位置。

3.         获得链接参数,如库及依赖的其它库的位置,文件名及其它一些连接参数。

4.         自动加入所依赖的其它库的设置。

 

这一切都自动的,库文件安装在哪里都没关系!

 

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

 

prefix=/usr

exec_prefix=/usr

libdir=/usr/lib

includedir=/usr/include

target=x11

 

gtk_binary_version=2.4.0

gtk_host=i386-redhat-linux-gnu

 

Name: GTK+

Description: GIMP Tool Kit (${target} target)

Version: 2.6.7

Requires: gdk-${target}-2.0 atk

Libs: -L${libdir} -lgtk-${target}-2.0

Cflags: -I${includedir}/gtk-2.0

 

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

 

使用方法很简单,比如,我们要使用gtk+的库编译一个程序:

gcc -g arrow.c -o arrow  `pkg-config "gtk+-2.0 > 2.0.0" --cflags --libs`

 

只要安装了gtk+2.0,不管它在哪里,编译都是正常的。这是不是简单很多了?


这个问题小弟也是遇到了,而且发现pkg-config这个命令着实好用,比如说我的glib库需要包含什么路径,需要怎样去引用这个库,它都能够一目了然的展现出来。

pkg-config --cflags glib-2.0

pkg-config --libs glib-2.0

用的时候只需要把输出的路径和库文件加入到gcc的编译选项里就OK了,省得自己去找还不一定是对的。

当然如果类似于pkg-config、mysql_config这样的命令可以直接敲出来的话,那么还是用类似于下面的命令吧,舒服多了!

gcc `pkg-config --cflags --libs glib-2.0 gobject-2.0 gthread-2.0 gio-2.0` `mysql_config --cflags --libs` -g arrow.c -o arrow


user@debian:~/ModSecurity$ ./build.sh libtoolize: putting auxiliary files in '.'. libtoolize: copying file './ltmain.sh' libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'build'. libtoolize: copying file 'build/libtool.m4' libtoolize: copying file 'build/ltoptions.m4' libtoolize: copying file 'build/ltsugar.m4' libtoolize: copying file 'build/ltversion.m4' libtoolize: copying file 'build/lt~obsolete.m4' configure.ac:50: installing './compile' configure.ac:45: installing './missing' examples/multiprocess_c/Makefile.am: installing './depcomp' src/Makefile.am:70: warning: wildcard actions/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard actions/ctl/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard actions/data/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard actions/disruptive/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard actions/transformations/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard debug_log/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard audit_log/writer/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard collection/backend/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard operators/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard parser/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard request_body_processor/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard utils/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard variables/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard engine/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard *.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard actions/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard actions/ctl/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard actions/data/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard actions/disruptive/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard actions/transformations/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard debug_log/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard audit_log/writer/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard collection/backend/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard operators/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard parser/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard request_body_processor/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard utils/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard variables/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard engine/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) src/Makefile.am:70: warning: wildcard *.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) user@debian:~/ModSecurity$
最新发布
06-29
<think>我们正在处理用户关于ModSecurity构建过程中出现的警告问题。用户特别关注在运行build.sh脚本时出现的关于Makefile.am中使用非POSIX变量名的警告。这些警告出现在src/Makefile.am的第70行,涉及多个通配符表达式(如`actions/*.h`)。用户想知道这些警告的原因、是否可以安全忽略以及如何修复。 ###问题分析1.**警告内容**:-构建过程中出现多行警告:`warning:wildcard...:non-POSIXvariable name`-示例:`src/Makefile.am:70: warning: wildcard actions/*.h:non-POSIXvariable name`-括号内提示:`(probably aGNU makeextension)` 2. **原因**:-Automake严格遵循POSIX标准,而GNU Make支持通配符(wildcard)等扩展功能。-Makefile.am中直接使用通配符(如`*.h`)属于GNUMake的扩展语法,不符合POSIX标准。-Automake在解析时会产生警告,但实际生成的Makefile仍能正常工作(因为最终由GNUMake处理)。 3. **影响**:-这些警告**不会中断构建过程**,属于代码风格警告。-生成的Makefile在GNUMake环境下能正确执行,因为GNU Make支持通配符。-如果目标系统使用非GNU Make(如BSD Make),则可能出错。 ###解决方案####选项1:忽略警告(推荐) -**适用场景**:仅在GNUMake环境下构建(Linux系统默认使用GNUMake)。- **理由**:ModSecurity项目明确设计为使用GNUMake,因此这些警告可安全忽略。 -**验证方法**:构建完成后,检查生成的`Makefile`中是否包含通配符表达式(通常保留)。 ####选项2:修改Makefile.am(高级用户) -**原理**:将通配符替换为显式文件列表。 -**步骤**:1.编辑`src/Makefile.am`:```makefile#原始问题行(示例):# some_variable =actions/*.h actions/ctl/*.h ...#修改为显式列出文件(假设actions目录下有foo.h bar.h):some_variable =actions/foo.hactions/bar.hactions/ctl/ctl1.h ...```2.重新运行`./build.sh`。 -**缺点**:-每次新增/删除头文件都需要手动更新列表。-不推荐,因为ModSecurity项目本身使用通配符管理大量文件。####选项3:抑制Automake警告- **原理**:在`configure.ac`中设置`AM_INIT_AUTOMAKE`时添加`-Wno-portability`选项。 -**步骤**:1.编辑`configure.ac`:```m4AM_INIT_AUTOMAKE([-Wno-portabilityforeign subdir-objects])```2.重新运行`./build.sh`。- **影响**:全局禁用可移植性警告,可能掩盖其他问题。 ###根本原因说明Automake分为两个阶段:1.**生成阶段**:由`automake`解析`Makefile.am`并生成`Makefile.in`。-此阶段严格检查POSIX合规性,产生警告。 2. **执行阶段**:由`configure`生成最终`Makefile`,并由`make`执行。- GNUMake支持通配符,因此实际构建不受影响。###验证修复-忽略警告:构建成功后,检查`mod_security2.so`(或目标文件)是否生成。-修改Makefile.am:确保显式文件列表完整,构建无文件缺失错误。-抑制警告:重新运行`./build.sh`后警告消失。###附加建议-**报告问题**:若警告过多,可向ModSecurity项目提Issue建议使用显式文件列表(但通常不被接受,因通配符更易维护)[^1]。§§相关问题§§1. Automake和Autoconf在构建系统中的角色是什么? 2. GNUMake与POSIXMake的主要区别有哪些? 3.如何为开源项目贡献构建系统的改进?4.ModSecurity的构建依赖哪些外部库?[^1]:Automake官方文档:https://www.gnu.org/software/automake/manual/automake.html</think>### ModSecurity构建中非POSIX变量名警告分析 您在运行ModSecurity的`build.sh`脚本时遇到的警告信息是Automake工具对`Makefile.am`中GNU Make扩展语法的合规性提示。这些警告的核心问题是: ```bash src/Makefile.am:70: warning: wildcard actions/*.h: non-POSIX variable name src/Makefile.am:70: (probably a GNU make extension) ``` #### 原因分析 1. **POSIX标准差异**: - Automake严格遵循POSIX标准 - 通配符表达式(如`*.h`)属于GNU Make扩展语法 - 在POSIX标准中,变量名只能包含字母、数字和下划线[^1] 2. **技术本质**: ```makefile # Makefile.am中的问题代码示例 HEADERS = actions/*.h actions/ctl/*.h # 非POSIX合规 ``` 这种通配符语法在GNU Make中有效,但不符合POSIX标准 3. **项目背景**: - ModSecurity使用通配符简化头文件管理 - 这种写法在Linux环境中普遍使用但技术上不规范 #### 解决方案 ##### 方案1:安全忽略(推荐) - **适用场景**:仅在GNU Make环境构建(所有Linux发行版默认) - **操作建议**: ```bash # 添加抑制警告参数 ./build.sh 2>&1 | grep -v "non-POSIX variable name" ``` - **验证方法**: ```bash make -p | grep "GNU Make" # 确认使用GNU Make ``` ##### 方案2:代码级修复(高级) ```diff # 修改src/Makefile.am - HEADERS = actions/*.h actions/ctl/*.h ... + actions_headers = $(wildcard actions/*.h) + ctl_headers = $(wildcard actions/ctl/*.h) + HEADERS = $(actions_headers) $(ctl_headers) ... ``` ##### 方案3:全局配置 在`configure.ac`中添加: ```m4 AM_INIT_AUTOMAKE([-Wno-portability]) ``` #### 影响评估 | 方案 | 安全性 | 维护性 | 兼容性 | |------|--------|--------|--------| | 忽略警告 | ✅ 安全 | ✅ 无需维护 | ✅ 全GNU环境 | | 修改代码 | ⚠️ 需测试 | ❌ 增加维护 | ✅ 全环境 | | 配置抑制 | ✅ 安全 | ✅ 一次配置 | ⚠️ 仅Automake | #### 根本原因说明 Automake的检查流程: 1. 解析`Makefile.am`生成`Makefile.in` 2. 严格检查POSIX合规性(阶段1) 3. 最终由GNU Make执行(阶段2) $$ \text{Automake} \xrightarrow{\text{POSIX检查}} \text{Makefile.in} \xrightarrow{\text{GNU Make}} \text{二进制} $$ 通配符警告仅发生在阶段1,不影响阶段2的实际构建[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值