分类: C/C++
2014-10-08 16:49:46
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"])], [])