diff --git a/.gitignore b/.gitignore index dd00fc5ccf..121c2caed1 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,6 @@ .memdump .sc-start-sc_* .ycm_extra_conf.py -/ABOUT-NLS /AUTHORS /ChangeLog /GNUmakefile @@ -101,7 +100,7 @@ /maint.mk /mingw-libvirt.spec /mkinstalldirs -/po/* +/po/*gmo /proxy/ /python/ /run @@ -211,6 +210,3 @@ tags !/gnulib/lib/Makefile.am !/gnulib/tests/Makefile.am !/m4/virt-*.m4 -!/po/*.po -!/po/POTFILES.in -!/po/libvirt.pot diff --git a/ABOUT-NLS b/ABOUT-NLS new file mode 120000 index 0000000000..b583e276a7 --- /dev/null +++ b/ABOUT-NLS @@ -0,0 +1 @@ +po/README.md \ No newline at end of file diff --git a/autogen.sh b/autogen.sh index 1183b13083..9afad8f9d5 100755 --- a/autogen.sh +++ b/autogen.sh @@ -127,8 +127,7 @@ if test -d .git || test -f .git; then expected_hash=$(cat "$state_file" 2>/dev/null) actual_hash=$(gnulib_hash "$no_git") - if test "$actual_hash" = "$expected_hash" && \ - test -f po/Makevars && test -f AUTHORS; then + if test "$actual_hash" = "$expected_hash" && test -f AUTHORS; then # The gnulib hash matches our expectations, and all the files # that can only be generated through bootstrap are present: # we just need to run autoreconf. Unless we're performing a diff --git a/bootstrap.conf b/bootstrap.conf index 0bfa7941f6..9559922fce 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -58,7 +58,6 @@ getopt-posix getpass getpeername getsockname -gettext-h gettimeofday gitlog-to-changelog gnumakefile @@ -132,16 +131,6 @@ waitpid warnings ' -# Additional xgettext options to use. Use "\\\newline" to break lines. -XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\ - --flag=virAsprintf:2:c-format\\\ - --from-code=UTF-8\\\ -' - -# This is not a GNU package, so the default bug address is invalid, -# and the translation project is not in use. -MSGID_BUGS_ADDRESS=libvir-list@redhat.com -COPYRIGHT_HOLDER='Red Hat, Inc.' SKIP_PO=true # Enable copy-mode for MSYS/MinGW. MSYS' ln doesn't work well in the way @@ -150,31 +139,6 @@ if test -n "$MSYSTEM"; then copy=true fi -# If "AM_GNU_GETTEXT(external" or "AM_GNU_GETTEXT([external]" -# appears in configure.ac, exclude some unnecessary files. -# Without grep's -E option (not portable enough, pre-configure), -# the following test is ugly. Also, this depends on the existence -# of configure.ac, not the obsolescent-named configure.in. But if -# you're using this infrastructure, you should care about such things. - -gettext_external=0 -grep '^[ ]*AM_GNU_GETTEXT(external\>' configure.ac > /dev/null && - gettext_external=1 -grep '^[ ]*AM_GNU_GETTEXT(\[external\]' configure.ac > /dev/null && - gettext_external=1 - -if test $gettext_external = 1; then - # Gettext supplies these files, but we don't need them since - # we don't have an intl subdirectory. - excluded_files=' - m4/glibc2.m4 - m4/intdiv0.m4 - m4/lcmessage.m4 - m4/uintmax_t.m4 - m4/ulonglong.m4 - m4/visibility.m4 - ' -fi # Tell gnulib to: # require LGPLv2+ @@ -202,8 +166,6 @@ local_gl_dir=gnulib/local buildreq="\ autoconf 2.59 automake 1.9.6 -autopoint - -gettext 0.17 git 1.5.5 gzip - libtool - diff --git a/configure.ac b/configure.ac index ae798faa54..0aecf68c38 100644 --- a/configure.ac +++ b/configure.ac @@ -257,6 +257,7 @@ LIBVIRT_ARG_LIBSSH LIBVIRT_ARG_LIBXML LIBVIRT_ARG_MACVTAP LIBVIRT_ARG_NETCF +LIBVIRT_ARG_NLS LIBVIRT_ARG_NSS LIBVIRT_ARG_NUMACTL LIBVIRT_ARG_OPENWSMAN @@ -298,6 +299,7 @@ LIBVIRT_CHECK_LIBSSH LIBVIRT_CHECK_LIBXML LIBVIRT_CHECK_MACVTAP LIBVIRT_CHECK_NETCF +LIBVIRT_CHECK_NLS LIBVIRT_CHECK_NUMACTL LIBVIRT_CHECK_NWFILTER LIBVIRT_CHECK_OPENWSMAN @@ -732,33 +734,7 @@ if test "$enable_test_locking" = "yes"; then fi AM_CONDITIONAL([WITH_CIL],[test "$enable_test_locking" = "yes"]) -dnl Check for gettext - don't go any newer than what RHEL 5 supports -dnl -dnl save and restore CPPFLAGS around gettext check as the internal iconv -dnl check might leave -I/usr/local/include in CPPFLAGS on FreeBSD resulting -dnl in the build picking up previously installed libvirt/libvirt.h instead -dnl of the correct one from the source tree. -dnl compute the difference between save_CPPFLAGS and CPPFLAGS and append it -dnl to INCLUDES in order to preserve changes made by gettext but in a place -dnl that does not break the build -save_CPPFLAGS="$CPPFLAGS" -AM_GNU_GETTEXT_VERSION([0.17]) -AM_GNU_GETTEXT([external]) -GETTEXT_CPPFLAGS= -if test "x$save_CPPFLAGS" != "x$CPPFLAGS"; then - set dummy $CPPFLAGS; shift - for var - do - case " $var " in - " $save_CPPFLAGS ") ;; - *) GETTEXT_CPPFLAGS="$GETTEXT_CPPFLAGS $var" ;; - esac - done -fi -CPPFLAGS="$save_CPPFLAGS" -AC_SUBST([GETTEXT_CPPFLAGS]) - -ALL_LINGUAS=`cd "$srcdir/po" > /dev/null && ls *.po | sed 's+\.po$++'` +LIBVIRT_GETTEXT dnl Cygwin, MinGW and MSVC checks LIBVIRT_WIN_CHECK_COMMON @@ -909,7 +885,7 @@ AC_CONFIG_FILES([\ src/libvirt-qemu.pc \ src/libvirt-lxc.pc \ libvirt.spec mingw-libvirt.spec \ - po/Makefile.in \ + po/Makefile \ include/libvirt/libvirt-common.h \ examples/Makefile \ tests/Makefile \ @@ -990,6 +966,7 @@ LIBVIRT_RESULT_LIBXL LIBVIRT_RESULT_LIBXML LIBVIRT_RESULT_MACVTAP LIBVIRT_RESULT_NETCF +LIBVIRT_RESULT_NLS LIBVIRT_RESULT_NSS LIBVIRT_RESULT_NUMACTL LIBVIRT_RESULT_OPENWSMAN diff --git a/m4/virt-nls.m4 b/m4/virt-nls.m4 new file mode 100644 index 0000000000..f9fb27ceb5 --- /dev/null +++ b/m4/virt-nls.m4 @@ -0,0 +1,71 @@ +dnl gettext utilities +dnl +dnl Copyright (C) 2018 Red Hat, Inc. +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License, or (at your option) any later version. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library. If not, see +dnl . +dnl + +AC_DEFUN([LIBVIRT_ARG_NLS],[ + LIBVIRT_ARG_ENABLE([NLS], [NLS], [check]) +]) + +AC_DEFUN([LIBVIRT_CHECK_NLS],[ + if test "x$enable_nls" != "xno" + then + AC_CHECK_FUNC([gettext], [], [ + AC_CHECK_LIB([intl], [gettext], [], [ + if test "x$enable_nls" == "xcheck" + then + enable_nls=no + else + AC_MSG_ERROR([gettext() is required to build libvirt]") + fi + ]) + ]) + fi + + if test "x$enable_nls" != "xno" + then + AC_CHECK_HEADERS([libintl.h], [enable_nls=yes],[ + if test "x$enable_nls" == "xcheck" + then + enable_nls=no + else + AC_MSG_ERROR([libintl.h is required to build libvirt]") + fi + ]) + fi + + dnl GNU gettext tools (optional). + AC_CHECK_PROG([XGETTEXT], [xgettext], [xgettext], [no]) + AC_CHECK_PROG([MSGFMT], [msgfmt], [msgfmt], [no]) + AC_CHECK_PROG([MSGMERGE], [msgmerge], [msgmerge], [no]) + + dnl Check they are the GNU gettext tools. + AC_MSG_CHECKING([msgfmt is GNU tool]) + if $MSGFMT --version >/dev/null 2>&1 && $MSGFMT --version | grep -q 'GNU gettext'; then + msgfmt_is_gnu=yes + else + msgfmt_is_gnu=no + fi + AC_MSG_RESULT([$msgfmt_is_gnu]) + AM_CONDITIONAL([HAVE_GNU_GETTEXT_TOOLS], + [test "x$XGETTEXT" != "xno" && test "x$MSGFMT" != "xno" && \ + test "x$MSGMERGE" != "xno" && test "x$msgfmt_is_gnu" != "xno"]) +]) + +AC_DEFUN([LIBVIRT_RESULT_NLS],[ + LIBVIRT_RESULT([NLS], [$enable_nls]) +]) diff --git a/po/Makefile.am b/po/Makefile.am new file mode 100644 index 0000000000..95e5ab72bf --- /dev/null +++ b/po/Makefile.am @@ -0,0 +1,97 @@ +DOMAIN = $(PACKAGE_NAME) +COPYRIGHT_HOLDER = The Libvirt authors +MSGID_BUGS_ADDRESS = https://libvirt.org/bugs.html + +LANGS := \ + af am anp ar as ast bal be bg bn_IN \ + bn bo br brx bs ca cs cy da de_CH \ + de el en_GB eo es et eu fa fi \ + fr gl gu he hi hr hu ia \ + id ilo is it ja ka kk km kn ko \ + kw_GB kw@kkcor kw kw@uccor ky lt lv mai mk ml \ + mn mr ms nb nds ne nl nn nso \ + or pa pl pt_BR pt ro ru si sk sl \ + sq sr@latin sr sv ta te tg th tr tw \ + uk ur vi wba yo zh_CN zh_HK zh_TW zu + + +POTFILE_DEPS := $(shell $(SED) 's,^,$(top_srcdir)/,' $(srcdir)/POTFILES) +POTFILE := $(DOMAIN).pot +POFILES := $(LANGS:%=%.po) +GMOFILES := $(LANGS:%=%.gmo) + +EXTRA_DIST = \ + POTFILES \ + $(POTFILE) \ + $(POFILES) \ + $(GMOFILES) + +if HAVE_GNU_GETTEXT_TOOLS + +XGETTEXT_ARGS = \ + --default-domain=$(DOMAIN) \ + --from-code=utf-8 \ + --add-comments=TRANSLATORS: \ + --keyword=_ --keyword=N_ \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --package-name="$(PACKAGE_NAME)" \ + --package-version="$(PACKAGE_VERSION)" \ + --msgid-bugs-address="$(MSGID_BUGS_ADDRESS)" \ + --directory=$(top_srcdir) \ + $(NULL) + +SED_PO_FIXUP_ARGS = \ + -e "s|text/plain; charset=CHARSET|text/plain; charset=UTF-8|g" \ + -e "s|SOME DESCRIPTIVE TITLE|Libvirt package strings|g" \ + -e "s|Copyright (C) YEAR|Copyright (C) $$(date +'%Y')|" \ + $(NULL) + + +# Although they're in EXTRA_DIST, we still need to +# copy these again, because update-gmo will change +# their content, and dist-hook runs after the +# things in EXTRA_DIST are copied. +dist-hook: $(GMOFILES) + cp -f $(POTFILE:%=$(srcdir)/%) $(distdir)/ + cp -f $(POFILES:%=$(srcdir)/%) $(distdir)/ + cp -f $(GMOFILES:%=$(srcdir)/%) $(distdir)/ + +update-po: $(POFILES) + +update-gmo: $(GMOFILES) + +$(POTFILE): POTFILES $(POTFILE_DEPS) + $(XGETTEXT) -o $(srcdir)/$@-t $(XGETTEXT_ARGS) \ + --files-from=$(abs_srcdir)/POTFILES + $(SED) $(SED_PO_FIXUP_ARGS) < $@-t > $@ + rm -f $@-t + +%.po: $(POTFILE) + cd $(srcdir) && \ + $(MSGMERGE) --backup=off --no-fuzzy-matching --update $@ $(POTFILE) + +%.gmo: %.po + rm -f $(srcdir)/$@ $@-t + $(MSGFMT) -c -o $@-t $(srcdir)/$< + mv $@-t $(srcdir)/$@ + +.PRECIOUS: $(POTFILE) $(POFILES) + +endif HAVE_GNU_GETTEXT_TOOLS + +# Cannot use 'localedir' since this conflicts with autoconf. +langinstdir = $(datadir)/locale + +install-data-hook: $(GMOFILES) + mkdir -p $(DESTDIR)$(langinstdir) + for lang in $(LANGS); do \ + d=$(DESTDIR)$(langinstdir)/$$lang/LC_MESSAGES; \ + mkdir -p $$d; \ + install -m 0644 $(srcdir)/$$lang.gmo $$d/$(DOMAIN).mo; \ + done + +uninstall-hook: + for lang in $(LANGS); do \ + d=$(DESTDIR)$(langinstdir)/$$lang/LC_MESSAGES; \ + rm -f $$d/$(DOMAIN).mo; \ + done diff --git a/po/POTFILES.in b/po/POTFILES similarity index 100% rename from po/POTFILES.in rename to po/POTFILES diff --git a/po/README.md b/po/README.md new file mode 100644 index 0000000000..ba3d07ccdb --- /dev/null +++ b/po/README.md @@ -0,0 +1,36 @@ +Libvirt Message Translation +=========================== + +Libvirt translatable messages are maintained using the GNU Gettext tools and +file formats, in combination with the Zanata web service. + +Source repository +================= + +The libvirt GIT repository stores the master "libvirt.pot" file and full "po" +files for translations. The master "libvirt.pot" file can be re-generated using + + make libvirt.pot + +The full po files can have their source locations and msgids updated using + + make update-po + +Normally these updates are only done when either refreshing translations from +Zanata, or when creating a new release. + +Zanata web service +================== + +The translation of libvirt messages has been outsourced to the Fedora +translation team using the Zanata web service: + + https://fedora.zanata.org/project/view/libvirt + +As such, changes to translations will generally NOT be accepted as patches +directly to libvirt GIT. Any changes made to "$LANG.mini.po" files in libvirt +GIT will be overwritten and lost the next time content is imported from Zanata. + +The master "libvirt.pot" file is periodically pushed to Zanata to provide the +translation team with content changes. New translated text is then periodically +pulled down from Zanata to update the po files. diff --git a/src/internal.h b/src/internal.h index 1760e3b69c..47ff0479d2 100644 --- a/src/internal.h +++ b/src/internal.h @@ -26,6 +26,7 @@ # include # include # include +# include # if STATIC_ANALYSIS # undef NDEBUG /* Don't let a prior NDEBUG definition cause trouble. */ @@ -45,14 +46,13 @@ /* The library itself needs to know enum sizes. */ # define VIR_ENUM_SENTINELS -/* All uses of _() within the library should pick up translations from - * libvirt's message files, rather than from the package that is - * linking in the library. Setting this macro before including - * "gettext.h" means that gettext() (and _()) will properly expand to - * dgettext. */ -# define DEFAULT_TEXT_DOMAIN PACKAGE -# include "gettext.h" -# define _(str) gettext(str) +# ifdef HAVE_LIBINTL_H +# define DEFAULT_TEXT_DOMAIN PACKAGE +# include +# define _(str) dgettext(PACKAGE, str) +# else /* HAVE_LIBINTL_H */ +# define _(str) str +# endif /* HAVE_LIBINTL_H */ # define N_(str) str # include "libvirt/libvirt.h" diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index a1a0d567a6..4d3f241592 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -64,8 +64,10 @@ virAdmGlobalInit(void) virLogSetFromEnv(); +#ifdef HAVE_LIBINTL_H if (!bindtextdomain(PACKAGE, LOCALEDIR)) goto error; +#endif /* HAVE_LIBINTL_H */ if (!VIR_CLASS_NEW(remoteAdminPriv, virClassForObjectLockable())) goto error; diff --git a/src/libvirt.c b/src/libvirt.c index 0b6bd6666e..0a81cbfb99 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -363,8 +363,10 @@ virGlobalInit(void) goto error; #endif +#ifdef HAVE_LIBINTL_H if (!bindtextdomain(PACKAGE, LOCALEDIR)) goto error; +#endif /* HAVE_LIBINTL_H */ /* * Note we must avoid everything except 'remote' driver diff --git a/src/util/virgettext.c b/src/util/virgettext.c index c0135b4ea4..f583eaf8c4 100644 --- a/src/util/virgettext.c +++ b/src/util/virgettext.c @@ -37,6 +37,7 @@ int virGettextInitialize(void) { +#if HAVE_LIBINTL_H if (!setlocale(LC_ALL, "")) { perror("setlocale"); /* failure to setup locale is not fatal */ @@ -51,6 +52,6 @@ virGettextInitialize(void) perror("textdomain"); return -1; } - +#endif /* HAVE_LIBINTL_H */ return 0; } diff --git a/tools/virt-host-validate.c b/tools/virt-host-validate.c index 29d2482b6c..1470bf1c7d 100644 --- a/tools/virt-host-validate.c +++ b/tools/virt-host-validate.c @@ -23,7 +23,9 @@ #include #include -#include +#ifdef HAVE_LIBINTL_H +# include +#endif /* HAVE_LIBINTL_H */ #include #include "internal.h"