# po/Makefile.am for anaconda # # Based loosely on Makefiles generated by gettext # # Copyright (C) 2016 Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # This file is intended to replace everything that gettextize or autopoint # installs. It has a lot less weird crud and tries to cooperate with # automake at least a little bit. # # To use it: # - Edit COPYRIGHT_HOLDER and MSGID_BUGS_ADDRESS below # # - Add the file types you're interested in to POTFILE_SUFFIXES. This replaces # the old POTFILES.in since the list of files you want to select for # translation is invariably all of them. # # - If you have other files that can't be selected by suffix, or that need to # be built from source files, add them to POTFILE_EXTRA # # - Add po/Makefile to AC_CONFIG_FILES (there may be po/Makefile.in if # switching from gettextize, replace that) # # - Get rid of AM_GNU_GETTEXT and AM_GNU_GETTEXT_VERSION. You might want to # add checks for xgettext, msgmerge, msgfmt, and msgcat. Up to you. # # - Add the following to .gitignore: # po/*.mo # po/*.po # po/*.mpo # po/*.pot # # - Remove everything in the po/ directory from source control except this # file. # # The idea is something like this: # From a clean project, you do the automake stuff and download a bunch of # .po files from the external translation site. These are the "source" files. # # From the source tree we create a template file, .pot, of all the # translatable strings. This file is not saved or distributed because there's # really no reason to do that if translations are not part of the source # tree. The file is pushed to the translators when creating a new release, # and it is used during the build, and that's it. # # The .po files might not match the .pot file, because this is the nature of # linear time and translations being a separate task. Maybe the translator # last touched the .po file yesterday. Maybe three years ago. To get the # translations in sync with the source, which usually means untranslating # some strings, we run msgmerge on all of the source files. The merged files # are saved in builddir as .mpo, which is a non-standard file extension # I just made up. # # The merged .po files are then compiled into .mo files, which are what # get installed to /usr/share/locale. # Variables used in xgettext arguments COPYRIGHT_HOLDER = Red Hat, Inc. MSGID_BUGS_ADDRESS = anaconda-devel@lists.fedoraproject.org include $(top_srcdir)/branch-config.mk include ./l10n-config.mk PO_DOWNLOADED_FLAG = $(srcdir)/.po_downloaded # What kind of files are we looking for? POTFILE_SUFFIXES = py c glade desktop # Below this line is the part that shouldn't need to be changed for other # projects # Turn POTFILE_SUFFIXES into a list of files POTFILE_INPUT = $(foreach s,$(POTFILE_SUFFIXES),\ $(shell find $(top_srcdir) -type d -name .git -prune \ -o -type d -name node_modules -prune \ -o -type f -name '*.$(s)' -print)) # The template file, generated by from all files with translatable strings. POTFILE = $(PACKAGE).pot # The translation files, provided by translators, pulled down from translation repository. # Use whatever we got from this repository, or nothing at all if no translations were # pulled. POFILES = $(shell find $(srcdir) -type f -name '*.po') # The translations files after they have been merged with the latest copy of # the .pot file. These are written to $(builddir) as .mpo. MERGED_POFILES = $(patsubst %.po,%.mpo,$(notdir $(POFILES))) # The MO files, which are the binary data built from the .po files. MOFILES = $(patsubst %.mpo,%.mo,$(MERGED_POFILES)) # Special weirdness to auto-generate sr@latin.po if sr.po is present MERGED_POFILES += $(if $(shell [ -f sr.po ] && echo y),sr@latin.mpo,) sr@latin.mpo: $(srcdir)/sr.po $(AM_V_GEN)$(MSGFILTER) -i $(srcdir)/sr.po -o $@ recode-sr-latin # The gettext programs and arguments # xgettext eXtracts strings from translatable files and generates the template # (.pot) file. We use a wrapper from translation-canary in order to catch # warnings about strings that may not be translatable, and all the keyword # arguments define the various functions that are used to mark a string as # translatable XGETTEXT = $(top_srcdir)/translation-canary/xgettext_werror.sh XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --keyword=P_:1,2 \ --keyword=C_:1c,2 --keyword=CN_:1c,2 --keyword=CP_:1c,2,3 \ --keyword=gettext:1,1t --keyword=gettext:1c,2,2t \ --keyword=ngettext:1,2,3t --keyword=ngettext:1c,2,3,4t \ --add-comments=TRANSLATORS: \ --sort-output \ --from-code=UTF-8 --package-name=$(PACKAGE) \ --package-version=$(PACKAGE_VERSION) \ --copyright-holder="$(COPYRIGHT_HOLDER)" \ --msgid-bugs-address="$(MSGID_BUGS_ADDRESS)" # msgfmt compiles a .po file into a .mo file # Do not include --check in the options, since those checks are more # conveniently done by translation-canary MSGFMT = msgfmt MSGFMT_OPTIONS = # msgmerge merges changes in the template (.pot) file back into the translation # (.po) file MSGMERGE = msgmerge MSGMERGE_OPTIONS = # msgfilter applies a filter to a .po file. We use this to automatically # transliterate Serbian from Cyrillic (sr) to Latin (sr@latin). MSGFILTER = msgfilter # msgcat cats multiple .po (or .pot) files together. We use this to generate # the .pot file from multiple parts. MSGCAT = msgcat # Automake magic for verbose/non-verbose build output GETTEXT_V_EXTRACT = $(GETTEXT_V_EXTRACT_$(V)) GETTEXT_V_EXTRACT_ = $(GETTEXT_V_EXTRACT_$(AM_DEFAULT_VERBOSITY)) GETTEXT_V_EXTRACT_0 = @echo " EXTRACT " $@; GETTEXT_V_FORMAT = $(GETTEXT_V_FORMAT_$(V)) GETTEXT_V_FORMAT_ = $(GETTEXT_V_FORMAT_$(AM_DEFAULT_VERBOSITY)) GETTEXT_V_FORMAT_0 = @echo " FORMAT " $@; GETTEXT_V_MERGE = $(GETTEXT_V_MERGE_$(V)) GETTEXT_V_MERGE_ = $(GETTEXT_V_MERGE_$(AM_DEFAULT_VERBOSITY)) GETTEXT_V_MERGE_0 = @echo " MERGE " $@; # If make was run with V=1, add verbose options to msgfmt MSGFMT_V_OPTIONS = $(MSGFMT_V_OPTIONS_$(V)) MSGFMT_V_OPTIONS_ = $(MSGFMT_V_OPTIONS_$(AM_DEFAULT_VERBOSITY)) MSGFMT_V_OPTIONS_0 = $(MSGFMT_OPTIONS) MSGFMT_V_OPTIONS_1 = $(MSGFMT_OPTIONS) --statistics --verbose # Same with msgmerge MSGMERGE_V_OPTIONS = $(MSGMERGE_V_OPTIONS_$(V)) MSGMERGE_V_OPTIONS_ = $(MSGMERGE_V_OPTIONS_$(AM_DEFAULT_VERBOSITY)) MSGMERGE_V_OPTIONS_0 = $(MSGMERGE_OPTIONS) --quiet MSGMERGE_V_OPTIONS_1 = $(MSGMERGE_OPTIONS) --verbose # Actually do stuff: # .po files get distributed but not installed # Let's also store a flag downloaded file which tells us that the translations are # already downloaded. dist_noinst_DATA = $(POFILES) $(PO_DOWNLOADED_FLAG) # Build the .mo files but don't actually do anything with them. The real # install part is in the install-data-local target below. Build the .pot file # as well, even if there are no .mo files to build, so it can be tested. nodist_noinst_DATA = $(MOFILES) $(POTFILE) # How to build the .pot file. This needs to be regenerated if anything that # goes into it has changed. # Build in two parts so that the bulk of the files are saved as relative to # top_srcdir (via --directory). Leave $POTFILES_EXTRAS as-is so the extra # targets don't need to worry about paths changing out from under them. main.pot: $(POTFILE_INPUT) $(GETTEXT_V_EXTRACT)$(XGETTEXT) $(XGETTEXT_OPTIONS) --directory=$(top_srcdir) -o $@ \ $(patsubst $(top_srcdir)/%,%,$(POTFILE_INPUT)) $(POTFILE): main.pot $(AM_V_GEN)$(MSGCAT) -o $@ main.pot # Request po files download before collecting them in the POFILES variable. $(POFILES): $(PO_DOWNLOADED_FLAG) $(PO_DOWNLOADED_FLAG): # To download po files from the l10n repo at an arbitrary commit $(GIT_L10N_SHA): # - clone the repo into /tmp at any branch without actually checking out any files # - fetch the commit, so it can be checked out # - check out the commit # - copy the .po files # - remove the repo again # - remove any trailing semicolons (";") in Plural-Forms header entries # - create the flag file TEMP_DIR=$$(mktemp --tmpdir -d anaconda-localization-XXXXXXXXXX) && \ git clone --depth 1 -b $(GIT_L10N_BRANCH) --no-checkout -- $(L10N_REPOSITORY) $$TEMP_DIR && \ (cd $$TEMP_DIR && git fetch --depth 1 origin $(GIT_L10N_SHA) && git checkout $(GIT_L10N_SHA)) && \ cp $$TEMP_DIR/$(L10N_DIR)/*.po $(srcdir)/ && \ rm -rf $$TEMP_DIR && \ find $(srcdir)/ -type f -exec sed -ri '/^\"Plural-Forms:/ s/;(\\n")$$/\1/' {} + touch $(PO_DOWNLOADED_FLAG) # Force a rebuild of the .pot file. Useful if something got removed, for # example. $(PACKAGE).pot-update: @rm -f $(POTFILE) @$(MAKE) $(POTFILE) # How to build the merged .mpo files from the .po files $(MERGED_POFILES): $(POFILES) $(POTFILE) # OMP_NUM_THREADS=1; This helps to avoid 'libgomp: Thread creation failed: Resource temporarily unavailable' on Cockpit's CI .po.mpo: $(GETTEXT_V_MERGE) OMP_NUM_THREADS=1 $(MSGMERGE) $(MSGMERGE_V_OPTIONS) -o $@ $< $(POTFILE) # How to build the .mo files from the .mpo files $(MOFILES): $(MERGED_POFILES) .mpo.mo: $(GETTEXT_V_FORMAT)$(MSGFMT) $(MSGFMT_V_OPTIONS) -o $@ $< # Install the .mo files. # .mo files get installed as $datadir/locale//LC_MESSAGES/.po # which doesn't really fit well with the way make or automake do things but # that is the world we live in localedir = $(datadir)/locale install-data-local: @for mo in $(MOFILES) ; do \ lang="$$(basename "$$mo" .mo)" ; \ $(MKDIR_P) $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES || exit $$? ; \ $(INSTALL_DATA) "$$mo" "$(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE).mo" || exit $$? ; \ done uninstall-local: @for mo in $(MOFILES) ; do \ lang="$$(basename "$$mo" .mo)" ; \ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE).mo ; \ done CLEANFILES = $(MERGED_POFILES) $(MOFILES) $(POTFILE) main.pot $(PO_DOWNLOADED_FLAG)