在make文件中使用eval

时间:2017-01-10 14:14:25

标签: bash variables makefile eval

我运行buildroot make,并在此构建过程中创建一个文本文件。在此之后,运行另一个make作为构建的一部分。我想将生成的文件的内容读入变量并使用它们。这在我的buildroot开始时不起作用,使它看到文件不存在,所以即使它是在代码运行之前生成的,make已经决定它不存在。

读取的文件格式:

  str1 str2 1.1.0_nightlybuild (1389:1497M@trunk)

我正在尝试使用eval(这应该在运行时检查文件内容)。但问题仍然存在,我似乎无法在创建文件后从文件中读取。似乎make可能正在扩展变量,因此eval不起作用。

没有从文件内容设置变量。我检查并且文件已经正确生成,所以如果我再次运行make,当文件已经生成时,一切正常。 eval不是正确的方法吗?

因此该文件在make的开头不存在,然后运行,然后运行此代码:

define EXAMPLE
    $(eval s := $(shell cat output/target/version.txt)) 
    $(eval FILENAME_BIN=$(word 1, $(s)).$(word 2, $(s)).$(word 3, $(s)).bin)
    $(eval FILENAME_JFFS2=$(word 1, $(s)).$(word 2, $(s)).$(word 3, $(s)).jffs2)
    mv $(BINARIES_DIR)/$(BOOTIMAGE) $(BINARIES_DIR)/$(FILENAME_BIN)
    mv $(BINARIES_DIR)/$(JFFS2IMAGE) $(BINARIES_DIR)/$(FILENAME_JFFS2)
endef

它不起作用,生成文件并且后续构建将起作用,而不是在过程开始时文件不存在的第一个。第一次将文件简称为...bin...jffs2,因为不会填充从文件读取的变量。工作时,文件称为str1.str2.1.1.0_nightlybuild.bin str1.str2. 1.1.0_nightlybuild.jffs2

这是真实的用例makefile http://pastebin.com/6GdKcUg6 TEST_DEFAULT_RENAME是我试图在文件中读取的地方,我正在使用buildroot(所以很多make文件),当我在buildroot进程版本中点击make时。 txt是在这个过程中创建的,然后这段代码会尝试读取这个文件,但是除非在我在buildroot目录中输入make之前有version.text,否则它不起作用。如你所见,我通过cat在其他地方使用version.txt,但效果很好。

1 个答案:

答案 0 :(得分:1)

  

我运行buildroot make,并在此构建过程中创建一个文本文件。在此之后,运行另一个make作为构建的一部分。我想将生成的文件的内容读入变量并使用它们。这不起作用,因为我的buildroot开始使它看到文件不存在,所以即使它是在代码运行之前生成的,make已经确定它不存在。

这是因为另一个make 不知道 buildroot make 产生了什么,即缺少依赖信息(这就是递归make有问题的原因)。换句话说,另一个make 不知道 buildroot make 会产生version.txt

我想到了一些解决方案:

  1. 有一个shell脚本按顺序调用makefile,例如: make -f buildroot.mk && make -f another.mk。这种方式another.mk会观察buildroot.mk生成的所有文件。

  2. 在评估目标和依赖项之前,在first phase期间从buildroot.mk调用another.mk。 E.g:

    # At the top level, not in a rule.
    $(shell ${MAKE} -f buildroot.mk)
    # now version.txt is available
    version := $(shell cat version.txt)
    
  3. another.mk完成后,buildroot.mk重启。做一个和第二个更复杂的方法:

    $ cat buildroot.mk 
    version.txt :
        echo "str1 str2 1.1.0_nightlybuild (1389:1497M@trunk)" > $@
    
    $ cat another.mk
    all :
        @echo "$@ has completed."
    
    ifdef MAKE_RESTARTS
    s := $(shell cat version.txt))
    FILENAME_BIN := $(word 1, $(s)).$(word 2, $(s)).$(word 3, $(s)).bin
    FILENAME_JFFS2 := $(word 1, $(s)).$(word 2, $(s)).$(word 3, $(s)).jffs2
    $(info ${FILENAME_BIN})
    $(info ${FILENAME_JFFS2})
    else
    another.mk : version.txt
        touch $@
    endif
    
    version.txt :
        $(MAKE) -f buildroot.mk
    
    .PHONY: all version.txt
    
    $ make -f another.mk 
    make -f buildroot.mk
    make[1]: Entering directory '~/tmp'
    echo "str1 str2 1.1.0_nightlybuild (1389:1497M@trunk)" > version.txt
    make[1]: Leaving directory '~/tmp'
    touch another.mk
    str1.str2.1.1.0_nightlybuild.bin
    str1.str2.1.1.0_nightlybuild.jffs2
    all has completed.
    
    $ make -f another.mk 
    make -f buildroot.mk
    make[1]: Entering directory '~/tmp'
    make[1]: 'version.txt' is up to date.
    make[1]: Leaving directory '~/tmp'
    touch another.mk
    str1.str2.1.1.0_nightlybuild.bin
    str1.str2.1.1.0_nightlybuild.jffs2
    all has completed.