【问题标题】:how to run a system call from a makefile and save the answer in a variable如何从生成文件运行系统调用并将答案保存在变量中
【发布时间】:2011-12-09 10:35:15
【问题描述】:

我正在尝试设置要在编译期间使用的变量值。 我尝试在单独的 makefile 目标中做到这一点

svnversion:
    SVN_REV=$(shell svnversion -cn | sed -e 's/.*://' -e 's/\([0-9]*\).*/\1/' | grep '[0-9]')
    $(info svn_rev = $(SVN_REV))

我读到这是设置变量值的方法。 然而,当我运行“make”时,我看到了:

SVN_REV=613
svn_rev = 

所以变量似乎是空的。之后我希望这个变量在编译发生时会出现(在其他目标中)。是这样吗?或者我应该在 svnversion 目标中添加一个“导出”命令?以及如何解决 SVN_REV 变量? $(SVN_REV) 或 $$(SVN_REV)。

谢谢

【问题讨论】:

  • 会不会是变量区分大小写?

标签: c shell makefile command


【解决方案1】:

您不能在规则的不同行之间甚至在不同规则之间使用变量。每一行都在它自己的 shell 中执行,因此无法以这种方式传递信息。 (Petesh 表示,正如我刚才看到的那样)

如果您需要存储中间信息,请使用如下文件:

 foo:
         uname -m > current_arch
         ...

 bar:
         gcc -m $$(cat current_arch) ...
         ...

如果正在执行的命令不是太耗时并且不依赖于在构建过程中调用的时间,您也可以设置一个宏:ant

 ARCH = $$(uname -m)

 bar:
         gcc -m $(ARCH) ...

但这不是设置变量,而是宏替换。调用 make bar 时传递给 shell 的实际命令是:

         gcc -m $(uname -n)

然后将执行 uname 命令。

【讨论】:

    【解决方案2】:

    您实际上是在行尾结束的子shell中分配值SVN_REV,

    你可能想要的是:

    svnversion:: SVN_REV=$(shell svnversion -cn | sed -e 's/.*://' -e 's/\([0-9]*\).*/\1/' | grep '[0-9]')
    
    svnversion:
            $(info svn_rev = $(SVN_REV))
    

    这会在设置目标时设置变量。

    如果这不是预期的,假设您想对变量进行一些处理,那么您需要在行尾使用可怕的; \ 使每一行成为前一行的延续语义。如果您随后引用 shell 变量(如第一行中评估的变量),那么您需要在变量名之前使用 $$ 语法

    例如

    svnversion:
            SVN_REV=$(shell svnversion -cn | sed -e 's/.*://' -e 's/\([0-9]*\).*/\1/' | grep '[0-9]'); \
            echo svn_rev = $$SVN_REV
    

    但因为它在 shell 中,所以您不能在 $(info 命令中使用该变量,因为这发生在目标评估之外。

    【讨论】:

    • 您能解释一下svnversion:: snipet 吗?它是一个额外的目标吗?什么时候运行?
    • 当你的目标是svnversion::,你评估变量SVN_REV
    • 这允许像debug:: CFLAGS+=-g这样的机制添加到make中的CFLAGS变量
    猜你喜欢
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多