I have installed gnuwin32 core utils, make and gettext:


I have a makefile that looks like this:

.PHONY: po mo

    xgettext -Lpython --output=po/messages.pot vocelab/app.py vocelab/app.kv
    msgmerge --update --no-fuzzy-matching --backup=off po/en.po po/messages.pot
    msgmerge --update --no-fuzzy-matching --backup=off po/hu.po po/messages.pot

    mkdir -p "data/locales/en/LC_MESSAGES"
    mkdir -p "data/locales/hu/LC_MESSAGES"
    msgfmt -c -o data/locales/en/LC_MESSAGES/langapp.mo po/en.po
    msgfmt -c -o data/locales/hu/LC_MESSAGES/langapp.mo po/hu.po

The problem is that the mkdir command is the one built-in cmd.exe. Even though I have "c:\Program Files (x86)\GnuWin32\bin" on my path, the built-in command takes precedence. So when I type "make mo" then I get this error:

A subdirectory or file data/locales/en/LC_MESSAGES already exists.

I could replace mkdir with "c:\Program Files (x86)\GnuWin32\bin\mkdir.exe" in the makefile, but that does not seem right. On a different system, somebody might have a different location for gnuwin32.

In other words: the mkdir.exe is there, but it conflicts with a built-on command of cmd.exe. The other option would be to use a different shell on Windows. But installing the linux subsystem for Windows, or installing cygwin would require gigabytes of disk space. In contrast, the gnu win32 directory needed for this project is only 40MB.

I have found a solution that actually works, but it is ugly and not portable:

GNUWIN32=c:/Program Files (x86)/GnuWin32\bin

.PHONY: po mo

    "$(GNUWIN32)/xgettext" -Lpython --output=po/messages.pot vocelab/app.py vocelab/app.kv
    "$(GNUWIN32)/msgmerge" --update --no-fuzzy-matching --backup=off po/en.po po/messages.pot
    "$(GNUWIN32)/msgmerge" --update --no-fuzzy-matching --backup=off po/hu.po po/messages.pot

    "$(GNUWIN32)/mkdir" -p "data/locales/en/LC_MESSAGES"
    "$(GNUWIN32)/mkdir" -p "data/locales/hu/LC_MESSAGES"
    "$(GNUWIN32)/msgfmt" -c -o data/locales/en/LC_MESSAGES/langapp.mo po/en.po
    "$(GNUWIN32)/msgfmt" -c -o data/locales/hu/LC_MESSAGES/langapp.mo po/hu.po

The CMD mkdir does not support -p switch anymore on Windows 8+ systems. That's why you get this error.

As I said in the comment, don't expect that one makefile/script will run on both Windows and Linux like this one does. Usually you will need to provide different versions, one for each OS for more complicated makefiles.

To overcome the error with CMD mkdir (for Windows only):

if not exist "data/locales/en/LC_MESSAGES" mkdir "data/locales/en/LC_MESSAGES"

or for a shorter command

en = "data/locales/en/LC_MESSAGES"
hu = "data/locales/hu/LC_MESSAGES"

if not exist $en mkdir $en
if not exist $hu mkdir $hu

To use the gnuwin mkdir

Use double quotes on the mkdir. This will force windows to search the executable mkdir instead of the CMD command.

"mkdir" -p "data/locales/en/LC_MESSAGES"

Update: Tested the double quote in Kali Linux, Linux Mint, Windows 7 and works on all of them. Just make sure that your gnuwin\bin is in your system Path

  • I want to use gnuwin32's mkdir. I think that was clearly on the question. That mkdir.exe does support the -p switch. The if construct you suggested does not work on linux, not portable. – nagylzs Sep 25 '17 at 14:29
  • @nagylzs If you want to explicitly use cygwin then portability is an issue since not every computer is going to have cygwin installed, or even if it has, be in the same place as your script specifies... Yes, this will work on windows but not Linux. But that's why for each OS you provide different parameters. I've been using scripts and makefiles for both OS's and every time I make one for Windows and one for Linux. I will look at it again tommorow and see what I can do – Jimmy_A Sep 25 '17 at 16:49
  • @nagylzs Updated answer. Think that solves your issue – Jimmy_A Sep 26 '17 at 9:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.