我正在做我的CS作业,其中包含许多单文件程序。我的工作目录如下所示:
133.c 134.c 220.c 281.c 337.c 338.c 339.c makefile
我写了一个像这样的Makefile:
%: %.c
${CC} ${CFLAGS} -o $@ $^
因此,当我想编译问题220的程序时,我输入:
ibug@wsl:~ $ make 220
gcc -o 220 220.c
ibug@wsl:~ $
我想写一个clean-%
规则,这样当我在shell中运行它时,结果应该如下所示
ibug@wsl:~ $ make clean-133
rm -f 133
ibug@wsl:~ $ make clean-281
rm -f 281
ibug@wsl:~ $ make clean-337
rm -f 337
我已经走了这么远:
.PHONY: clean-%
SRC = $(wildcard %.c)
BIN = $(patsubst %.c,%,$(SRC))
clean-%:
rm -f ??????
我应该用什么来代替问号?
我正在使用GNU Make 4.1(在Windows的Linux子系统上)。
答案 0 :(得分:4)
您正在寻找automatic variable $*
,其中包含词干(即与%
匹配的部分):
clean-%:
rm -f $*
但是,继续阅读。
将先决条件clean-%
添加到.PHONY
目标:
.PHONY: clean-%
不会将模式规则 clean-%
转换为虚假目标,而是转变显式规则,其实际目标名称是clean-%
(不是模式),变成虚假的目标。
原因是只有显式规则的目标可以成为虚假目标,模式不能成为假目标。因此,看起来像模式的虚假目标(即包含%
)实际上并不是一种模式(即,%
实际上是%
)。
添加所有可能的值clean-%
可以与.PHONY
无法帮助匹配,因为虚假目标 不匹配隐式模式规则。所以,如果你这样做:
.PHONY: clean-foo
clean-foo
永远不会匹配隐式模式规则(即,它永远不会与您的clean-%
模式规则匹配)。
clean-xxx
定义为虚假目标我猜你确实希望这些clean-xxx
目标是虚假目标,因为这些目标不代表文件系统上的实际文件。
与隐式模式规则不同,static pattern rules可以匹配虚假目标。以下方法包括定义一个可以匹配clean-xxx
虚假目标的静态模式规则:
list := $(patsubst %.c,%,$(wildcard *.c))
# list of clean-xxx targets
clean-targets := $(addprefix clean-,$(list))
.PHONY: $(clean-targets)
$(clean-targets): clean-%:
rm -f $*
上面的静态模式规则将匹配其目标列表中指定的任何clean-xxx
虚假目标(即$(clean-targets)
。
以下方法包括将这些clean-xxx
规则动态生成为显式规则而不是单个模式规则:
list := $(patsubst %.c,%,$(wildcard *.c))
define create-clean-target
$(eval .PHONY: clean-$1);
$(eval clean-$1:; rm -f $1)
endef
# dynamically generate the clean-xxx targets
$(foreach t,$(list),$(call create-clean-target,$t))
用户定义函数create-target
定义显式目标clean-xxx
,传递给函数的参数为xxx
。由于要定义的目标是一个明确的目标,因此它也可以成为假的目标。
答案 1 :(得分:1)
使用您的文件命名约定,您不需要任何makefile ,因为GNU Make's built-in rules已经执行了您想要的操作。试试这个:
$ mv Makefile Makefile.bak
$ rm -f 220
$ make 220 # make magic happening here!
$ rm -f 220
$ make CC=cc CFLAGS="-Wall -O2" 220
如您所见, make 知道如何使用C编译器将 foo .c转换为 foo 可执行文件。
要检索内置规则列表,请在不存在Makefile的情况下运行make -p
。
至于清理可执行文件,为什么如此冗长并在make clean-NNN
或rm -f NNN
输入rm -f [0-9]??
时输入AsyncTaskHandleJson().execute(url)
inner class AsyncTaskHandleJson : AsyncTask<String, String, String>() {
override fun doInBackground(vararg url: String?): String {
var text: String
var connection = URL(url[0]).openConnection() as HttpURLConnection
try {
connection.connect()
text = connection.inputStream.use { it.reader().use { reader -> reader.readText() } }
} finally {
connection.disconnect()
}
return text
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson(result)
}
}
?