昨天总监把工程的makefile改写了一下,感觉比以前的强多了,以后再工程子目录下添加源文件也不用像以前那么麻烦了,看了看,学到了一些新东西。
1. makefile 's function
$(patsubst PATTERN,REPLACEMENT,TEXT)
函数功能:
搜索“TEXT”中以空格分开的单词,将符合模式“PATTERN”替换为“REPLACEMENT”。参数“PATTERN”中可以使用模式通配符“%”来代表一个单词中的若干个字符。如果参数“REPLACEMENT”中也包含一个“%”,那么“REPLACEMENT”中的"%“将是”PATTERN“中所代表的字符串。在”PATTERN“和”REPLACEMENT“中,只有第一个”%“被作为模式字符来处理,之后出现的不再作模式字符(作为一个字符)。在参数中如果需要将一个出现的”%“作为字符本身而不作为模式字符时,可使用反斜杠”\“进行转移处理。
返回值:
替换后的新字符串。
函数说明:
参数”TEXT“单词之间的多个空格在处理时被合并一个空格,并忽略前导和结尾空格。
叽里呱啦说了一堆,我第一次看的时候真的没有看明白它在说什么,幸好下面有一个例子。
$(patsubst %.c,%.o,x.c.c bar.c)
把字符串”x.c.c bar.c“中以.c结尾的单词替换成以.o结尾的字符。函数的返回结果是”x.c.o bar.o“
变量的高级用法可以这样
$(VAR:PATTERN=REPLEACEMENT)
it is same to this:
$(patsubst PATTERN,REPLEACEMENT,$(VAR))
还是例子比较清楚:它是这么个意思
$(objects:.o=.c)
$(patsubst %.o,%.c,$(objects))
上面这两个式子是等价的。 understand ?
OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp))
这样或许更清晰一些
2. .cpp.o:
$(CPP) $(CPPFLAGS) $(INCLUDE_PATH) -MMD -MP -MF "$(DEPDIR)/$*.Po" -c -o $@ $<;
g++ 编译选项
-M
Instead of outputting the result of preprocessing, output a rule suitable for make describing the dependencies of the main source file. The preprocessor outputs one make rule containing the object file name for that source file, a colon, and the names of the all the included files, including those coming from -include or -imacros command line options.
Unless specified explicitly (with -MF or -MQ), the object file name consists of the basename of the source file with any suffix replaced with object file suffixx. If there are many included files then the rule is split into serveral line using \-newline. The rule has no commands.
This option does not suppress the preprocessors's debug output, such as -dM. To avoid mixing such debug output with the dependency rules you should explicitly specify the dependency output file with -MF, or use an enviroment variable like DEPENDENCIES_OUTPUT.Debug output will still be sent to the regular output stream as normal.
-MM
like -M but do not mention header files that are found in system header directories, nor header files that are included, directly or indirectly, from such a header.
This implies that the choice of angle brackets or double quotes in an #include directive does not in itself determine whether that header will appear in -MM dependency output. This is a slight change in semantics from GCC versions 3.0 and earlier.
-MF file
When used with -M or -MM, specifies a file to write the dependencies to. If no -MF switch is given the reprocessor sends the rules to the same place it would have sent preprocessed output.
When used with the dirver options -MD or -MMD, -MF overrides the default dependency output file.
-MP
This option instructs cpp to add a phony/'fəuni/(a.假的,欺骗的。n.假冒者,赝品) target for each dependency other than the main file, causing each to depend on nothing. These dummy rules work around errors make gives if you remove header file without updating the Makefile to match.
写了这么多, 其实就是一个意思,将依赖关系写入到 -MF选项所指定的文件中,不明白,为什么要用这个选项,默认的不是挺好用的吗?
如果还不明白,这里有个链接,如果看了这个链接还不明白,那你就别问了。-_-
该链接的精华:
gcc -M 参数你应该了解吧,比如我有一个t.c,内容是
#include
#include
int test()
{
return 0;
}
gcc -c -M t.c 不会编译t.c,而是输出t.o (t.c对应的目标文件)的依赖关系(用于makefile),比如在我的系统上输出:
t.o: t.c /usr/include/stdio.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
/usr/include/gnu/stubs.h /usr/include/gnu/stubs-32.h \
/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/include/stddef.h \
/usr/include/bits/types.h /usr/include/bits/typesizes.h \
/usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/include/stdarg.h \
/usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
/usr/include/string.h /usr/include/xlocale.h
如果你想让依赖关系打印到文件,而不是标准输出,那么可以用
gcc -M -MF file t.c
上面的内容就会保存到 file 里。
默认的, -M参数意味着-E参数同时也生效, -E参数的用处是只进行预编译,而不会编译出真正的目标文件 (t.o)
有了上面的概念,就可以理解 -MD了,
比如
gcc -c -MD t.c
就会生成 t.d (保存前面说国的依赖关系), t.o (t.c编译后的目标文件,之所以会产生是因为 -E参数在-MD的时候默认是关闭的)
gcc -c -o p.o -MD t.c
就会声称 p.o 和 p.d (保存依赖关系),这是因为你用了-o参数指定了名字
阅读(696) | 评论(0) | 转发(0) |