Пара "ключ-значение" в MAKEFILE - PullRequest
0 голосов
/ 25 мая 2020

Я новичок в makefle, мне нужен массив в makefile, и я обнаружил, что могу добиться этого, имея переменную, в которой их элементы разделены пробелами, а затем повторять ее. Теперь мне нужно что-то вроде пары map (key, value) для хранения значений с ключами. Вопрос: можно ли это сделать в make-файле? Заранее спасибо ..

Ответы [ 2 ]

1 голос
/ 25 мая 2020

Для этого можно использовать вставку токена:

VAR_FOO_KEY := FOO_VAL
VAR_BAR_KEY := BAR_VAL

#example lookup:
KEY := FOO_KEY
LOOKUP_VAL := $(VAR_$(KEY))
0 голосов
/ 16 августа 2020

Создайте файл с именем 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 $4,$(error K0123.mk: args>3 forbidden),      \
    $(if $3,mkdir -p $1.key; echo "$3" > $1.key/$2,   \
    $(if $2,`cat $1.key/$2`,                          \
    $(if $1,rm -fr $1.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».

Этот метод предлагает большую свободу в использовании нескольких словарей с несколькими парами ключ / значение для каждого словаря. Один словарь может использоваться для всего Makefile. Другой словарь может быть использован для всех правил, имеющих общие потребности. Для каждого правила могут использоваться отдельные словари.

Еще один шаг, упрощающий, вот сценарий оболочки, воплощающий идею 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 [ "" != "$1" ] ; then echo "KV error: $1"; fi

    exit 0
}

if [ $1 = "--help" ] ; then usage;
elif [ $1 = "--clear" ] ; then rm -fr *.key;
else
    case $# in
        3) mkdir -p $1.key; echo "$3" > $1.key/$2;;
        2) cat $1.key/$2;;
        1) rm -fr $1.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
...