Meson中与Makefile的patsubst等效的功能如何实现?
在Meson中批量替换文件名后缀(如.ts转.js)
问题场景
在Makefile中,我们可以通过$(input:.ts=.js)快速将一组.ts文件列表转换为对应的.js输出文件列表。但在Meson中直接套用类似思路会遇到以下问题:
尝试1:使用@BASENAME@占位符
js = custom_target( 'compile-ts', input: ts, command: [ tsc, '-p', tsconfig, '--outDir', '.' ], output: '@BASENAME@.js' )
报错信息:
ERROR: custom_target: output cannot contain "@PLAINNAME@" or "@BASENAME@" when there is more than one input
原因:当custom_target传入多个输入文件时,无法使用这类单文件占位符生成批量输出列表。
尝试2:直接调用数组的replace()方法
... output: sources.replace('.ts', '.js')
报错信息:
ERROR: Unknown method "replace" in object <[ArrayHolder] holds [list]: ['main.ts', 'window.ts']> of type ArrayHolder.
原因:replace()是字符串对象的专属方法,不能直接作用于Meson的数组对象。
临时解决方法:foreach循环
可以通过遍历数组逐个替换后缀,但写法不够简洁:
javascript = [] foreach ts: typescript javascript += ts.replace('.ts', '.js') endforeach
更优雅的解决方案
从Meson 0.55版本开始,支持列表推导式,可以一行完成批量替换:
javascript = [f.replace('.ts', '.js') for f in typescript]
这种写法和Makefile的$(input:.ts=.js)一样简洁,直接对数组中的每个字符串元素调用replace()方法,生成新的输出文件列表。
如果需要在custom_target中直接使用,也可以内嵌这个推导式:
js = custom_target( 'compile-ts', input: typescript, command: [tsc, '-p', tsconfig, '--outDir', meson.current_build_dir()], output: [f.replace('.ts', '.js') for f in typescript] )
注意:确保你的Meson版本不低于0.55,如果版本较低,只能使用foreach循环的方式。
内容的提问来源于stack exchange,提问作者ea7ababe
相关产品推荐
相关产品推荐

