前奏
最近在做项目时,碰到个问题,在编译avahi模块时出现了报错。如下图:
当时我就特别奇怪,之前使用muslc
的时候都没啥问题,为啥现在使用glibc
就有问题了。难不成,之前编译的dbus就有这个函数定义,使用glibc之后就没有了?为了搞清楚这个问题,我决定使用谷歌!!!然而,悲伤的事是:
没有想象的美好,so,只能靠自己了。(面向谷歌编程的我好难过。)
分析问题
是啥子问题
既然要解决问题,首先我们要搞清楚问题是什么。从图中可以很清晰的看到,是编译器在链接文件时无法查找到dbus_connection_disconnect
。既然是链接问题,很显然主要从两个方面入手:
- 检查编译时是否有指定dbus库的位置;
- 如果指定了,那么dbus中是否包含该函数;
找到dbus
既然是查找文件,在linux中我们当然是使用find咯,结果如下:
再对比一下第一张图中的编译命令,发现其中-L
中包含了dbus的目录,而-l
则包含了dbus-1
,由此可见,编译命令没有问题。
检查dbus库函数
既然编译命令没有问题没有问题,那么需要检查下libdbus中是否包含该函数,如果包含结果显示有,那么很可能我们的dbus库存在问题,如果不包含,则需要检查源码中为什么会使用该函数。其结果如下:
从上图看到,很显然,libdbus中不包含这个函数。因此,我们的思路就需要转变到avahi中是否自己定义了该函数,但是链接的时候文件没有被定义到。
检查avahi中关于该函数的源码
为了明确找到avahi中是否定义了该函数,我们使用了grep
进行查找,结果如下:
从图中我们可以看到,并没有dbus_connection_disconnect
的函数定义,所有的函数都是调用。为此,我们随便打开一个文件检查下代码调用的内容,如下图:
打开文件,查找该函数后发现,我去,好家伙,居然有个宏定义。如果是存在HAVE_DBUS_CONNECTION_CLOSE
则使用dbus_connection_close
,否则就使用dbus_connection_disconnect
。
那么时候该咋办?很简单,check一下dbus库中是否包含dbus_connection_close
函数,如果包含的话,就是宏定义存在问题。那么我们的方向就会转变为为什么宏定义存在问题。
检查dbus中是否包含dbus_connection_close
老方法,nm
加grep
:
好家伙,这下石锤了,宏定义出了问题。方向明确,找宏定义出问题的原因。
HAVE_DBUS_CONNECTION_CLOSE
为啥没有定义?
既然要找为啥该宏出问题,那么得先找到在哪里定义了该宏。从编译的角度来说,有两种方式可以传递宏定义:
- 使用
gcc
等编译器时使用-D
赋值; - 另外一种时在文件中定义。
由于是该宏定义没有定义,第一种的命令行肯定不包含该定义。所以,我们转向查找文件中(makefile或者源文件)查找。这时候,grep
大法再次出击:
检查了一遍,的确没有很明确的#define HAVE_DBUS_CONNECTION_CLOSE XXX
的内容,说明代码中的确没有定义该宏。再仔细检查发现,该宏是包含是包含在autom4te.cache
中的。至于这个文件夹的含义,我也不是特别清楚。但是,这个线索告诉我们,这个宏是通过configure
命令生成的。于是,我又重新clean并编译了该包,并输出了编译日志以方便我查看configure
生成内容。(命令是make package/libs/avahi/clean;make package/libs/avahi/install
,当然也可以进入到该pacakge目录然后执行mm -B
)。其结果如下:
从内容中看到,dbus_connection_close
的确没有被检查到。那么,这里一定是存在一些问题的。这时候,我的想法是搞清楚,autoconf
查找函数的原理。为此,我做了以下事情:
- 谷歌
autoconf
如何检查函数的原理; - 根据日志输出上下文查找代码;
其中,由于第二步后来发现是无用功,我在这里就不赘述,我们主要看第一个结果。其实,我在谷歌的时候并没有找到实际答案,但是找到了一个很关键的信息:configure
的输出都会被存储在config.log中。于是,下一步就是自然而然的检查config.log
文件。
检查config.log文件
多的就不说了,关键信息如下:
从上图可以看到,居然是使用编译器链接来检查该函数是否存在,而由于pthread
库没有指定而导致宏定义失败。
解决问题
好了,通过上面的步骤,问题基本找到了。接下来就是解决问题了,由于我之前做产品时就是在全志平台,因此积累过一定经验,我的最后修改如下(至于为什么这么修改,不在这个博文的主题中,如果有兴趣,我可以单独再写博文讨论):
重新编译,成功!
后记
实际上,类似的问题在工作中其实经常碰到,我之所以写这个博文有两个原因:
- 之前不爱记录,我想改变一下,也分享给需要的人;
- 工作中难免碰到问题,想提供一些思路给大家。
这次博文呢,算是我想对我相对完整的记录,希望大家指教。
历史
Version | Date | Description |
---|---|---|
0.1 | 2020-10-11 | 第一次记录 |
评论区