Makefile和header定义选项的共存

时间:2013-03-20 14:44:28

标签: makefile preprocessor-directive

我在FORTRAN代码项目中工作,其中编译决策采用两个文件:头文件(definitions.h),它包含在相关的FORTRAN文件中,以及makefile。例如,在makefile中选择了编译器,一些库集以及允许的并行化类型(MPI,OpenMP或无),并且{{1}控制了代码的某些部分的包含标题中的指令。

  1. 我不喜欢编辑两个不同的文件来设置编译。有更好的方法吗?

  2. 此外,#definemakefile文件均受版本控制。这意味着我的粗心开发人员提交并推送两个文件的新版本,他们只更改了启用的编译选项,因此污染了版本控制历史记录。理想情况下,至少不需要编辑最大的文件(definitions.h)来设置编译选项。

  3. 在某些情况下,会出现不一致的情况。通常,makefile中选择的某些库组合与makefile指令选择的某些代码段不兼容。有没有办法正确检查?

    例如,为了停止编译,如果#defineLIB1=LIBFOO)和makefile定义为bar(在头文件中),我试图停止编译跟随1

    中的一些代码
    makefile

    但是(a)这是非常难看的,(b)显然它根本不起作用。如何解决这个问题?


  4. 我在3.上工作,我觉得我有一个答案:我添加一个新的ifeq ($(LIB1), LIBFOO) bar_status:=`grep -i '^[[:space:]]*\#define[[:space:]]*bar[[:space:]]*[[:digit:]]' definitions.h | tail -n1 | grep -ic '^[[:space:]]*#define[[:space:]]*bar[[:space:]]*1[[:space:]]*'` ifeq ($(bar_status), 1) $(error ERROR: You are trying to compile the code with bar enabled in definitions.h, but this is incompatible with the library LIBFOO selected in the makefile) endif endif 目标,.PHONY,这是其他相关目标的必备条件,并且读取

    ini_check

    请注意,现在我使用C预处理器在解析标头后获取变量ifeq ($(LIB1), LIBFOO) bar_value:=$(shell echo bar | cat definitions.h - | gcc -E -undef - 2>/dev/null | tail -n1) endif ini_check: ifeq ($(LIB1), LIBFOO) ifeq ($(bar_value), 1) $(error ERROR: You are trying to compile the code with bar enabled in definitions.h, but this is incompatible with the library LIBFOO selected in the makefile) endif endif @echo "Done with the initial check, starting compilation..." 的值。

1 个答案:

答案 0 :(得分:0)

如果你的策略是运行没有标志或参数的Make,你仍然可以通过将相关的开关放在一个附件文件(不是版本控制下)中来保存自己一些悲伤,makefile将{{ 1}}。

正如您所说,使用Make解析源文件,正如您所说,既丑又难。维持这是一场噩梦。我建议在版本控制下将两个版本的include保存在不同的目录中;相同的make选择库的逻辑可以选择头文件。

我不知道当你的头文件与库“不兼容”时你会得到什么样的错误,但如果库有不同的接口,你可以通过放置一些库来故意调用编译器错误 - 头文件中的特定调用。 (如果它们没有不同的接口,那么您似乎有一些不良的依赖于实现的行为。)

最后,如果“几分钟”太长而无法等待这样的编译器错误,那么你必须经常犯这样的错误 - 你可能想查看你的程序。 (另外,如果你只修改了一个或两个文件,那么构建不应该花那么长时间 - 每天构建,是的,但不是你每小时做几次的那种。)