如何在Make中为多语言目录结构定义依赖生成.mo文件?
Makefile中用msgfmt生成.mo文件的规则修复方案
问题根因
你尝试的%.mo:%.po或$(buildpath)/locale/%/LC_MESSAGES/%.mo: $(projectpath)/locale/%/LC_MESSAGES/%.po模式失效,是因为Make的模式规则里%只能匹配单个连续路径片段,无法同时对应语言目录和文件名两个独立部分,导致Make无法关联源文件和目标文件。
有效解决方案
方案1:静态模式规则(推荐)
直接复用你已定义的PO_FILES和MO_FILES变量,建立一对一的依赖关系:
# 假设你已完成以下变量定义: # PO_FILES := $(wildcard $(projectpath)/locale/*/LC_MESSAGES/*.po) # MO_FILES := $(patsubst $(projectpath)/locale/%,$(buildpath)/locale/%,$(PO_FILES:.po=.mo)) # DIRS := $(dir $(MO_FILES)) # 先确保目标目录存在 $(DIRS): mkdir -p $@ # 静态模式规则:每个.mo文件对应同名.po文件 $(MO_FILES): $(buildpath)/locale/%/LC_MESSAGES/%.mo: $(projectpath)/locale/%/LC_MESSAGES/%.po | $(DIRS) msgfmt -o $@ $<
方案2:动态路径解析的通用规则
如果不想依赖预定义变量,可通过路径拆分命令来生成目标文件:
# 匹配所有源.po文件,动态生成对应.mo文件 $(projectpath)/locale/*/LC_MESSAGES/*.po: # 提取语言目录(如zh_CN) LANG_DIR := $(patsubst $(projectpath)/locale/%/LC_MESSAGES/%,%,$(dir $@)) # 提取文件名(如messages) FILE_NAME := $(notdir $(basename $@)) # 拼接目标.mo文件路径 MO_TARGET := $(buildpath)/locale/$(LANG_DIR)/LC_MESSAGES/$(FILE_NAME).mo # 创建目标目录(如果不存在) @mkdir -p $(dir $(MO_TARGET)) # 生成.mo文件 msgfmt -o $(MO_TARGET) $<
核心注意点
| $(DIRS)是顺序依赖,确保目录先创建,但不会因目录更新触发.mo文件重新生成- 确认
msgfmt在Make的PATH环境变量中,或者直接指定绝对路径(如/usr/bin/msgfmt) - 静态模式规则更稳定,因为它直接复用你已整理好的文件列表,避免路径解析错误
内容的提问来源于stack exchange,提问作者Ultra Junkie
相关产品推荐
相关产品推荐

