admin管理员组

文章数量:1410697

I want to use the tool msgfmt in a makefile to generate .mo files from .po sources. The .po sources are per language and reside in a folder structure like this:

$(projectpath)/locale/de/LC_MESSAGES
$(projectpath)/locale/fr/LC_MESSAGES
$(projectpath)/locale/en/LC_MESSAGES

The generated .mo files shall reside in a similar folder structure:

$(buildpath)/locale/de/LC_MESSAGES
$(buildpath)/locale/fr/LC_MESSAGES
$(buildpath)/locale/en/LC_MESSAGES

In the makefile, I have successfully created 2 variables for the sources and the targets:

PO_FILES := $(wildcard $(projectpath)/locale/*/LC_MESSAGES/*.po)
MO_FILES := $(subst $(projectpath)/locale/,$(buildpath)/locale/,$(subst .po,.mo,$(PO_FILES)))

and I am also able to create the target directories for the MO_FILES.

DIRS := $(sort $(dir $(MO_FILES)))

However, I am failing when defining the dependency to trigger the generation.

The following options didn't work:

%.mo:%.po
$(buildpath)/locale/%/LC_MESSAGES/%.mo: $(projectpath)/locale/%/LC_MESSAGES/%.po

I also tried a few other combination with same result. Make claims that it has no rule to make the target.

I want to use the tool msgfmt in a makefile to generate .mo files from .po sources. The .po sources are per language and reside in a folder structure like this:

$(projectpath)/locale/de/LC_MESSAGES
$(projectpath)/locale/fr/LC_MESSAGES
$(projectpath)/locale/en/LC_MESSAGES

The generated .mo files shall reside in a similar folder structure:

$(buildpath)/locale/de/LC_MESSAGES
$(buildpath)/locale/fr/LC_MESSAGES
$(buildpath)/locale/en/LC_MESSAGES

In the makefile, I have successfully created 2 variables for the sources and the targets:

PO_FILES := $(wildcard $(projectpath)/locale/*/LC_MESSAGES/*.po)
MO_FILES := $(subst $(projectpath)/locale/,$(buildpath)/locale/,$(subst .po,.mo,$(PO_FILES)))

and I am also able to create the target directories for the MO_FILES.

DIRS := $(sort $(dir $(MO_FILES)))

However, I am failing when defining the dependency to trigger the generation.

The following options didn't work:

%.mo:%.po
$(buildpath)/locale/%/LC_MESSAGES/%.mo: $(projectpath)/locale/%/LC_MESSAGES/%.po

I also tried a few other combination with same result. Make claims that it has no rule to make the target.

Share Improve this question asked Mar 4 at 10:59 Ultra JunkieUltra Junkie 1767 bronze badges 1
  • 1 Pattern rules can only ever have exactly one pattern matching token (%). A second and subsequent token is considered a literal % character, not a pattern matcher. – MadScientist Commented Mar 4 at 12:49
Add a comment  | 

2 Answers 2

Reset to default 3

What about:

PO_FILES := $(wildcard $(projectpath)/locale/*/LC_MESSAGES/*.po)
MO_FILES := $(patsubst $(projectpath)/%.po,$(buildpath)/%.mo,$(PO_FILES))

.PHONY: all
all: $(MO_FILES)

$(MO_FILES): $(buildpath)/%.mo: $(projectpath)/%.po
    mkdir -p $(@D)
    cp $< $@

(with cp instead of msgfmt that I do not have).

You would either have to write the mo:po rule for each locale, or use some GNU make magic with call/eval to create the rules with a loop:

buildpath   := buildpath
projectpath := projectpath
locales     := de en fr
PO_FILES    := $(wildcard $(projectpath)/locale/*/LC_MESSAGES/*.po)
MO_FILES    := $(subst $(projectpath)/locale/,$(buildpath)/locale/,$(subst .po,.mo,$(PO_FILES)))

all: $(MO_FILES)

define PROGRAM_template =
$(buildpath)/locale/$(1)/LC_MESSAGES/%.mo: $(projectpath)/locale/$(1)/LC_MESSAGES/%.po
        @echo cp $$< $$@
endef

$(foreach l,$(locales),$(eval $(call PROGRAM_template,$(l))))

If I run "make" with this, this is what happens:

cp projectpath/locale/de/LC_MESSAGES/x.po buildpath/locale/de/LC_MESSAGES/x.mo
cp projectpath/locale/en/LC_MESSAGES/x.po buildpath/locale/en/LC_MESSAGES/x.mo
cp projectpath/locale/en/LC_MESSAGES/y.po buildpath/locale/en/LC_MESSAGES/y.mo
cp projectpath/locale/en/LC_MESSAGES/z.po buildpath/locale/en/LC_MESSAGES/z.mo
cp projectpath/locale/fr/LC_MESSAGES/x.po buildpath/locale/fr/LC_MESSAGES/x.mo

This is pretty much straight out of the GNU make manual, https://www.gnu./software/make/manual/make.html#Eval-Function

本文标签: