如何仅通过Make调用覆盖与源文件同目录的C头文件?
我之前也碰到过几乎一模一样的糟心事!旧项目的代码硬要拉同目录下的config.h,可我新项目里的配置才是需要用的,又不想改旧代码里的#include "config.h"语句——毕竟改了以后维护起来麻烦得很。其实完全不用碰代码,只靠Make的编译参数就能搞定。
先给你说清楚GCC的搜索逻辑:它处理#include "xxx.h"的时候,默认是先搜当前源文件所在的目录,再去-I指定的目录找。我们要做的就是把新项目的config.h所在目录,塞到GCC搜索顺序的最前面,让它先找到我们想要的那个配置文件。
具体操作很简单,在你的Makefile里加这么一行就行:
CFLAGS += -iquote ./src
这里的./src就是你新项目里config.h所在的目录(如果你的Makefile不在new_project根目录,就改成对应的相对路径或者绝对路径)。-iquote这个参数的妙处在于,它会把指定的目录加到#include ""的搜索优先级最前面,比源文件的同目录还高——这样旧代码再喊#include "config.h"时,GCC第一时间就会找到你新项目里的配置,根本不会去旧代码的目录瞎找了。
如果你还想再加一层保险,怕某些极端情况(比如旧的config.h没加防重复包含的宏),可以再加上-include参数强制预包含新项目的配置:
CFLAGS += -include ./src/config.h
这个参数会让GCC在编译任何源文件之前,自动把这个头文件包含进去,相当于给每个源文件都偷偷加了一行#include "./src/config.h",这样就算旧代码的#include被处理,也会因为新项目的配置已经加载过,不会再去读旧的了。
最后要注意:确保所有编译旧项目代码的规则都用上了这个CFLAGS参数,别漏了某些源文件的编译规则没传递这个配置,不然那些漏了的文件还是会去读旧的config.h。
内容来源于stack exchange

