我有一个makefile,它在不同的位置生成一堆图像版本:
website/img/logo_256.png
website/img/logo_152.png
/tmp/logo_64.png
等等(/tmp/生成是这样,因此以后我可以使用这些文件来生成多分辨率
.ico
,其细节并不重要)。我想要一个规则
logo_%.png: ${SRC}
convert $^ -thumbnail $*x$* $@
但是,
$*
也引入了匹配的目录,所以我得到了以下形式的命令:convert logo_1024.png -thumbnail /tmp/64x/tmp/64 /tmp/logo_64.png
这是不正确的(我需要
48x48
,而不是/tmp/48x/tmp/48
)。或者我可以写
/tmp/logo_%.png: ${SRC}
convert $^ -thumbnail $*x$* $@
website/img/logo_%.png: ${SRC}
convert $^ -thumbnail $*x$* $@
这看起来很丑。
我敢肯定有很多方法可以分解和匹配
$@
以获得我想要的东西,但是我不是makefile专家,所以这需要一些研究。最简单的方法是什么?
最佳答案
请参阅GNU Make手册中Automatic Variables的后半部分:
Of the variables listed above, four have values that are single file names, and three have values that are lists of file names. These seven have variants that get just the file's directory name or just the file name within the directory. The variant variables' names are formed by appending ‘D’ or ‘F’, respectively. These variants are semi-obsolete in GNU make since the functions dir and notdir can be used to get a similar effect (see Functions for File Names). Note, however, that the ‘D’ variants all omit the trailing slash which always appears in the output of the dir function. Here is a table of the variants:
‘$(@D)’
The directory part of the file name of the target, with the trailing slash removed. If the value of ‘$@’ is dir/foo.o then ‘$(@D)’ is dir. This value is . if ‘$@’ does not contain a slash.
‘$(@F)’
The file-within-directory part of the file name of the target. If the value of ‘$@’ is dir/foo.o then ‘$(@F)’ is foo.o. ‘$(@F)’ is equivalent to ‘$(notdir $@)’.
‘$(*D)’
‘$(*F)’
The directory part and the file-within-directory part of the stem; dir and foo in this example.
‘$(%D)’
‘$(%F)’
The directory part and the file-within-directory part of the target archive member name. This makes sense only for archive member targets of the form archive(member) and is useful only when member may contain a directory name. (See Archive Members as Targets.)
‘$(<D)’
‘$(<F)’
The directory part and the file-within-directory part of the first prerequisite.
‘$(^D)’
‘$(^F)’
Lists of the directory parts and the file-within-directory parts of all prerequisites.
‘$(+D)’
‘$(+F)’
Lists of the directory parts and the file-within-directory parts of all prerequisites, including multiple instances of duplicated prerequisites.
‘$(?D)’
‘$(?F)’
Lists of the directory parts and the file-within-directory parts of all prerequisites that are newer than the target.
编辑:
在@Ian的评论提示下,我再次看了看,意识到这不是一个完整的解决方案。完整的解决方案如下。
上面的
F
修饰符(和$(notdir)
函数)将从目标文件名中删除路径。那是必要的一部分。需要额外的操作才能从目标中仅提取数字分量(如
/some/path/logo_64.png
)。$(basename)
函数将删除后缀(以及$(patsubst %.png,%,$@)
或$(@:%.png=)
以更特定的方式显示)。结合我们从
/some/path/logo_64.png
到logo_64
所获得的内容。此时的处理在很大程度上取决于数据将是什么样子以及可以做出哪些断言。如果logo_
是静态前缀,那么一个简单的$(patsubst logo_%,%,...)
就可以工作(匹配的替换引用也将像以前一样)。如果不能保证,但是可以保证维将是最后一个下划线分隔的组件,则可以使用
$(lastword $(subst _, ,...))
。关于makefile - 在makefile规则中提取匹配项的一部分,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25972358/