查看文章
 
在一个makefile中输出一个程序的debug版本和release版本
2010-06-09 16:50
在一个makefile中输出一个程序的debug版本和release版本

场景:
开发人员(rd)和测试人员(qa)是不同的人,可执行程序是通过配置管理平台提供的。同时,所有程序要上线运行,要通过qa的测试,然后将测试通过的程序,在配置管理平台上输出后上线。(从百度的流程中提取出来的,其他公司的流程未知)

需求:
debug版本的会有一些额外的处理,以及能够打印更多的log;release版本的,需要关闭可能影响性能的一些处理,以及关闭过多的log打印。rd在送测时,希望,同时送测两个版本的可执行程序,一方面方便qa在需要更详细日志的时候,可以使用debug版本。另一方面,rd不需要单独编译debug版本给qa使用。

一些知识:
gcc/g++中,有若干参数跟debug有关系,具体的可以看gcc/g++的man页,或者本文后面附录部分。
1、-g参数,在编译中添加一些调试信息,gdb可以使用这些信息。
2、-D参数和-U参数,-D将宏定义传递给程序,-U取消程序中的宏定义。

程序开发:
通过宏定义(比如_DEBUG_)对一些功能或者日志进行开关控制,比如将中间状态存储到文件中,供分析用等。

makefile:
1、makefile中,对一个.o文件只会编译一次,但经测试,同一个c或者cpp文件可以编译为多个不同的.o文件。
2、-g参数和-D、-U参数是在编译成.o文件时生效的。
3、故,对与debug版本和release版本的,可以生成不同的两份.o文件。
4、在link阶段,对debug和release两个版本的程序,使用各自那份的.o文件。

一个例子:
有三个文件,main.cpp, work.cpp, work.h
makefile:
obj1=main.o work.o
obj2=main.debug.o work.debug.o
target1= app
target2= app_for_debug

all: $(target1) $(target2)
clean: rm -f $(obj1) $(obj2) $(target1) $(target2)
%.o : %.cpp
g++ -c $< -o $@ 
%.debug.o : %.cpp
g++ -D_DEBUG_ -c $< -o $@
$(target1):$(obj1)
g++ -o $(target1) $@ $^
$(target2):$(obj2)
g++ -g -o $(target2) $@ $^

########################################附录##########################

gcc/g++中英文man页的相关参数部分:

##################英文版本:#################################

-D name
Predefine name as a macro, with definition 1.

-D name=definition
Predefine name as a macro, with definition definition.  The contents of definition are tokenized and processed as if they
appeared during translation phase three in a #define directive.  In particular, the definition will be truncated by embedded
newline characters.

If you are invoking the preprocessor from a shell or shell-like program you may need to use the shell's quoting syntax to
protect characters such as spaces that have a meaning in the shell syntax.

If you wish to define a function-like macro on the command line, write its argument list with surrounding parentheses before
the equals sign (if any).  Parentheses are meaningful to most shells, so you will need to quote the option.  With sh and csh,
-D'name(args...)=definition' works.

-D and -U options are processed in the order they are given on the command line.  All -imacros file and -include file options
are processed after all -D and -U options.

-U name
Cancel any previous definition of name, either built in or provided with a -D option.

-g  Produce debugging information in the operating system's native format (stabs, COFF, XCOFF, or DWARF).  GDB can work with this
debugging information.

On most systems that use stabs format, -g enables use of extra debugging information that only GDB can use; this extra infor-
mation makes debugging work better in GDB but will probably make other debuggers crash or refuse to read the program.  If you
want to control for certain whether to generate the extra information, use -gstabs+, -gstabs, -gxcoff+, -gxcoff, or -gvms
(see below).

Unlike most other C compilers, GCC allows you to use -g with -O.  The shortcuts taken by optimized code may occasionally pro-
duce surprising results: some variables you declared may not exist at all; flow of control may briefly move where you did not
expect it; some statements may not be executed because they compute constant results or their values were already at hand;
some statements may execute in different places because they were moved out of loops.

Nevertheless it proves possible to debug optimized output.  This makes it reasonable to use the optimizer for programs that
might have bugs.

The following options are useful when GCC is generated with the capability for more than one debugging format.


##########################中文版本###################################

-Dmacro
定义 宏 macro, 宏 的 内容 定义为 字符串 `1'.

-Dmacro=defn
定义 宏 macro 的 内容 为 defn. 命令行 上 所有的 `-D' 选项 在 `-U' 选项 之前 处理.

-Umacro
取消 宏 macro.  `-U' 选项 在 所有的 `-D' 选项 之后 处理, 但是 优先于 任何 `-include' 或 `-imacros' 选项.

-g     以 操作系统 的 本地格式 (stabs, COFF, XCOFF, 或 DWARF).  产生 调试信息. GDB 能够 使用 这些 调试信息.

在 大多数 使用 stabs 格式 的 系统 上, `-g' 选项 启动 只有 GDB 才使用 的 额外调试信息; 这些信息 使 GDB 调试 效果 更好, 但是 有
可能 导致 其他 调试器 崩溃, 或 拒绝 读入 程序.  如果 你 确定 要
控制 是否 生成 额外的 信息, 使用`-gstabs+', `-gstabs', `-gxcoff+', `-gxcoff', `-gdwarf+', 或 `-gdwarf' (见下文).

和 大多数 C 编译器 不同, GNU CC 允许 结合使用 `-g' 和 `-O' 选项. 优化的 代码 偶尔 制造 一些 惊异的 结果: 某些 声明过的 变量 根本 不存在; 控制流程 直接 跑到 没有 预料到的 地方;  某些语句  因为
计算结果 是 常量 或 已经确定 而 没有 执行; 某些语句 在 其他 地方 执行, 因为 他们 被移到 循环 外面 了.

然而 它 证明了 调试 优化的输出 是 可能的. 对 可能 含有 错误 的 程序 使用 优化器 是 合理的.

如果 GNU CC 支持 输出 多种 调试信息, 下面的 选项 则 非常有用.

##############################################
版权所有:http://hi.baidu.com/wg_wang

类别:Programming||添加到搜藏 |分享到i贴吧|浏览(2462)|评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
     

   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu