如果你打开Libevent的一些文件,比如util.h文件。就会发现使用了很多宏定义,并根据一些宏定义而进行条件编译。这些宏定义往往来自event-config.h文件中。
如util.h文件的代码开始处:
- #ifdef _EVENT_HAVE_SYS_TIME_H
- #include <sys/time.h>
- #endif
- #ifdef _EVENT_HAVE_STDINT_H
- #include <stdint.h>
- #elif defined(_EVENT_HAVE_INTTYPES_H)
- #include <inttypes.h>
- #endif
其会根据是否定义了某个宏,而决定是否包含某个头文件。从宏的名字来看,其指明了是否有这个头文件。有时还会指明是否有某个函数。这样做的原因很简单,因为Libevent是跨平台的,必须得考虑到某些系统可能没有一些头文件或者函数。
event-config.h文件是一个很基础和重要的文件。在文件的一开始有这样一句"This file was generated by autoconf when libevent was built"。这说明这个文件是在Libevent配置的时候生成的,即在编译Libevent之前就应该要生成该文件了。当然也早于我们在Libevent基础上编写应用程序。
其在编译之前就检查所在的系统的一些情况。比如是否含有某个文件或者函数。其对这些进行检测,然后把结果写入到event-config.h文件中。等到编译Libevent和编译我们的APP时,会include该头文件。
PS:上面两段的说法有点错误。待修改。
该文件大部分内容是根据config.h.in文件生成的。比如,config.h.in文件里面有下面的代码:
- /* Define to 1if you have the <arpa/inet.h> header file. */
- #undefHAVE_ARPA_INET_H
- .....
- /* Define ifyour system supports the epoll system calls */
- #undefHAVE_EPOLL
对应地,Linux内核版本在2.6以上的Linux对应生成的event-config.h文件会定义这两个宏,如下:
- /* Define to 1if you have the <arpa/inet.h> header file. */
- #define_EVENT_HAVE_ARPA_INET_H 1
- ......
- /* Define to 1if you have the <sys/epoll.h> header file. */
- #define_EVENT_HAVE_SYS_EPOLL_H 1
而在Windows系统下生成的event-config.h文件就没有定义这两个宏。
可以说,event-config.h这个文件定义的宏指明了所在的系统有哪些可用的头文件、函数和一些配置。
又比如对于gcc来说,是支持__func__这个宏的,但对于VS编译器就不支持,VS对应功能的宏为__FUNCTION__。此时在Windows系统的event-config.h文件中,就会定义:
- /* Define toappropriate substitue if compiler doesnt have __func__ */
- #define_EVENT___func__ __FUNCTION__
而在util-internal.h文件中,有这样的定义:
- #ifdef_EVENT___func__
- #define __func___EVENT___func__
- #endif
这样就可以在其他文件中通用__func__宏了,无需关注是什么系统了。
event-config.h文件的有些内容是根据编译Libevent时的配置选项生成的。比如是否支持多线程这个选项。如果配置Libevent的时,加入了这样一句
- ./configure--disable-thread-support
那么,在event-config.h文件将定义DISABLE_THREAD_SUPPORT这个宏,此时得到的Libevent是不支持多线程的。