bugmake - Bugs: bug #30323, No path in MAKE_COMMAND (with fix)

 
 

bug #30323: No path in MAKE_COMMAND (with fix)

Submitter:  None
Submitted:  Fri 02 Jul 2010 12:53:59 PM UTC
   
 
Severity:  2 - Minor Item Group:  Enhancement
Status:  Wont Fix Privacy:  Public
Assigned to:  None Open/Closed:  Closed
Component Version:  3.82 Operating System:  Any
Fixed Release:  None Triage Status:  Verified
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Tue 01 Oct 2013 05:33:02 PM UTC, comment #8: 

Your example exactly reproduces what the comment says: since the current directory is implicitly always on PATH on Windows, the Make executable is found in the current directory, and the Makefile does not work.

The same happens on GNU/Linux if you prepend "." to PATH:

$ mkdir mktest && cd mktest
$ cp -p /bin/make ./mak1
$ export PATH=.:"$PATH"
$ mkdir subdir
$ mak1 -f-
all:
        cd subdir && $(MAKE)
^D
cd subdir && mak1
/bin/sh: mak1: not found
mak1: * [all] Error 127

Therefore, I submit that the Windows port behaves exactly like Make behaves on Posix platforms in this case.  If the Posix code is modified to work around this failure, I will then consider changing the Windows code to follow suit.


Eli Zaretskii <eliz>
Group Member
Wed 04 Aug 2010 01:50:42 PM UTC, comment #7: 

Hi Eli,

> Sorry, I don't follow. I'm not even sure we are talking about the same thing, so let's step back for a moment and see that we understand each other.


Ful ACK.

> This code's sole purpose is to define the value of $MAKE such that it will cause the same executable to be invoked by sub-Make's. There's no other purpose here. Agreed?


ACK.

> Next, let's forget about the comment, it is only correct for Posix platforms. Let's talk only about what the code actually does on Windows. Okay?


ACK.

> Now, the code in question, in its WINDOWS32 branch, simply mirrors all backslashes to forward slashes (except in a couple of weirdo cases, which we will ignore for the moment). Unlike the Posix branch, this code does NOT prepend the current directory to the value of argv[0]. Do you agree?


NACK. The line

    argv[0] = xstrdup(w32ify(argv[0],1));

calls w32ify() with the second parameter being 1 causing w32ify() to call _fullpath().

Then _fullpath() calls GetFullPathName() which is described as:
"merges the name of the current drive and directory with a specified file name to determine the full path and file name of a specified file."

> Now, if you agree with all of the above, please describe a use-case where the result of this code will be a value of $MAKE which could potentially invoke a different executable in a sub-Make.


1. Have make.exe in the current directory (and not in the PATH).
2. Have a subdirectory 'subdir'.
3. Have a Makefile with the following content:

all:
cd subdir && $(MAKE)

4. Use cmd.exe and enter 'make'.

You'll get:

cd subdir && make
make: not found
make: * [all] Error 127

Oliver Schmidt - oliv.schmidt(at)sap.com

Anonymous
Sat 24 Jul 2010 11:18:51 AM UTC, comment #6: 

Sorry, I don't follow.  I'm not even sure we are talking about the same thing, so let's step back for a moment and see that we understand each other.

This code's sole purpose is to define the value of $MAKE such that it will cause the same executable to be invoked by sub-Make's.  There's no other purpose here.  Agreed?

Next, let's forget about the comment, it is only correct for Posix platforms.  Let's talk only about what the code actually does on Windows.  Okay?

Now, the code in question, in its WINDOWS32 branch, simply mirrors all backslashes to forward slashes (except in a couple of weirdo cases, which we will ignore for the moment).  Unlike the Posix branch, this code does NOT prepend the current directory to the value of argv[0].  Do you agree?

Now, if you agree with all of the above, please describe a use-case where the result of this code will be a value of $MAKE which could potentially invoke a different executable in a sub-Make.

Eli Zaretskii <eliz>
Group Member
Sat 24 Jul 2010 10:41:31 AM UTC, comment #5: 

Hi Eli,

> Do you have a use-case where argv[0] on Windows does not hold a full file name of Make's executable?


Yes.

Before the existing code cited in my original post is executed there are two usecases:

