Shell makefile如何将用户定义的变量写入yaml文件以支持vagrantfile fetch参数

Shell makefile如何将用户定义的变量写入yaml文件以支持vagrantfile fetch参数,shell,makefile,vagrant,yaml,vagrantfile,Shell,Makefile,Vagrant,Yaml,Vagrantfile,我有一个使用makefile来控制vagrant的项目,我想把vagrant参数放入makefile中,比如cpu,内存,ip,主机名,转发端口等等。我发现一个vagrantfile读取yaml文件以参数化vagrantfile。因此makefile需要一个目标来读取所有用户选项变量,并将它们作为键值对写入config.yaml 样本如下 # === BEGIN USER OPTIONS === BOX_OS ?= fedora # Box setup #BOX_IMAGE # Disk set

我有一个使用makefile来控制vagrant的项目,我想把vagrant参数放入makefile中,比如
cpu
内存
ip
主机名
转发端口
等等。我发现一个vagrantfile读取yaml文件以参数化vagrantfile。因此makefile需要一个
目标
来读取所有用户选项变量,并将它们作为
键值
对写入config.yaml

样本如下

# === BEGIN USER OPTIONS ===
BOX_OS ?= fedora
# Box setup
#BOX_IMAGE
# Disk setup
DISK_COUNT ?= 1
DISK_SIZE_GB ?= 25
# VM Resources
MASTER_CPUS ?= 2
MASTER_MEMORY_SIZE_GB ?= 2
NODE_CPUS ?= 2
NODE_MEMORY_SIZE_GB ?= 2

NODE_COUNT ?= 2
# Network
MASTER_IP ?= 192.168.26.10
NODE_IP_NW ?= 192.168.26.
POD_NW_CIDR ?= 10.244.0.0/16

...
...
# === END USER OPTIONS ===
echo
命令确实实现了这一点

# Makefile
envInit:
    @echo "POD_NW_CIDR : \"$(POD_NW_CIDR)\"" > ${FILECWD}/configs.yaml
但是
太多的变量可能太复杂

有没有办法批量读取变量及其值并将其写入yml文件

如果你们能告诉我如何实现批量读取变量及其值并将其写入yml文件,我将不胜感激。

将所有用户选项(以及默认值)定义为一个列表,以便它们是可编辑的:

# list of user options with default values
userOptions = \
  BOX_OS=2 \
  DISK_COUNT=1 \
  MASTER_IP=192.168.26.10

# replace each default value with the env value, if any
userOptionValues = $(foreach i, $(userOptions), \
  $(word 1, $(subst =, ,$i))=$(or \
      $($(word 1, $(subst =, ,$i))), $($(word 1, $(subst =, ,$i))), $(word 2, $(subst =, ,$i))))

# write the yaml file
envInit:
# empty the file
    @printf "" > configs.yaml
# write a line for each option
    @for i in $(userOptionValues); do \
        printf "%s : %s\n" "$$(printf $$i | cut -d= -f1)" "$$(printf $$i | cut -d= -f2)" >> configs.yaml; \
    done

@flyx感谢您的回答,您的代码工作得很好。但我似乎找到了一个更好的方法,我对它进行了部分修改

printvars:
    @echo$(foreach V,$(sort $(.VARIABLES)), \
        $(if $(filter-out environment% default automatic,$(origin $V)),$(info $V: $($V))))
但在实现这一目标之间仍然存在差距

# the Makefile test file
FILECWD = $(shell pwd)

# === BEGIN USER OPTIONS ===
CLOUD_IP ?= 192.168.79.222
CLOUD_NAME ?= cloud
CLOUD_CPU ?= 6
CLOUD_MEMORY ?= 8


# === END USER OPTIONS ===

printvars:  
    @echo$(foreach V,$(sort $(.VARIABLES)), \
        $(if $(filter-out environment% default automatic,$(origin $V)),$(info $V: $($V))))
make printvars
的输出包含许多其他变量

$ make printvars 
.DEFAULT_GOAL: printvars
CLOUD_IP: 192.168.79.222
CLOUD_MEMORY: 8
CLOUD_NAME: cloud
CURDIR: /testmakecreateyml0930
FILECWD: /testmakecreateyml0930
GNUMAKEFLAGS: 
MAKEFILE_LIST:  Makefile
MAKEFLAGS: 
SHELL: /bin/sh
而且它只能打印,不能导出到yaml文件。这离成功只有一步之遥


如果您能帮助我修改它以实现我的目标,我将不胜感激

您可以使用
GNUmake
s
$(文件)
功能直接写入文件:

define newline :=
$(strip)
$(strip)
endef
space := $(strip) $(strip)#
-never-matching := ¥# character 165, this is used as a list element that should never appear as a real element

option-names = $(subst $(-never-matching),,$(filter $(-never-matching)%,$(subst $(-never-matching)$(space),$(-never-matching),$(-never-matching)$(strip $(subst $(newline), $(-never-matching),$1)))))


# define your user options in as many separate parts as you like, spaces and empty lines included:
define USER_OPTIONS +=
a = spaces are no problem

b = "neither nearly all 'other' characters: 8&)("
endef

define USER_OPTIONS +=

c = baz baf
d = foobar
endef

# make all definition make variables verbatim 
$(eval $(USER_OPTIONS))

YAML_FORMAT := $(foreach name,$(call option-names,$(USER_OPTIONS)),$(newline)$(name) : $($(name)))

# write the file. Warning: this happens before any rule is run!
$(file >test.yaml,$(YAML_FORMAT))

$(info $(foreach name,$(call option-names,$(USER_OPTIONS)),<$(name) : $($(name))> ))
定义换行符:=
$(条)
$(条)
恩德夫
空格:=$(条带)$(条带)#
-从不匹配:=¥#字符165,用作永远不应显示为真实元素的列表元素
选项名称=$(subst$(-从不匹配),,$(filter$(-从不匹配)%,$(subst$(-从不匹配)$(空格),$(-从不匹配),$(-从不匹配)$(strip$(subst$(换行符),$(-从不匹配),$1);)
#在任意多个单独的部分中定义用户选项,包括空格和空行:
定义用户选项+=
a=空格没有问题
b=“几乎所有‘其他’字符都不是:8&)(”
恩德夫
定义用户选项+=
c=baz-baf
d=foobar
恩德夫
#使所有定义一字不差地生成变量
$(评估$(用户选项))
YAML_格式:=$(foreach名称,$(调用选项名称,$(用户选项)),$(换行符)$(名称):$($(名称)))
#写入文件。警告:这发生在任何规则运行之前!
$(文件>test.yaml,$(yaml_格式))
$(信息$(foreach名称,$(调用选项名称,$(用户选项)),)
诀窍在于将所有相关的用户选项变量聚集在一个多行make变量中。函数
option names
将该变量中的所有标识符拉到一个单独的列表中


我使用了
换行符
等字符定义,其中有许多“编程”功能make.

用户选项在
make
中是否有任何功能?或者它只是文本?用户选项可以用作make文件、vagrant文件或vagrant虚拟机中的变量,例如vagrant虚拟机中python程序的参数、vagrant文件中的IP参数和
vagrant up${流浪者的名字}
这有一个问题,即选项中不能有空格。感谢您的回答以解决此问题。我找到了另一种实现方法,但有一个问题,请帮助我回答。再次感谢。请参阅以下@flyx内容。@Vroomfondel是。如果您想在值中包含空格,则可能需要生成文件。\n我把变量放在一个列表值中以避免这个问题。你需要以某种方式告诉Makefile哪些变量应该放在YAML文件中,哪些不应该,而这个解决方案不会这样做。