0

See the image, I wanted to create folders in Makefile for c project under Windows 10. At the last line, I accidentally added "#", and it works. However, it does not work without the "#" at the last line.

That line is as follows:

mkdir -p $@

or

mkdir -p $@ #
  1. Why does it not work without "#"?
  2. How to write it correctly under windows 10?

Edit: Error Message in short error message is the system cannot find the given files ( it is a translattion )

making dirs....
build/
mkdir -p build/ 
Makefile:293: recipe for target 'build/' failed
process_begin: CreateProcess(NULL, mkdir -p build/, ...) failed.
make (e=2): Das System kann die angegebene Datei nicht finden.

make: *** [build/] Error 2

Edit: I add the code in text as follows

#Create non existing dirs
OBJDIRS = $(sort $(dir $(OBJS))) #sort removes duplicate dirs...
$(OBJDIRS):
    @echo
    @echo "making dirs...."
    @echo $@
    mkdir -p $@ #ok
mpromonet
  • 11,326
  • 43
  • 62
  • 91
Jay S.
  • 19
  • 1
  • 6
  • 2
    Please describe more specifically what "doesn't work" means. That is, describe the expected behaviour and the actual behaviour. Also, please don't use images for text. Copy the text directly into the question as text. – kaylum Apr 04 '16 at 12:09
  • 1
    `mkdir -p` is a U\*x command. Unless you have some sort of U\*x userland (cygwin, Bash, etc) it will simply not work, just like `cmd /c start notepad.exe` is unlikely to do anything useful on non-Windows platforms. – tripleee Apr 04 '16 at 12:36
  • kaylum. it does not work means make interpret it an error and stops there. – Jay S. Apr 04 '16 at 13:06
  • tripleee, you are right. The makefile is a template from Linux. I was trying to port it to Windows environment. But how can I rewrite it under windows. – Jay S. Apr 04 '16 at 13:14
  • @ tripleee it read the manual, it says that mkdir -p is not supported. However, what is the equilant for windows? – Jay S. Apr 13 '16 at 20:03
  • the script was correct. it was because of software version. It is cured after update. – Jay S. Oct 29 '16 at 18:38

2 Answers2

2

mkdir does not need the -p parameter, so remove it. Also it need backslashes instead of slashes, replace them.

So the command you have to use instead of your current mkdir is:

    mkdir $(subst /,\,$@)

Edit:

In the improbable case CMD Command Extensions are disabled by default, you have to use this command instead:

    cmd /E:ON /C mkdir $(subst /,\,$@)
jdarthenay
  • 3,062
  • 1
  • 15
  • 20
  • Thanks, I have tried both. But none of those work! Besides, I am using GNU Make 4.1 build for i686-w64-mingw32. – Jay S. Apr 04 '16 at 16:20
  • @Jay S Do you get funny errors such as `gmake: Interrupt/Exception caught (code = 0xc0000005, addr = 0x000007FEFEF82020)` – jdarthenay Apr 04 '16 at 16:26
  • @Jay And what are the error messages you get? Doesn't it also create a "#" directory? – jdarthenay Apr 04 '16 at 17:23
  • @ jdarthenay. Nope, with extra #, everything is made correctly as I wished. – Jay S. Apr 04 '16 at 18:19
  • @Jay could you check the shell is cmd.exe and not anther one? To know how to check what shell is used by make, read this: http://stackoverflow.com/questions/36403389/exact-same-command-line-produces-error-in-make-yet-succeeds-if-run-from-shell/36403841#36403841 – jdarthenay Apr 05 '16 at 04:15
  • I tried those in that link. none of those scripts worked. But I think in that direction. – Jay S. Apr 05 '16 at 07:58
  • 1
    @Jay I did not ask you to 'try those in that link' I asked you to check the shell make is using. Just add a `echo shell is $(SHELL)` line before the `mkdir` line. What is its output? – jdarthenay Apr 05 '16 at 08:08
  • @Jay do not answer elsewhere... and never put spaces in indentation in a makefile, all commands MUST start with a tabulation character. Replace all four-spaces indent in your makefile by tabulations. – jdarthenay Apr 05 '16 at 09:53
  • @JayS. So, it was a problem of spaces instead of tabulation since the beginning? – jdarthenay Apr 12 '16 at 15:50
  • @jdarhenay no, it is not. I had looked the Makefile with binary editor. It is indeed a tab (ascii table tab) – Jay S. Apr 15 '16 at 10:01
1

I had exactly the same problem and thanks your temporary solution, it ended up working. However, I dug around a little more and figured out at least partly what's going on. If you run

make --debug=j

you'll see that when you add the # character, make actually runs

mkdir _build #
CreateProcess(NULL,C:/Program Files/GNU ARM Eclipse/Build Tools/2.6-201507152002/bin/sh.exe -c "mkdir _build #",...)

It should actually make sense that only this works, as mkdir is not an actual executable in windows, but a command interpreted only within a windows shell. I did some digging through the make (for Win32) source code, and it does appear as if there's quite a bit of hardcoded logic for deciding which commands to feed through sh and which commands to attempt to launch as a process. I haven't gotten around to figuring out which use case causes the the # symbol to suddenly decide to feed mkdir into the shell rather than trying to launch the process, but you have three options I can think of for doing this "correctly":

1) Use an executable mkdir, like the one in CoreUtils for Windows: http://gnuwin32.sourceforge.net/packages/coreutils.htm. Make sure it's in your path, of course.

2) Change the mkdir command to cmd /c "mkdir $@", which would feed mkdir to the native command handler in Windows. In my case, I do not use the -p flag, so it's compatible with the Windows mkdir, but in your case, -p is not supported by the native Windows shell, so you would need to either use a more powerful shell (sh) or see #1.

3) Read through the make source code and see if there's some reason to this behavior, or if it's a bug. I searched through the manual, and I do not believe the nature of sending your command to the shell or opening it as a process is documented.

Sam C
  • 11
  • 1