Wolfram Aulenbach
Wolfram Aulenbach

Reputation: 439

How to merge similar rules in a Makefile?

I use a Makefile to do language translations/conversions. For every language there is a rule to do the conversion from XML to a specific format.

How to combine following these similar patterns into one rule?
Adding more languages would bloat the code in this Makefile.

In this case I cannot change the suffix for targets (de_DE -> de_DE.txt). That would make it easier!

Here is the Makefile:

# german translation
%.de_DE: %.de_DE.xml
    @java $(JAVA_PAR) $(CONVERTER) $< $@

# turkish translation
%.tr_TR: %.tr_TR.xml
    @java $(JAVA_PAR) $(CONVERTER) $< $@

# cz translation
%.cs_CZ: %.cs_CZ.xml
    @java $(JAVA_PAR) $(CONVERTER) $< $@

Upvotes: 1

Views: 558

Answers (2)

reinierpost
reinierpost

Reputation: 8591

GNU make supports this, but not in a way I find very maintainable: the syntax and semantics are hard to grasp.

LANGS := de_DE tr_TR cs_CS en_US nl_NL

define LANG_template
# translation 
%.$1: %.$1.xml
    @java $(JAVA_PAR) $(CONVERTER) $$< $$@
endef

$(foreach l, $(LANGS), \
  $(eval $(call LANG_template,$(l))) \
)

Note the doubled dollar signs. In recipes with shell variables you'll end up with four.

Upvotes: 4

hlovdal
hlovdal

Reputation: 28180

You can instead generate the language rules (e.g. perl mk_lang_rules.pl > lang_rules.make) and add include lang_rules.make to your makefile. Where mk_lang_rules.pl is like the following for instance:

#!/usr/bin/perl
use strict;
use warnings;

my %langs = (
        "german" => "de_DE",
        "turkish" => "tr_TR",
        "cz" => "cs_CZ",
);

foreach my $lang (keys %langs) {
        my $code = $langs{$lang};
        print "\n# $lang translation\n";
        print "%.$code: %.$code.xml\n";
        print "\t\@java \$(JAVA_PAR) \$(CONVERTER) \$< \$@\n";
}
print "\n";

Upvotes: 0

Related Questions