Binary MO files need to be generated at build time. This means that your build system needs to have a build target to read the textual PO files used as the source and convert them to the binary MO files that will be installed in the user's system. As you correctly point out, the msgfmt command (part of the gettext tools) will ultimately create them.
So to answer the last part of the question, yes, MO files are machine-dependant.
Creating MO files the hard way
Now onto how to create them, in the standard gettext layout you'll generally have all PO files in the same directory, one per language and named after each language's ISO-639 2-letter or 3-letter code:
po/
po/ca.po
po/de.po
...
If you want to build them manually, you'll have to walk through each file in that dir and invoke msgfmt manually, e.g.
$ msgfmt -c po/ca.po -o build/locale/LC_MESSAGES/ca/myapp.mo
But you don't want to be doing this when there is already an established way and automated tools created especially for the operation of building MO files.
Furthermore, these tools take care of other associated tasks, such as extracting translations from the code and putting them all together in a POT file to give to translators to do their work.
Creating MO files the clever way
If you are using Python, I very much recommeng using the python-distutils-extra package (install p-d-e), which automates and hides away the complexity by just having to specify the following in the setup.py file you'll use to build, install and distribute your app. Same example as @dobey was already pointing out on his answer:
DistUtilsExtra.auto.setup(
name='myapp',
version='0.1',
#license='GPL-3',
#author='Your Name',
#author_email='email@ubuntu.com',
#description='UI for managing …',
#long_description='Here a longer description',
#url='https://launchpad.net/myapp'
)
That will take care of everything for you.
If you want to test translations before shipping them, you can use the handy build_i18n command from python-distutils-extra:
$ python setup.py build_i18n
This will build all the PO files in your /po folder and will put them under build (it will create it if it doesn't exist) in the same layout gettext expects when they are installed in a system.
You can then test your application with translations either by:
* Copying the contents of /build to /usr/share/locale, or
* Pointing your app to the build directory using the gettext.bindtextdomain() function:
gettext.bindtextdomain(domain='myapp', localedir='/home/me/dev/myapp/build')
Being even cleverer
Stand on the shoulder of giants. Simply create a test application with Quickly and copy how translations are set up in setup.py, which basically boils down to using the DistutilsExtra module in auto mode, as outlined above.
You can use the test app to play with generating translations too and learn how the generation works.
Packaging
The tarball you put together as part of a release should not include the .mo files. That is, you don't have to build them manually. That needs to happen when either someone builds the tarball contents to install manually or when e.g. a Debian binary package is being created.
Looking at your source tree, I would suggest again to use a build system such as python-distutils-extra, which will also help with the packaging. Roughly, you'll need to:
- Create a
setup.py file with contents similar to those suggested above
- Create the packaging control files under debian/. Using p-d-e your
debian/rules file can become very simple and consist of only a few lines.
Actually, you might just want to use Quickly to create the harness for the build and packaging system for your app and then replace Quickly's generated source code for the test application with your application's code.