我想执行以下命令:
./a.out 1
./a.out 2
./a.out 3
./a.out 4
.
.
. and so on
如何写这个东西作为一个循环在Makefile?
我想执行以下命令:
./a.out 1
./a.out 2
./a.out 3
./a.out 4
.
.
. and so on
如何写这个东西作为一个循环在Makefile?
当前回答
如果您正在使用GNU make,您可以尝试一下
NUMBERS = 1 2 3 4 doit: $(foreach var,$(NUMBERS),./a.out $(var);)
哪个将生成并执行
./a.out 1; ./a.out 2; ./a.out 3; ./a.out 4;
其他回答
#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.
在循环中动态地分配变量
1 2 3 4中for数的问题;做…-solution是,在循环中没有变量可以赋值。$(eval VAR=…)只能在目标执行开始时已知赋值内容的情况下使用。如果赋值依赖于循环变量,VAR将为空。
为了避免这个问题,可以使用目标功能对循环建模。下面的例子从SRC / OBJ获取第n个文件,并将它们一起处理。使用这种结构,您甚至可以使用$(eval…)来处理循环变量,如VAR3所示。
makefile
SRC = f1.c f2.cpp f3.cpp
OBJ = f1.o f2.o f3.o
SRC2 = $(addsuffix _,$(SRC))
JOIN = $(join $(SRC2),$(OBJ))
PHONY: all
all : info loop
loop : $(JOIN)
$(JOIN) :
@# LOOP - CONTENT
@echo "TARGET: $@"
$(eval VAR1=$(word 1,$(subst _, ,$@)))
@echo "VAR1: "$(VAR1)
$(eval VAR2=$(word 2,$(subst _, ,$@)))
@echo "VAR2: "$(VAR2)
$(eval VAR3=$(subst .o,.x,$(VAR2)))
@echo "You can even substitute you loop variable VAR3: "$(VAR3)
#g++ -o $(VAR2) $(VAR1)
@echo
PHONY: info
info:
@printf "\n"
@echo "JOIN: "$(JOIN)
@printf "\n"
输出
$ make
JOIN: f1.c_f1.o f2.cpp_f2.o f3.cpp_f3.o
TARGET: f1.c_f1.o
VAR1: f1.c
VAR2: f1.o
You can even substitute you loop variable VAR3: f1.x
#g++ -o f1.o f1.c
TARGET: f2.cpp_f2.o
VAR1: f2.cpp
VAR2: f2.o
You can even substitute you loop variable VAR3: f2.x
#g++ -o f2.o f2.cpp
TARGET: f3.cpp_f3.o
VAR1: f3.cpp
VAR2: f3.o
You can even substitute you loop variable VAR3: f3.x
#g++ -o f3.o f3.cpp
尽管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
一个简单的、独立于shell/平台的纯宏解决方案是…
# GNU make (`gmake`) compatible; ref: <https://www.gnu.org/software/make/manual>
define EOL
$()
endef
%sequence = $(if $(word ${1},${2}),$(wordlist 1,${1},${2}),$(call %sequence,${1},${2} $(words _ ${2})))
.PHONY: target
target:
$(foreach i,$(call %sequence,10),./a.out ${i}${EOL})
如果您正在使用GNU make,您可以尝试一下
NUMBERS = 1 2 3 4 doit: $(foreach var,$(NUMBERS),./a.out $(var);)
哪个将生成并执行
./a.out 1; ./a.out 2; ./a.out 3; ./a.out 4;