代码之家  ›  专栏  ›  技术社区  ›  jme52

Makefile和标头定义选项共存

  •  1
  • jme52  · 技术社区  · 11 年前

    我在一个FORTRAN代码项目中工作,该项目的编译决策在两个文件中进行:一个头文件( definitions.h ),包括在相关的FORTRAN文件中,以及 makefile 例如,编译器、一些库集和允许的并行化类型(MPI、OpenMP或none)在 生成文件 ,并且代码的某些部分的包含由控制 #define 标头中的指令。

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

    2. 此外 生成文件 以及 定义.h 文件处于修订控制之下。这意味着,我那些粗心的开发人员提交并推送这两个文件的新版本,他们只更改了启用的编译选项,从而污染了修订控制历史。理想情况下,至少最大的文件( 生成文件 )不必进行编辑即可设置编译选项。

    3. 在某些情况下,会出现不一致的情况。通常,在 生成文件 与所选代码的某些部分不兼容 #定义 指令。有什么方法可以正确检查吗?

      例如,为了停止编译,如果 LIB1=LIBFOO (在 生成文件 )以及 bar 定义为 1 (在头文件中),我在 生成文件

      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
      

      但(a)这非常丑陋,(b)显然根本不起作用。如何解决这个问题?


    我做了3.,我想我有一个答案:我添加了一个新的 .PHONY 目标 ini_check ,这是其他相关目标的必备条件,并读取

    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..."
    

    请注意,现在我使用C预处理器来获取变量的值 酒吧 在解析标头之后。

    1 回复  |  直到 11 年前
        1
  •  0
  •   Beta    11 年前

    如果您的策略是在没有标志或参数的情况下运行Make,那么通过将相关开关放在一个附件文件中,您仍然可以省去一些痛苦( 在版本控制下)生成文件将 include .

    正如你所说,用Make解析源文件既丑陋又困难。这是一场噩梦。我建议保留两个版本的 definitions.h 在不同目录的版本控制下;选择库的相同Make逻辑可以选择头文件。

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

    最后,如果“几分钟”太长而无法等待这样的编译器错误,那么您一定经常会犯这样的错误——您可能需要查看您的过程。(此外,如果你只修改了一两个文件,一次构建不应该花那么长时间——是的,每天都要进行,但不是一小时要进行几次。)