linux下编译的时候,经常会在编译命令中加入一些自定义的编译选项或者参数,比如 gcc -DYF_DEBUG 之类,这样的方式是比较灵活

可以根据需要取消或者加入编译选项,去年搞的那个linux makefile 测试版+发布版 自动切换--"自动化"就是利用这一方法做的;

这一方法对于编译最终可执行文件没任何问题;但对于lib或者so库编译会包含一定的风险,造成一些恶心的麻烦;比如上面说的 YF_DEBUG

用于关闭或者打开一些监控选项,比如一个 struct 定义:

struct yf_conn {
#ifdef YF_DEBUG
yf_int_t cnt;...
#endif
yf_fd_t fd;
};

首先编译成库,如果是采用在编译命令中使用编译参数,当库编译好之后,使用者使用起来会有n多陷阱;如果库编译打开了这一选项,但

使用者不知道这一选项,或者忘记也定义这一选项,那么使用者看到的头文件中的结构定义和库中的结构定义将不一致,然后就是莫名其妙的

内存错误,而且这类错误很难理解,所以比较难fix;

以前碰到过这种恶心的问题,所以对这种问题感觉非常深刻;当时对于这种唯一的解决办法是:库和使用者都记得使用统一的编译选项,只要

一个改了,其他的都统一修改;

随着yifei项目的代码和模块增多增大,lib和so分离的需求也越来越大,于是又一次碰到了同样的问题;回过头来看这一问题,发现其实 autoconfig

提供了其他方法解决这一问题:

之前的定义是:

# debug option
AC_ARG_ENABLE([debug],
[AS_HELP_STRING([--enable-debug], [debug program with log(default is no)])],
[CFLAGS="-DYF_DEBUG -g -O0"],
[CFLAGS="-O2"])

这样多个库以及使用者之间都必须在 configue.in 中都加入这一恶心的重复选项,因为这一选项是加在 gcc 命令之后的;

其实 autoconfig 会自动生成一个头文件,所以完全可以把这个 YF_DEBUG 加入到头文件中去,这样一旦configue --enable-debug 之后,这一选

项就自定加入到了头文件中,而不是只是放在gcc命令中;这样使用者就不需要再重复定义这一选项了;

于是新的方法:

# debug option
AC_ARG_ENABLE([debug],
[AS_HELP_STRING([--enable-debug], [debug program with log(default is no)])],
[CFLAGS="-g -O0";AC_DEFINE([YF_DEBUG], [], ["enable debug"])],
[CFLAGS="-O2"])

btw: autoconfig 和 automake 这一系列工具确定都非常强大,好用;

注意:enable 的 第一个参数比如下面的 syscall 和 --enable-syscall 后面的 enable 的后缀必须完全一致,否则将。。。

开始一不小心将第一个参数写成了 sys_call 害我查了办个小时。。。。

# sys call reptr option
AC_ARG_ENABLE([syscall],
[AS_HELP_STRING([--enable-syscall], [enable sys call])],
[AC_DEFINE([YF_SYS_CALL_REPTR], [], ["enable sys call"])], [])