通过读取另一个文件的内容在makefile中创建变量

通过读取另一个文件的内容在makefile中创建变量,makefile,Makefile,如何从makefile动态创建变量,该变量的值将是另一个数据文件的全部内容。我猜您希望将makefile中的变量设置为另一个文件的内容: FILE=test.txt VARIABLE=`cat $(FILE)` target: echo $(VARIABLE) 假设GNU制造: file := whatever.txt variable := $(shell cat ${file}) cat在Windows上不存在。适用于Linux和Windows的解决方案: cat := $(i

如何从makefile动态创建变量,该变量的值将是另一个数据文件的全部内容。

我猜您希望将makefile中的变量设置为另一个文件的内容:

FILE=test.txt
VARIABLE=`cat $(FILE)`

target:
    echo $(VARIABLE)
假设GNU制造:

file := whatever.txt
variable := $(shell cat ${file})

cat
在Windows上不存在。适用于Linux和Windows的解决方案:

cat := $(if $(filter $(OS),Windows_NT),type,cat)
variable := $(shell $(cat) filename)
说明:
似乎在Windows上总是有
OS
环境变量定义为等于“Windows\u NT”。这样,对于Windows,使用type命令,对于非Windows,使用cat。

由于尚未指定平台,因此它在Solaris上的工作方式如下:

VERSION:sh = cat VERSION

all:
        echo $(VERSION)

GNU make版本4.2支持文件读取操作,因此,关于的伟大答案,现在有一种可选的方法来解决此问题:

FILE     := test.txt
variable :=$(file < $(FILE))
文件:=test.txt
变量:=$(文件<$(文件))
由于添加了
$(文件操作文件名)
,因此更加简单:

VARIABLE = $(file < my_file.txt)
VARIABLE=$(文件

此处的手动页面:

如果您正在使用GNU make,另一种获得此效果的方法是使用另一个make文件的make“include”:

从Makefile:

include "./MyFile.mak"
创建包含以下内容的文件“MyFile.mak”:

FILE := "my file content"
FILE += "more content 1"
FILE += "more content 2"

这里有一个更具可移植性的解决方案,它适用于
MAKE
version 3,其中
file
指令不可用。缺点是需要在此过程中创建一个临时文件

$(shell echo define my_variable > file.tmp)
$(shell cat my_file.txt >> file.tmp)
$(shell echo endef >> file.tmp)
include file.tmp
主要思想是使用
define
指令,该指令专门用于声明多行变量。当然,如果可以显式地编写文件内容以供Makefile使用,则可以避免使用
shell
和临时文件

请记住,如果您的文件包含
$
符号,
MAKE
将在展开
my_variable
时尝试将其作为变量/指令展开(或者在分配时,您可以使用
:=
对其进行定义)。如果您想避免它,您需要在包含文件内容之前对其进行转义。例如,您可以执行以下操作,而不是
cat

$(shell sed 's/\$$/$$$$/g' my_file.txt >> file.tmp)

实际上,我不能把变量定义放在最上面:因为在all:target中运行一些命令之前,PATH_TO_MY_DATA_文件不存在。作为替代,我所做的是将事情拆分为两个makefile(创建了一个子make)并在子make的顶部声明变量,现在它就像一个符咒一样工作。这是一个错误的答案。
变量
的值是一个字符串
cat$(文件)
(引号中),它只能在shell的配方中展开。试着像
$(info${VARIABLE})
@MaximEgorushkin那样打印它的值,这没有错。你只需要考虑<代码>变量< /代码>作为承诺。这是唯一一个可与较早版本的
make
一起使用的版本。
:=
$(shell…
都是GNU扩展。降级。这将在每次执行规则时执行
cat
。这通常不是有意的,应该加以警告,因为它很慢。此外,如果文件是管道,则会产生意外的副作用。赋值应为
:=
,以便在替换变量时,而在定义变量时,不会对规则求值。替换值应为
$(shell cat$(FILE))
,以便
cat
命令由make执行,而不是稍后由配方规则执行。@antred,make是标准UNIX/POSIX工具集的一部分,其中也包括cat。如果您安装make,那么安装所有其他基本工具都是正常的,而且很少有情况会导致任何困难。依靠
cat
而不是复杂的备用规则将使makefile更易于理解,并且几乎可以移植,有时甚至可以移植。@ceving使用标准的GNU make。Solaris make是一个不可移植的应用程序。Gnu make既不是标准的,也比Solaris make更具移植性。“受欢迎”是你的话。如果我们认真考虑可移植性和标准构象,坚持POSIX,我会与“流行”在这种情况下-非GNU制作只是太原始。如果你的目标是继续支持90年代的操作系统,那么@bb generation的答案可能就是你所需要的(尽管在很多情况下它会给你带来麻烦)。在所有其他情况下,GNU Make要么很容易获得,要么更可能是默认值,因此请使用它。GNU Make可以在任何地方运行,因此它比任何其他Make都更易于移植。当然,“标准”可能是主观的。这在GNU Make 4.2.1下对我有效,与其他建议的解决方案不同:)这是在GNU Make 4中引入的,macOS在2019年仍然使用3.81:-(修复了一个错误。变量名区分大小写。名称“foo”、“foo”和“foo”都表示不同的变量。()也不需要引号,$(文件<“$(文件)”)尝试打开“test.txt”。这似乎不起作用,我得到了
Makefile:1:“./MyFile.mak”:没有这样的文件或目录
,这可能意味着您正在使用一个非GNU版本的make…或一个非常旧版本的GNU make…试试:“make-v”使用mac中的make,不确定是否捆绑或由自制安装,
make-v
提供了
GNU make 3.81
您是否确保没有在Makefile中意外地将制表符转换为空格字符?make在这方面几乎和python一样烦人。我通过删除引号在mac上实现了这一点,例如:
I包括./MyFile