- Make's executable is found in the PATH env var
- Make's executable is found in the current directory

After the existing code cited in my original post is executed there's one usecase left:

- Make's executable is found in the current directory

This is by the way the situation the existing comment cited in my original post refers to:

"If it is a name with no slash, we can only hope that PATH did not find it in the current directory."

Oliver Schmidt - oliv.schmidt(at)sap.com


Anonymous
Mon 19 Jul 2010 05:52:24 PM UTC, comment #4: 

Do you have a use-case where argv[0] on Windows does not hold a full file name of Make's executable?

Eli Zaretskii <eliz>
Group Member
Mon 19 Jul 2010 11:18:29 AM UTC, comment #3: 

Hi Eli,

> GetModuleFileName is available on Windows 9X as well.


I see. Thanks for the hint.

> So I think the current code is allright even on older Windows versions.


> If you have a practical case weher this API doesn't work on Windows 9X, please show the Makefile and the error messages.


I'm quite sure that there's a misunderstanding :-(

The current code doesn't use GetModuleFileName() NOR the proposed _pgmptr. Therefore it is certainly compatible with older Windows versions.

My proposal is to use one OR the other instead of the current code using argv[0]. So I was only caring about the compatibility of my proposal with older Windows versions.

My proposal makes sure that MAKE_COMMAND always contains an absolute path regardless of circumstances under which GNU make was called.

As far as I see there's no need to discuss/prove that an absolute path in MAKE_COMMAND is desirable as the current code itself contains a comment pointing out (one incarnation of) the problem:

"If it is a name with no slash, we can only hope that PATH did not find it in the current directory."

Oliver Schmidt - oliv.schmidt(at)sap.com

Anonymous
Mon 05 Jul 2010 08:38:48 PM UTC, comment #2: 

It's maybe a bad idea to convert ("w32ify") paths to forward slashes that may be passed to the windows shell.

Anonymous
Fri 02 Jul 2010 01:50:46 PM UTC, comment #1: 

According to this page:

http://winapi.freetechsecrets.com/win32/WIN32GetModuleFileName.htm

GetModuleFileName is available on Windows 9X as well.  (I believe the above site more than I believe the official MS docs, because some time ago they simply removed Windows 9X from the list of systems on which each API is available, probably to tell users those systems are no longer supported.)  At least Emacs uses this API without conditioning it on W2K and later.  So I think the current code is allright even on older Windows versions.

If you have a practical case weher this API doesn't work on Windows 9X, please show the Makefile and the error messages.

Eli Zaretskii <eliz>
Group Member
Fri 02 Jul 2010 12:53:59 PM UTC, original submission:  

Hi,

The file main.c contains the following comment:

"Set the "MAKE_COMMAND" variable to the name we were invoked with. (If it is a relative pathname with a slash, prepend our directory name so the result will run the same program regardless of the current dir. If it is a name with no slash, we can only hope that PATH did not find it in the current directory.)"

However the last sentence isn't true for Windows. With GetModuleFileName(NULL, ...) it is possible to reliably retrieve the absolute pathname of the running program independently from the peculiarities of the way it was called (aka the content of argv[0]).

The fix is to replace

  if (strpbrk(argv[0], "/:\\") ||
      strstr(argv[0], "..") ||
      strneq(argv[0], "//", 2))
    argv[0] = xstrdup(w32ify(argv[0],1));

with

  argv[0] = xstrdup (w32ify (_pgmptr, 0));

This fix doesn't call GetModuleFileName() directly because that is documented to require at least Windows 2000. Instead it uses _pgmptr which is documented to be available since Windows 95 - and which is populated by the CRT nowadays using GetModuleFileName().

Note that resolving to a full pathname in w32ify() is now turned off. It's only called to convert '\' to '/'.

Oliver Schmidt - oliv.schmidt(at)sap.com

Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by psmith (Updated the item)
  • -email is unavailable- added by eliz (Posted a comment)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2013-10-09 psmith Open/ClosedOpen Closed
        Component Version4.0 3.82
    2013-10-01 eliz StatusNone Wont Fix
        Operating SystemMS Windows Any
        Triage StatusNone Verified
    2013-10-01 eliz Severity3 - Normal 2 - Minor
        Item GroupBug Enhancement

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code