Ответы:
Следующее будет делать, если, как я предполагаю, вы используете ./a.outплатформу UNIX.
for number in 1 2 3 4 ; do \
./a.out $$number ; \
done
Тест следующим образом:
target:
for number in 1 2 3 4 ; do \
echo $$number ; \
done
производит:
1
2
3
4
Для больших диапазонов используйте:
target:
number=1 ; while [[ $$number -le 10 ]] ; do \
echo $$number ; \
((number = number + 1)) ; \
done
Это выводит от 1 до 10 включительно, просто измените whileусловие завершения с 10 на 1000 для гораздо большего диапазона, как указано в вашем комментарии.
Вложенные циклы можно сделать так:
target:
num1=1 ; while [[ $$num1 -le 4 ]] ; do \
num2=1 ; while [[ $$num2 -le 3 ]] ; do \
echo $$num1 $$num2 ; \
((num2 = num2 + 1)) ; \
done ; \
((num1 = num1 + 1)) ; \
done
производство:
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
4 1
4 2
4 3
seqкоманда, которая генерирует последовательность чисел, существует в большинстве (всех?) Unix-систем, поэтому вы можете написать for number in ``seq 1 1000``; do echo $$number; done(Поставьте один знак обратной галочки на каждой стороне команды seq, а не две, я не знаю, как правильно отформатировать это используя синтаксис stackoverflow)
makeобычно каждая строка обрабатывается как отдельная суб-оболочка. Без продолжения он попытался бы запустить подоболочку только с (например) for number in 1 2 3 4 ; do, без остальной части цикла. С ним это фактически становится единственной линией формы while something ; do something ; done, которая является полным утверждением. $$Вопрос ответил здесь: stackoverflow.com/questions/26564825/... , с кодом , казалось бы , извлеченным из этого самого ответа :-)
Если вы используете GNU make, вы можете попробовать
НОМЕРА = 1 2 3 4
сделай это:
$ (foreach var, $ (NUMBERS),. / a.out $ (var);)
который будет генерировать и выполнять
./a.out 1; ./a.out 2; ./a.out 3; ./a.out 4;
./a.out 1. ./a.out 2будет выполняться независимо.
Основная причина использования делают ИМХО это -jфлаг. make -j5будет запускать 5 команд оболочки одновременно. Это хорошо, если у вас 4 процессора, и хороший тест любого make-файла.
По сути, вы хотите, чтобы make увидел что-то вроде:
.PHONY: all
all: job1 job2 job3
.PHONY: job1
job1: ; ./a.out 1
.PHONY: job2
job2: ; ./a.out 2
.PHONY: job3
job3: ; ./a.out 3
Это -jдружелюбно (хороший знак). Можете ли вы определить котельную плиту? Мы могли бы написать:
.PHONY: all job1 job2 job3
all: job1 job2 job3
job1 job2 job3: job%:
./a.out $*
для того же эффекта (да, это то же самое, что и предыдущая формулировка, что касается make , только немного более компактно).
Еще немного о параметризации, так что вы можете указать ограничение в командной строке (утомительно, поскольку makeне имеет хороших арифметических макросов, поэтому я буду жульничать здесь и использовать $(shell ...))
LAST := 1000
NUMBERS := $(shell seq 1 ${LAST})
JOBS := $(addprefix job,${NUMBERS})
.PHONY: all ${JOBS}
all: ${JOBS} ; echo "$@ success"
${JOBS}: job%: ; ./a.out $*
Вы запускаете это make -j5 LAST=550со значением по LASTумолчанию 1000.
.PHONY: all, make будет искать файл с именем all. Если такой файл существует, make затем проверяет время последнего изменения этого файла, и makefile почти наверняка не будет выполнять то, что вы хотели. .PHONYДекларация говорит сделать , что allявляется символической мишенью. Поэтому Make будет считать allцель всегда устаревшей. Отлично. Смотрите руководство.
%в правиле, доступно как $*в рецепте.
Я понимаю, что этому вопросу уже несколько лет, но этот пост все еще может быть полезен кому-то, поскольку он демонстрирует подход, который отличается от вышеупомянутого и не зависит ни от операций оболочки, ни от необходимости для разработчика выделять жестко закодированный строка числовых значений.
встроенный макрос $ (eval ....) - ваш друг. Или может быть по крайней мере.
define ITERATE
$(eval ITERATE_COUNT :=)\
$(if $(filter ${1},0),,\
$(call ITERATE_DO,${1},${2})\
)
endef
define ITERATE_DO
$(if $(word ${1}, ${ITERATE_COUNT}),,\
$(eval ITERATE_COUNT+=.)\
$(info ${2} $(words ${ITERATE_COUNT}))\
$(call ITERATE_DO,${1},${2})\
)
endef
default:
$(call ITERATE,5,somecmd)
$(call ITERATE,0,nocmd)
$(info $(call ITERATE,8,someothercmd)
Это упрощенный пример. При больших значениях он не будет хорошо масштабироваться - он работает, но поскольку строка ITERATE_COUNT будет увеличиваться на 2 символа (пробел и точка) для каждой итерации, когда вы поднимаетесь на тысячи, для подсчета слов требуется все больше времени. Как написано, он не обрабатывает вложенные итерации (для этого вам понадобится отдельная функция итерации и счетчик). Это чисто gnu make, не требующий оболочки (хотя, очевидно, OP пытался запустить программу каждый раз - здесь я просто отображаю сообщение). If в ITERATE предназначено для перехвата значения 0, потому что в противном случае $ (word ...) выдаст ошибку.
Обратите внимание, что растущая строка, служащая счетчиком, используется потому, что встроенная переменная $ (words ...) может обеспечить арабский счет, но в противном случае make не поддерживает математические операции (вы не можете присвоить 1 + 1 чему-либо и получить 2, если вы не вызываете что-то из оболочки, чтобы выполнить это для вас, или используете не менее сложную макрооперацию). Это прекрасно работает для счетчика ИНКРЕМЕНТОВ, но не так хорошо для счетчика УМЕНЬШЕНИЯ.
Я сам этим не пользуюсь, но в последнее время мне нужно было написать рекурсивную функцию для оценки библиотечных зависимостей в многобинарной, многобиблиотечной среде сборки, где вам нужно знать, чтобы использовать ДРУГИЕ библиотеки, когда вы включаете какую-то библиотеку, которая сам по себе имеет другие зависимости (некоторые из которых варьируются в зависимости от параметров сборки), и я использую метод $ (eval) и counter, аналогичный приведенному выше (в моем случае счетчик используется, чтобы гарантировать, что мы каким-то образом не перейдем к бесконечному цикл, а также в качестве диагностики, чтобы сообщить, сколько итераций было необходимо).
Что-то еще ничего не стоящее, хотя и незначительное для Q оператора Q: $ (eval ...), предоставляет метод, позволяющий обойти внутреннее отвращение make к циклическим ссылкам, что хорошо и хорошо для применения, когда переменная является типом макроса (инициализируется с помощью =), по сравнению с немедленным назначением (инициализируется с помощью: =). Иногда вы хотите иметь возможность использовать переменную в своем собственном присваивании, и $ (eval ...) позволит вам сделать это. Здесь важно учесть, что во время запуска eval переменная разрешается, а разрешенная часть больше не рассматривается как макрос. Если вы знаете, что делаете, и пытаетесь использовать переменную RHS для присвоения себе, это, как правило, то, что вы хотите в любом случае произойти.
SOMESTRING = foo
# will error. Comment out and re-run
SOMESTRING = pre-${SOMESTRING}
# works
$(eval SOMESTRING = pre${SOMESTRING}
default:
@echo ${SOMESTRING}
Счастливый макияж.
Для кроссплатформенной поддержки настройте разделитель команд (для выполнения нескольких команд в одной строке).
Если вы используете MinGW на платформе Windows, например, разделитель команд &:
NUMBERS = 1 2 3 4
CMDSEP = &
doit:
$(foreach number,$(NUMBERS),./a.out $(number) $(CMDSEP))
Это выполняет объединенные команды в одну строку:
./a.out 1 & ./a.out 2 & ./a.out 3 & ./a.out 4 &
Как уже упоминалось, на платформе * nix CMDSEP = ;.
Это не совсем чистый ответ на вопрос, а разумный способ обойти такие проблемы:
вместо того, чтобы писать сложный файл, просто делегируйте управление, например, скрипту bash, например: makefile
foo : bar.cpp baz.h
bash script.sh
и script.sh выглядит так:
for number in 1 2 3 4
do
./a.out $number
done
eval echo \$${$(var)}; \ echo $$ var1; \ ((NUM = NUM + 1)); \ done all: set_var here SSA_CORE0_MAINEXEC - это переменная среды, которая уже установлена. Поэтому я хочу, чтобы это значение было оценено или напечатано с использованием переменной var1. Я попробовал это, как показано выше, но не работает. пожалуйста помоги.
bashи, таким образом, использовать эти функции. Цикл является одной из особенностей, для которой это можно продемонстрировать.
Вы можете использовать set -eв качестве префикса для цикла for. Пример:
all:
set -e; for a in 1 2 3; do /bin/false; echo $$a; done
makeвыйдет сразу с кодом выхода <> 0.
Хотя инструментарий таблиц GNUmake имеет истинный whileцикл (что бы это ни значило в программировании GNUmake с его двумя или тремя фазами выполнения), если вещь, которая необходима, - это итеративный список, есть простое решение с помощью interval. Для удовольствия мы также конвертируем числа в шестнадцатеричные:
include gmtt/gmtt.mk
# generate a list of 20 numbers, starting at 3 with an increment of 5
NUMBER_LIST := $(call interval,3,20,5)
# convert the numbers in hexadecimal (0x0 as first operand forces arithmetic result to hex) and strip '0x'
NUMBER_LIST_IN_HEX := $(foreach n,$(NUMBER_LIST),$(call lstrip,$(call add,0x0,$(n)),0x))
# finally create the filenames with a simple patsubst
FILE_LIST := $(patsubst %,./a%.out,$(NUMBER_LIST_IN_HEX))
$(info $(FILE_LIST))
Вывод:
./a3.out ./a8.out ./ad.out ./a12.out ./a17.out ./a1c.out ./a21.out ./a26.out ./a2b.out ./a30.out ./a35.out ./a3a.out ./a3f.out ./a44.out ./a49.out ./a4e.out ./a53.out ./a58.out ./a5d.out ./a62.out
#I have a bunch of files that follow the naming convention
#soxfile1 soxfile1.o soxfile1.sh soxfile1.ini soxfile1.txt soxfile1.err
#soxfile2 soxfile2.o soxfile2.sh soxfile2.ini soxfile2.txt soxfile2.err
#sox... .... ..... .... .... ....
#in the makefile, only select the soxfile1.. soxfile2... to install dir
#My GNU makefile solution follows:
tgt=/usr/local/bin/ #need to use sudo
tgt2=/backup/myapplication/ #regular backup
install:
for var in $$(ls -f sox* | grep -v '\.' ) ; \
do \
sudo cp -f $$var ${TGT} ; \
cp -f $$var ${TGT2} ; \
done
#The ls command selects all the soxfile* including the *.something
#The grep command rejects names with a dot in it, leaving
#My desired executable files in a list.