MAKEFILE 中的键值对

Key value pair in MAKEFILE

我是 makefle 的新手,我在 makefile 中需要数组,然后我发现我可以实现具有变量,它们的项目用空格分隔,然后迭代它。 现在我想要像 map(key,value) pair 这样的东西来用键存储值。 问题:我可以把它放在 makefile 中吗? 提前致谢..

您可以为此使用令牌粘贴:

VAR_FOO_KEY := FOO_VAL
VAR_BAR_KEY := BAR_VAL

#example lookup:
KEY := FOO_KEY
LOOKUP_VAL := $(VAR_$(KEY))

使用以下函数定义创建一个名为 KV.mk 的文件:

# KV(3 args): in a dictionary directory record a key value pair in a file
# KV(2 args): in a dictionary directory recover value associated with a key
# KV(1 arg ): remove a dictionary directory
# KV(0 arg ): remove all dictionary directories
define KV
    $(if ,$(error K0123.mk: args>3 forbidden),      \
    $(if ,mkdir -p .key; echo "" > .key/,   \
    $(if ,`cat .key/`,                          \
    $(if ,rm -fr .key/*,                          \
            rm -fr *.key                              \
    ))))
endef

然后制作一个客户端Makefile,内容如下:

include KV.mk

all: hello.cpp hello

.PHONY: hello.cpp
hello.cpp:
    @echo '#include <iostream>' > $@
    @echo 'int main(int argc, char** argv)' >> $@
    @echo '{ std::cout << "hello" << std::endl; return 0; }' >> $@

hello: hello.cpp
    @$(call KV,$@)
    @$(call KV,$@,compiler,g++)
    @$(call KV,$@,compiler) -o hello hello.cpp
    @./$@

clean:
    @rm -f hello.cpp hello
    @$(call KV)

将这两个文件复制到一个空目录中,然后运行“make”。

这种方法在拥有多个词典方面提供了很大的自由度 每个字典有多个 key/value 对。 一个字典可以用于整个 Makefile。 另一个字典可以用于所有具有共同需求的规则。 每个规则都可以使用单独的词典。

再简化一步,这里是一个shell封装了KV思想的脚本

#!/bin/bash

usage() {
    cat <<USAGE
KV(1) -- syre(tm) user command

NAME
    KV - key value store management for Makefile

SYNOPSIS
    (1) KV [--help]
    (2) KV [--clear]
    (3) KV [OPTION]... {key}
    (4) KV [OPTION]... {key}={value}

1: display usage (this text)
2: clear all dictionaries (make clean)
3: print value associated with key
4: store key value pair in the dictionary and key file
USAGE

    if [ "" != "" ] ; then echo "KV error: "; fi

    exit 0
}

if [  = "--help" ] ; then usage;
elif [  = "--clear" ] ; then rm -fr *.key;
else
    case $# in
        3) mkdir -p .key; echo "" > .key/;;
        2) cat .key/;;
        1) rm -fr .key;;
        *) usage "KV error: 1, 2, or 3 args required";;
    esac
fi

这里是显示该简化的同一个 Makefile。

all: hello.cpp hello

.PHONY: hello.cpp
hello.cpp:
    @echo '#include <iostream>' > $@
    @echo 'int main(int argc, char** argv)' >> $@
    @echo '{ std::cout << "hello" << std::endl; return 0; }' >> $@

hello: hello.cpp
    @./KV $@
    @./KV $@ compiler g++
    @`./KV $@ compiler` -o hello hello.cpp
    @./$@

clean:
    @rm -f hello.cpp hello
    @./KV --clear