在编译一些第三方软件的时候,会经常遇到一些文件识别不到的问题,这里整理下做个归总。
目前可能的原因有(排序分先后):
- 文件不存在;
- 文件存在但路径识别不了;
- ……
这次以常见的编译lmbench测试组件为例,说明下该类问题的排查思路。
一、问题现象
首先安装标准的流程编译lmbench,包括下载源码包、解压、然后make result,具体步骤不做阐述,可参考性能测试工具 Lmbench 的使用方法以及解析运行结果-CSDN博客。
在make result编译时碰到了找不到rpc.h这个文件错误:
二、排查思路
碰到这种问题首先要想的就是文件确实不存在,因为有很多文件是有第三方的rpm包提供的,所以先找下rpc.h这个文件属于哪个rpm包,不怕麻烦可以去每个包的spec中去搜,怕麻烦直接百度。本文中所缺的rpc.h属于libtirpc-devel.rpm这个包,发现已经安装且提供了。
既然安装了,为什么不识别呢?看了下路径确实是在/usr/include目录下的,唯一的就是多了一层tirpc子路径,所以基本可以推测是子目录不识别。接下来开始验证。首先看报错位置,为bench.h文件中的38行引用了rpc.h
所以直接修改bench.h源码:
再次编译,发现虽然报错了,但报错信息变成了rpc.h中不识别rpc/types.h,而这个types.h也是属于tirpc目录下的文件。之前我们只修改了一处rpc.h的路径,识别成功了。而这个types.h没有改,所以识别不了。但此时已经证明出,报错原因就是路径问题了。
三、问题解决
找到原因就好解决了,其实不识别文件就是因为路径问题。/usr/include是系统默认搜寻的路径,如果有自己的路径那就是通过“gcc -L /路径 或者 -l 库名称” 来解决,具体可见gcc编译手册第3章GCC online documentation- GNU Project。
一般的,软件编译都是通过script脚本控制的,这次也不例外。如果不想深入lmbench或者其他软件,最快的方法就是搜索关键字符串,其实编译中常见的那无外乎几个,如控制编译器的${CC},控制C语言编译选项的${CFLAGS},控制链接库文件的${LDLIBS},控制加载选项的${LDFLAGS}……;略微搜索一番在稍微看下脚本,基本就能锁定是哪个文件(本次搜索并阅读脚本后,发现LDLIBS定义在scripts/build文件中)。
参考网上的一个解决:
#如果遇到rpc/rpc.h:No such file or directory
# yum install libtirpc-devel
# 在scripts/build 中加上: # LDLIBS="${LDLIBS} -ltirpc" # CFLAGS="${CFLAGS} -I/usr/include/tirpc"
其实这个LDLIBS和CFLAGS就是编译时的宏,脚本会通过各种编译环境case的匹配,最后使得宏定义变成包含多种路径多种库目录的一个最终字符串,如果不想仔细理解scripts中的匹配规则,就可以像上述一样直接修改。
笔者本次修改略有不同,但本质一样,都是在宏定义中追加路径。
在build文件中全局解决/usr/include/tirpc路径下文件的识别问题,就能直接编译成功。