0

Not sure if anyone else has gotten this to work, but I'm having no end of trouble even with the following simple line in my Makefile running mingw32-make:

mklink Mk Makefile

The following created the link, but mingw32-make puked and threw error 255 thereafter:

$(shell cmd /c 'mklink Mk Makefile')

Nothing else is problematic, and I have a relatively complex makefile. Only mklink is doing this. (Apparently msys has it's own problems with ln so going down that path appears pointless.)

Engineer
  • 8,529
  • 7
  • 65
  • 105
  • AFAIK, `mklink` is a privileged operation on Windows; are you sure your `make` process is sufficiently privileged to invoke it? Other than that, I can think of no reason why it should not work. – Keith Marshall Jul 05 '15 at 19:47
  • I've provided _two_ answers below, covering the two independent aspects of this question -- arguably it shouldn't have two aspects, but it does. Unfortunately, SO doesn't give me a way to keep the more pertinent above the more recent; I can't vote for my own answers, but the more pertinent needs to be voted up, or maybe even accepted, to promote it. – Keith Marshall Jul 05 '15 at 23:18
  • @KeithMarshall, Both +1'ed, just need to test before I accept. The additional detail you've kindly provided re MSYS `ln` provides a fallback - superb. Many thanks for all your hard work on MinGW, the project that enables me to develop in the way I consider ideal. Best regards. – Engineer Jul 06 '15 at 07:41

2 Answers2

1

The following works for me, (on Win7 Home Premium, in VirtualBox), provided I invoke it in a shell running with administrator privilege:

$ cat makefile.tst
all:
        cmd /c "mklink mk makefile.tst"
        @echo "Success!"

$ make -f makefile.tst
cmd /c "mklink mk makefile.tst"
symbolic link created for mk <<===>> makefile.tst
Success!

$ rm mk

$ mingw32-make -f makefile.tst
cmd /c "mklink mk makefile.tst"
symbolic link created for mk <<===>> makefile.tst
Success!

My shell, in this case is MSYS sh.exe, invoked via msys.bat from cmd.exe with UAC escalation to administrator privilege. This is so that I can show that the mklink command works both in MSYS' own make.exe, and in mingw32-make.exe; (of course, the mingw32-make.exe example also works directly from the elevated cmd.exe shell itself).

I suspect that attempting to use mklink directly within the makefile, without the cmd /c preamble, may not work because mklink is a cmd.exe built-in, which GNU make may not know to run this way ... it reports a CreateProcess failure, because the specified file cannot be found, when I try it.

Your use of make's $(shell ...) construct would not work, because that causes make to invoke the command in the wrong phase of operation ... when parsing the makefile itself, and constructing its dependency graph, rather than as a command to run when the containing rule is invoked, where it will now attempt to execute the output from the $(shell ...) command as a command in its own right; this is clearly not what you want!

Keith Marshall
  • 1,980
  • 15
  • 19
  • "I suspect that attempting to use mklink directly... is a built-in" was what I gathered as well. Parse-vs.-use issue was my newness to `make` speaking loud and clear! – Engineer Jul 06 '15 at 07:51
1

Just to clarify the position with regard to MSYS' own ln command: it does work as well as can be expected, within the limitations of the versions of Windows on which it was originally implemented. In particular:

$ ln fileA fileB

creates a file-to-file hard link, on file systems such as NTFS, which support such links, and falls back to creating a copy on file systems such as FAT, which don't. Also:

$ ln dirA dirB

fails, as it should; hard linked directories are a recipe for disaster, and are not allowed, (just as they are forbidden on unix platforms). However:

$ ln -s fileA refB

will not create a symbolic link, (because no version of Windows supported them at the time when MSYS was developed, and no one has stepped forward to implement the capability, since they have become available ... although, their implementation still seems flaky, on Vista and Win7 anyway); rather, this command falls back to creating a hard link if possible, or a file copy otherwise. Similarly:

$ ln -s dirA refB

will not create a symbolic directory link, and in this case, there is no fall back; it simply and unconditionally fails! (It might be argued that a deep copy of the directory could be a suitable fall back action, but it isn't implemented so; instead, the lndir command is provided, to facilitate this).

Keith Marshall
  • 1,980
  • 15
  • 19