Перебор списка аргументов makefile

Я хочу, чтобы мой make-файл анализировал каждую пару arg=value в списке $(cfg) ниже. А затем используйте эти $(аргумент) и $(значение) в make-файле. Эти пары arg=value могут быть разделены пробелом или запятой.

Пример: я хочу переопределить три тестовые переменные (A, B, C) через командную строку.

make run test=my_test.sv cfg="A=3, B=4, C=5"

Makefile должен сделать что-то вроде этого:

foreach $arg,$val in $cfg  ----> +uvm_set_config_int=*,$arg,$val

Эффективный результат:

+uvm_set_config_int=*,A,3
+uvm_set_config_int=*,B,4
+uvm_set_config_int=*,C,5

Моя цель выше - разрешить переопределение любой тестовой конфигурации по умолчанию через командную строку.

Я проверил список переменных аргументов в Makefile, Передача аргументов для запуска, однако это не ответило на мой конкретный вопрос.

Заранее спасибо за помощь.


person Pooja    schedule 15.07.2018    source источник
comment
Почему бы вам не использовать make ... A=3 B=4 C=5? Или имена переменных (A, B, C) могут быть любыми?   -  person uzsolt    schedule 15.07.2018
comment
имена переменных могут быть любыми. Решение Madscientist решает мой случай   -  person Pooja    schedule 17.07.2018


Ответы (2)


Это не может быть правильным:

+uvm_set_config_int=*,A,3
+uvm_set_config_int=*,B,4
+uvm_set_config_int=*,C,5

потому что это просто устанавливает, а затем переопределяет единственное значение +uvm_set_config_int. В конце переменная +uvm_set_config_int будет содержать единственное значение *,C,5, так как это последнее присваивание. Может быть, вы имеете в виду использовать uvm_set_config_int += ... в каждом из вышеперечисленных, чтобы добавить к существующему значению?

Я действительно не понимаю, чего вы пытаетесь достичь здесь.

Однако вот пример того, как сделать то, о чем вы просили, хотя это не имеет особого смысла:

c = ,
$(foreach X,$(subst $c, ,$(cfg)),$(eval +uvm_set_config_int=*,$(subst =,$c,$X)))

Поскольку запятые используются для создания функций, мы должны скрыть их за переменной $c выше. Первый subst превращает запятые в пробелы, так как это то, что используется для разделения слов. Второй преобразовывает = в запятую, так что вы можете изменить A=3 на A,3 и т. д. eval оценивает текст, заданный как строка makefile.

person MadScientist    schedule 15.07.2018

Если вы выполняете некоторую настройку сборки через make, вы можете использовать gmtt, которая представляет собой библиотеку с функциональность, поддерживающая эту задачу. В gmtt можно сформулировать свою задачу так:

include gmtt/gmtt.mk

cfg-table := 2 $(cfg) # make a gmtt-table from the variable

# now select column 1 and 2 from the table for the right test and format the output (without the need to format, just use "select")
smoketest-cfg := $(call map-select,1 2,$(cfg-table),$$(call glob-match,$$1,smoketest*),+uvm_set_config=*$(comma)$$1$(comma)$$2)

regressiontest-cfg := $(call map-select,1 2,$(cfg-table),$$(call glob-match,$$1,regressiontest*),+uvm_set_config=*$(comma)$$1$(comma)$$2)


$(info $(smoketest-cfg))
$(info $(regressiontest-cfg))
$(info -----------------------)
$(info $(subst $(space),$(newline),$(strip $(smoketest-cfg))))

и теперь вы должны иметь возможность называть это так:

make cfg="smoketest-A 1 smoketest-B 2 regressiontest-A 3 regressiontest-B 4"

(gmtt использует таблицы, которые являются просто списками GNUmake, поэтому вы должны использовать пробелы в качестве разделителей элементов и у вас не должно быть пустых «ячеек».)

Выход:

 +uvm_set_config=*,smoketest-A,1 +uvm_set_config=*,smoketest-B,2
 +uvm_set_config=*,regressiontest-A,3 +uvm_set_config=*,regressiontest-B,4
-----------------------
+uvm_set_config=*,smoketest-A,1
+uvm_set_config=*,smoketest-B,2

Обратите внимание, что вам нужно заключать , в выходной формат как $(comma) (переменная, предоставленная gmtt) из-за щедрой обработки символов make, которая принимает почти все в качестве параметра функции, даже \, который, следовательно, не помогает как экранирующий символ.

person Vroomfondel    schedule 17.07.2018