在 Makefile 中将 *.po 重命名为 *.mo
Rename *.po to *.mo in Makefile
我需要将./lang/文件夹中的所有*.po翻译文件转换成*.mo文件。
在 Makefile 的 "i18n" 目标中,我写了:
i18n:
@for file in $(wildcard ./lang/*.po); do\
msgfmt $$file -o $(subst po,mo,$$file); \
done
然而,这段代码不起作用;而且,所有的*.po文件都损坏了。
文件夹中有 3 个文件,对于每个文件我得到:
./lang/uk_UK.po:1:2: syntax error
./lang/uk_UK.po:2: line terminator inside the line
./lang/uk_UK.po:3: Unknown key word «G»
./lang/uk_UK.po:4: Unknown key word «P»
./lang/uk_UK.po:5: Unknown key word «A»
./lang/uk_UK.po:6: Unknown key word «Z»
./lang/uk_UK.po:9: line terminator inside the line
./lang/uk_UK.po:10: Unknown key word «Report»
./lang/uk_UK.po:11: Unknown key word «POT»
./lang/uk_UK.po:12: Unknown key word «PO»
./lang/uk_UK.po:13: Unknown key word «Last»
./lang/uk_UK.po:14: Unknown key word «Language»
./lang/uk_UK.po:15: Unknown key word «Language»
./lang/uk_UK.po:16: Unknown key word «MIME»
./lang/uk_UK.po:17: Unknown key word «Content»
./lang/uk_UK.po:18: Unknown key word «Content»
./lang/uk_UK.po:19: Unknown key word «Entangle»
./lang/uk_UK.po:20: Unknown key word «AES»
因此,该命令似乎在 msgfmt 获取文件之前修改了文件。
我花了很多时间尝试不同的解决方案。我遇到了三种类型的问题:
1) 语法错误 - 循环不正确
2) 替换不正确
3) 损坏的翻译文件
我的代码有什么问题?
您的问题是您将 make 函数(和 make 上下文)与 shell functionality/variables(和 shell 上下文)混合使用。
i18n:
@for file in $(wildcard ./lang/*.po); do\
msgfmt $$file -o $(subst po,mo,$$file); \
done
$(wildcard)
和 $(subst)
函数在生成解析时(或适当的变量扩展时)扩展。 shell for 循环在 shell 执行时运行。
因此,虽然您的 $(wildcard)
在 shell 脚本运行之前正确执行(并为您的 for
循环提供一些可以操作的东西),因此可以正常工作(某种程度上) $(subst)
调用 also 在 shell 脚本运行之前执行,因此对字面值 $$file
而不是 shell 变量的扩展进行操作$file
.
在这种情况下,事实证明,您可能不希望$(wildcard)
或$(subst)
和而是想要这样的东西:
.PHONY: i18n
i18n:
@for file in ./lang/*.po; do\
msgfmt $$file -o "$${file/%po/mo}"; \
done
.PHONY: i18n
行对于确保 make target 正常工作是必要的,如果 i18n
文件被任何东西创建的话。
如果 "$${file/%po/mo}"
扩展失败,那么应该使用 "$${foo%po}mo"
代替。 //
扩展(用于模式替换)可能是 bash 主义,但 %
扩展(用于后缀删除)是 POSIX.
话虽如此,但实际上您可能想要使用更像这样的东西:
.PHONY: i18n
i18n: $(PO_FILES:po=mo)
%.mo: %.po
msgfmt $< -o $@
让凑合 "does this .mo
file need updating" checking/etc。并更有效地使用 make 为您做的事情。
我需要将./lang/文件夹中的所有*.po翻译文件转换成*.mo文件。 在 Makefile 的 "i18n" 目标中,我写了:
i18n:
@for file in $(wildcard ./lang/*.po); do\
msgfmt $$file -o $(subst po,mo,$$file); \
done
然而,这段代码不起作用;而且,所有的*.po文件都损坏了。
文件夹中有 3 个文件,对于每个文件我得到:
./lang/uk_UK.po:1:2: syntax error
./lang/uk_UK.po:2: line terminator inside the line
./lang/uk_UK.po:3: Unknown key word «G»
./lang/uk_UK.po:4: Unknown key word «P»
./lang/uk_UK.po:5: Unknown key word «A»
./lang/uk_UK.po:6: Unknown key word «Z»
./lang/uk_UK.po:9: line terminator inside the line
./lang/uk_UK.po:10: Unknown key word «Report»
./lang/uk_UK.po:11: Unknown key word «POT»
./lang/uk_UK.po:12: Unknown key word «PO»
./lang/uk_UK.po:13: Unknown key word «Last»
./lang/uk_UK.po:14: Unknown key word «Language»
./lang/uk_UK.po:15: Unknown key word «Language»
./lang/uk_UK.po:16: Unknown key word «MIME»
./lang/uk_UK.po:17: Unknown key word «Content»
./lang/uk_UK.po:18: Unknown key word «Content»
./lang/uk_UK.po:19: Unknown key word «Entangle»
./lang/uk_UK.po:20: Unknown key word «AES»
因此,该命令似乎在 msgfmt 获取文件之前修改了文件。
我花了很多时间尝试不同的解决方案。我遇到了三种类型的问题:
1) 语法错误 - 循环不正确
2) 替换不正确
3) 损坏的翻译文件
我的代码有什么问题?
您的问题是您将 make 函数(和 make 上下文)与 shell functionality/variables(和 shell 上下文)混合使用。
i18n:
@for file in $(wildcard ./lang/*.po); do\
msgfmt $$file -o $(subst po,mo,$$file); \
done
$(wildcard)
和 $(subst)
函数在生成解析时(或适当的变量扩展时)扩展。 shell for 循环在 shell 执行时运行。
因此,虽然您的 $(wildcard)
在 shell 脚本运行之前正确执行(并为您的 for
循环提供一些可以操作的东西),因此可以正常工作(某种程度上) $(subst)
调用 also 在 shell 脚本运行之前执行,因此对字面值 $$file
而不是 shell 变量的扩展进行操作$file
.
在这种情况下,事实证明,您可能不希望$(wildcard)
或$(subst)
和而是想要这样的东西:
.PHONY: i18n
i18n:
@for file in ./lang/*.po; do\
msgfmt $$file -o "$${file/%po/mo}"; \
done
.PHONY: i18n
行对于确保 make target 正常工作是必要的,如果 i18n
文件被任何东西创建的话。
如果 "$${file/%po/mo}"
扩展失败,那么应该使用 "$${foo%po}mo"
代替。 //
扩展(用于模式替换)可能是 bash 主义,但 %
扩展(用于后缀删除)是 POSIX.
话虽如此,但实际上您可能想要使用更像这样的东西:
.PHONY: i18n
i18n: $(PO_FILES:po=mo)
%.mo: %.po
msgfmt $< -o $@
让凑合 "does this .mo
file need updating" checking/etc。并更有效地使用 make 为您做的事情。