CC=g++ -O2 -DNDEBUG
DEST=validate_writefile_accuracy
OBJS=validate_writefile_accuracy.o DataStructure.o ParseCfgFile.o ValidateFile.o CellBuilder.o
CFLAGS=-Wall -D_REENTRANT -DHAVE_NETINET_IN_H -I./include \
-I/dinglicom/hypertable/current/include \
-I/dinglicom/hypertable/current/include/thrift
LDFLAGS=-rdynamic -L./lib -L/dinglicom/hypertable/current/lib \
-lHyperThrift -lHyperCommon -lHypertable -lthrift -lboost_date_time -lboost_program_options
all: $(DEST)
$(DEST): $(OBJS)
$(CC) $^ -o $@ $(LDFLAGS)
#$(CC) $(OBJS) -o $(DEST) $(LDFLAGS)
%.o: %.cc
$(CC) -c $< $(CFLAGS)
clean:
rm -rf $(OBJS) $(DEST)
通过这次使用经历,发现原来对g++命令的许多参数很不熟悉,所以借此机会对经常使用的参数进行记录整理。
-o参数:
这是非常常用的一个参数,本来不想作说明,但是遇到了一个问题,故予以说明。
上述Makefile文件中的“$(CC) $^ -o $@ $(LDFLAGS)”编译正常,但是如果将其改为“$(CC) $(LDFLAGS) $^ -o $@”或“$(CC) $^ -o $(LDFLAGS) $@”时总会出现一些与thrift相关的“莫名其妙”的编译错误。我也专门验证过两种写法,应该是正确的。看来这个问题确实与thrift强相关了,为了确保万一,还是提醒自己以后都按照第一种写法吧。或许这三种写法之间有些微妙的区别,自己暂时没有发现吧,希望以后能发现。。。如果有幸被哪位正好知道这个问题原因的大侠看到,也希望不吝赐教。。。
-g参数:
生成调试信息,即通常所说的“debug版本”。
使用此参数时,如果在print varname时出现错误“No symbol ‘varname’ in current context.”,则需要将此参数替换为“-gstabs+”或“-gdwarf-2”,但是发现后者效果好于后者。
-Dmacro参数:
定义宏,相当于c语言的:#define macro。例如常见的用法:-DNDEBUG,表示定义了名称为NDEBUG的宏,这一般用于禁用程序中的assert宏,因为assert.h文件中有类似下面的代码:
#ifdef NDEBUG
#define assert(_Expression) ((void)0)
#else
...
#endif
从这里也引申出了一个大家经常讨论的问题:Linux下如何编译得到Debug和Release版本。个人认为:release和debug的差异在于生成的可执行文件是否包含调试信息。所以在程序编写时可通过定义类如“#ifdef DEBUG”这样的代码表示debug代码,编译时通过“g++ -DDEBUG”这样的方式生成debug版本,当然release也是类似原理了。
个人觉得这个参数很是重要,上述Makefile中的“-D_REENTRANT -DHAVE_NETINET_IN_H”便是这个参数的使用。因为项目中使用了thrift,如果编译时缺少这个选项,便会报出许多关于protocol和socket的莫名其妙的错误。
-Umacro参数
取消宏,相当于C语言中的:#undef macro
-Wall 参数
一般使用该选项,允许发出GCC能够提供的所有有用的警告。也可以用-W{warning}来标记指定的警告。
-O0、-O1、-O2 、-O3参数
编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高。一般在发布release版本时使用。
-rdynamic参数
用来通知链接器将所有符号添加到动态符号表中,如果链接器支持-rdynamic的话,建议将其加上,这样符号表会多出了一个函数名称+偏移地址。
以下两个参数与生成 动态库相关:
-shared参数
指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号)
-fPIC参数
表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。此参数有小写格式“-fpic”,表示适用于共享库,而不是动态库。