diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
index 955a822..21d6d0b 100644
--- a/django/core/management/commands/makemessages.py
+++ b/django/core/management/commands/makemessages.py
@@ -38,11 +38,11 @@ def handle_extensions(extensions=('html',)):
     # trick xgettext to parse them as Python files)
     return set([x for x in ext_list if x != '.py'])
 
-def _popen(cmd):
+def _popen(cmd, cwd=None):
     """
     Friendly wrapper around Popen for Windows
     """
-    p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, close_fds=os.name != 'nt', universal_newlines=True)
+    p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, close_fds=os.name != 'nt', universal_newlines=True, cwd=cwd)
     return p.communicate()
 
 def walk(root, topdown=True, onerror=None, followlinks=False):
@@ -133,8 +133,10 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
     if os.path.isdir(os.path.join('conf', 'locale')):
         localedir = os.path.abspath(os.path.join('conf', 'locale'))
         invoked_for_django = True
+        relpath = os.path.join(os.path.pardir, os.path.dir)
     elif os.path.isdir('locale'):
         localedir = os.path.abspath('locale')
+        relpath = os.path.pardir
     else:
         raise CommandError("This script should be run from the Django SVN tree or your project or app tree. If you did indeed run it from the SVN checkout or your project or application, maybe you are just missing the conf/locale (in the django tree) or locale (for project and application) directory? It is not created automatically, you have to create it by hand if you want to enable i18n for your project or application.")
 
@@ -168,6 +170,8 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
         if verbosity > 0:
             print "processing language", locale
         basedir = os.path.join(localedir, locale, 'LC_MESSAGES')
+        # relative path from the PO file to the root of the application/project
+        relpath = os.path.join(relpath, os.path.pardir, os.path.pardir)
         if not os.path.isdir(basedir):
             os.makedirs(basedir)
 
@@ -190,12 +194,12 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
                     f.write(src)
                 finally:
                     f.close()
-                cmd = 'xgettext -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (domain, os.path.join(dirpath, thefile))
-                msgs, errors = _popen(cmd)
+                cmd = 'xgettext -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (domain, os.path.normpath(os.path.join(relpath, dirpath, thefile)))
+                msgs, errors = _popen(cmd, cwd=basedir)
                 if errors:
                     raise CommandError("errors happened while running xgettext on %s\n%s" % (file, errors))
-                old = '#: '+os.path.join(dirpath, thefile)[2:]
-                new = '#: '+os.path.join(dirpath, file)[2:]
+                old = '#: '+os.path.join(relpath, dirpath[2:], thefile)
+                new = '#: '+os.path.join(relpath, dirpath[2:], file)
                 msgs = msgs.replace(old, new)
                 if os.path.exists(potfile):
                     # Strip the header
@@ -226,14 +230,14 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
                 if verbosity > 1:
                     sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
                 cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
-                    domain, os.path.join(dirpath, thefile))
-                msgs, errors = _popen(cmd)
+                    domain, os.path.normpath(os.path.join(relpath, dirpath, thefile)))
+                msgs, errors = _popen(cmd, cwd=basedir)
                 if errors:
                     raise CommandError("errors happened while running xgettext on %s\n%s" % (file, errors))
 
                 if thefile != file:
-                    old = '#: '+os.path.join(dirpath, thefile)[2:]
-                    new = '#: '+os.path.join(dirpath, file)[2:]
+                    old = '#: '+os.path.join(relpath, dirpath[2:], thefile)
+                    new = '#: '+os.path.join(relpath, dirpath[2:], file)
                     msgs = msgs.replace(old, new)
                 if os.path.exists(potfile):
                     # Strip the header
@@ -250,7 +254,7 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
                     os.unlink(os.path.join(dirpath, thefile))
 
         if os.path.exists(potfile):
-            msgs, errors = _popen('msguniq --to-code=utf-8 "%s"' % potfile)
+            msgs, errors = _popen('msguniq --to-code=utf-8 "%s"' % potfile, cwd=basedir)
             if errors:
                 raise CommandError("errors happened while running msguniq\n%s" % errors)
             f = open(potfile, 'w')
@@ -259,7 +263,7 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
             finally:
                 f.close()
             if os.path.exists(pofile):
-                msgs, errors = _popen('msgmerge -q "%s" "%s"' % (pofile, potfile))
+                msgs, errors = _popen('msgmerge -q "%s" "%s"' % (pofile, potfile), cwd=basedir)
                 if errors:
                     raise CommandError("errors happened while running msgmerge\n%s" % errors)
             elif not invoked_for_django:
