Makefile 中的函数

发布于 2024-07-13 07:04:32 字数 827 浏览 3 评论 0原文

我正在编写一个包含大量重复内容的 Makefile,例如

debug_ifort_Linux:
        if [ $(UNAME) = Linux ]; then                           \
          $(MAKE) FC=ifort FFLAGS=$(difort) PETSC_FFLAGS="..."  \
                  TARGET=$@ LEXT="ifort_$(UNAME)" -e syst;      \
        else                                                    \
          echo $(err_arch);                                     \
          exit 1;                                               \
        fi

定义目标“syst”、定义变量“UNAME”(通常是 Linux,但也可能由 Cygwin 或 OSF1)以及变量“difort”和'err_arch' 也被定义。 该代码块针对不同的编译器目标多次使用(使用命名约定“”)。 由于这是大量冗余代码,我希望能够以更简单的方式编写它。 例如,我想做这样的事情:

debug_ifort_Linux:
        compile(uname,compiler,flags,petsc_flags,target,lext)

其中compile可以是一个函数,根据参数执行上面的代码。 有谁知道我如何才能做到这一点?

I am writing a Makefile with a lot of repetitive stuff, e.g.

debug_ifort_Linux:
        if [ $(UNAME) = Linux ]; then                           \
          $(MAKE) FC=ifort FFLAGS=$(difort) PETSC_FFLAGS="..."  \
                  TARGET=$@ LEXT="ifort_$(UNAME)" -e syst;      \
        else                                                    \
          echo $(err_arch);                                     \
          exit 1;                                               \
        fi

where the target 'syst' is defined, the variable 'UNAME' is defined (and is usually Linux, but might also by Cygwin or OSF1) and the variables 'difort' and 'err_arch' are also defined. This block of code is used very many times for different compiler targets (using a name convention of ''). Since this is a huge amount of redundant code, I would like to be able to write it in a more simple manner. E.g., I would like to do something like this:

debug_ifort_Linux:
        compile(uname,compiler,flags,petsc_flags,target,lext)

where compile could be a function doing the code above based on the arguments. Does anyone have any idea how I could accomplish this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苏佲洛 2024-07-20 07:04:32

有3个相关概念:

  1. call function
  2. 多行变量
  3. 条件

重构的结果可能如下所示:

ifeq ($(UNAME),Linux)
    compile = $(MAKE) FC=$(1) FFLAGS=$(2) PETSC_FFLAGS=$(3) \
                      TARGET=$@ LEXT="$(1)_$(UNAME)" -e syst
else
    define compile =
        echo $(err_arch)
        exit 1
    endef
endif
        

debug_ifort:
        $(call compile,ifort,$(difort),"...")

那一个\ 是 shell 的 $(MAKE) 行的继续。
这里不需要多行变量,因为它只是一行 shell 代码。
多行变量仅在 else 块中使用。

如果不需要参数,可以使用 := 赋值,然后用 $(compile) 扩展该方法(请参阅 罐头食谱)

注意: 使用 3.82 版本之前的 make,无法识别 =在我的定义语句的末尾。 我通过使用 definecompile 解决了这个问题。

There are 3 related concepts:

  1. call function
  2. multi-line variables
  3. conditionals

The refactored result could look like this:

ifeq ($(UNAME),Linux)
    compile = $(MAKE) FC=$(1) FFLAGS=$(2) PETSC_FFLAGS=$(3) \
                      TARGET=$@ LEXT="$(1)_$(UNAME)" -e syst
else
    define compile =
        echo $(err_arch)
        exit 1
    endef
endif
        

debug_ifort:
        $(call compile,ifort,$(difort),"...")

That one \ that is left is to continue the $(MAKE) line for the shell.
No multi-line variable is necessary here, because it is just one line of shell code.
Multi-line variables are only used in the else block.

If you don't need parameters you can use := assignment and just expand the method with $(compile) (see canned recipes)

Note: Using make prior to version 3.82, the = was not recognized at the end of the define statement for me. I fixed this by using define compile instead.

明月松间行 2024-07-20 07:04:32

您正在寻找 call 函数

compile =                                                 \
        if [ $(UNAME) = $(1) ]; then                      \
          $(MAKE) FC=$(2) FFLAGS=$(3) PETSC_FFLAGS="..."  \
                  TARGET=$@ LEXT="$(4)_$(UNAME)" -e syst; \
        else                                              \
          echo $(err_arch);                               \
          exit 1;                                         \
        fi

debug_ifort_Linux:
        $(call compile,Linux,ifort,$(difort),ifort)

不过,如果您可以稍微重构一下 Makefile,您应该看看是否可以使用 make条件 而不是 sh 的。

You're looking for the call function.

compile =                                                 \
        if [ $(UNAME) = $(1) ]; then                      \
          $(MAKE) FC=$(2) FFLAGS=$(3) PETSC_FFLAGS="..."  \
                  TARGET=$@ LEXT="$(4)_$(UNAME)" -e syst; \
        else                                              \
          echo $(err_arch);                               \
          exit 1;                                         \
        fi

debug_ifort_Linux:
        $(call compile,Linux,ifort,$(difort),ifort)

If you can restructure your Makefile a bit, though, you should see if you can use make's conditionals instead of sh's.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文