Case-insensitive targets

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Case-insensitive targets

Gisle Vanem-2
Hello list.

In a discussion with the LuaList, I got involved with
how GNU-make on Windows handles all targets in a case-
insensitive manner. Like in this 'case-insensitive-win.mak':

-----
default: program_name

PROGRAM_NAME Program_Name program_name:
         @echo 'Do something for $@.'

-----

c:\> make -f case-insensitive-win.mak
case-insensitive-win.mak:3: target 'program_name' given more than once in the same rule
case-insensitive-win.mak:3: target 'program_name' given more than once in the same rule
Do something for program_name.

-----

I understand that real files should be treated in a case-insensitive
manner, but such "phony" targets (whatever it's called)?
The only hit for "sensitive" in my GNU-make.pdf was this:
   Variable names are case-sensitive. The names ‘foo’, ‘FOO’, and ‘Foo’
   all refer to different variables.

I fail to understand all the details around '-DHAVE_CASE_INSENSITIVE_FS',
but is the above .mak-file working as designed on Windows?

If it is, then gnumake aborts in 'install_default_suffix_rules()'
if '-DMAKE_MAINTAINER_MODE' is defined. In default.c, at
  assert (f->cmds == 0);

since AFAICS the implicit ".c" and ".C" rules is the same on Windows.
I can come back to that later.

--
--gv

_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

Re: Case-insensitive targets

Eli Zaretskii
> From: Gisle Vanem <[hidden email]>
> Date: Thu, 2 Aug 2018 14:39:30 +0200
>
> I understand that real files should be treated in a case-insensitive
> manner, but such "phony" targets (whatever it's called)?

I'm not sure Make can distinguish between the two kinds.  E.g., the
rules for generating the "phony" target could be given later.  Paul
will know for sure.

And anyway, wouldn't it be confusing if case-sensitivity changed
depending on whether a file exists or doesn't?

> I fail to understand all the details around '-DHAVE_CASE_INSENSITIVE_FS',
> but is the above .mak-file working as designed on Windows?

Yes.  AFAIR, We deliberately down-case file names we read from the
filesystem before recording them in the Make's internal memory.

_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

Re: Case-insensitive targets

Gisle Vanem-2
Eli Zaretskii wrote:

> I'm not sure Make can distinguish between the two kinds.  E.g., the
> rules for generating the "phony" target could be given later.  Paul
> will know for sure.
>
> And anyway, wouldn't it be confusing if case-sensitivity changed
> depending on whether a file exists or doesn't?

Thanks for answering.  I guess so, yes.

>> I fail to understand all the details around '-DHAVE_CASE_INSENSITIVE_FS',
>> but is the above .mak-file working as designed on Windows?
>
> Yes.  AFAIR, We deliberately down-case file names we read from the
> filesystem before recording them in the Make's internal memory.

Then are there not a problem with adding default suffix rules
for e.g. '.s' and '.S'. According to you "down-case" argument
they must use the same default command?

Can you take a look at 'default.c' in:

install_default_suffix_rules (void)
{
   ...
   for (s = default_suffix_rules; *s != 0; s += 2, loop++)
     {
       struct file *f = enter_file (strcache_add (s[0]));
       /* This function should run before any makefile is parsed.  */
       assert (f->cmds == 0);

I put some trace in this loop and saw that some ".c"/".C",
".f"/".F" etc. rules returned 'f->cmds != NULL' and the
assert() triggers in '-DMAKE_MAINTAINER_MODE'.

 From makeint.h:

/* Disable assert() unless we're a maintainer.
    Some asserts are compute-intensive.  */
#ifndef MAKE_MAINTAINER_MODE
# define NDEBUG 1
#endif

That assert() doesn't seems to consider Windows.
Besides, there seems to be a mem-leak in that loop.

I'm not building with 'MAKE_MAINTAINER_MODE' normally,
but this time I needed some more details.

--
--gv

_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

Re: Case-insensitive targets

Eli Zaretskii
> From: Gisle Vanem <[hidden email]>
> Cc: [hidden email]
> Date: Thu, 2 Aug 2018 16:44:06 +0200
>
>    for (s = default_suffix_rules; *s != 0; s += 2, loop++)
>      {
>        struct file *f = enter_file (strcache_add (s[0]));
>        /* This function should run before any makefile is parsed.  */
>        assert (f->cmds == 0);
>
> I put some trace in this loop and saw that some ".c"/".C",
> ".f"/".F" etc. rules returned 'f->cmds != NULL' and the
> assert() triggers in '-DMAKE_MAINTAINER_MODE'.
>
>  From makeint.h:
>
> /* Disable assert() unless we're a maintainer.
>     Some asserts are compute-intensive.  */
> #ifndef MAKE_MAINTAINER_MODE
> # define NDEBUG 1
> #endif
>
> That assert() doesn't seems to consider Windows.
> Besides, there seems to be a mem-leak in that loop.

I wouldn't be surprised that this mode doesn't work on Windows, I
don't think anyone has ever tried that on that platforms.  I certainly
didn't.

_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

Re: Case-insensitive targets

Paul Smith-20
In reply to this post by Gisle Vanem-2
On Thu, 2018-08-02 at 16:44 +0200, Gisle Vanem wrote:
> install_default_suffix_rules (void)
> {
>    ...
>    for (s = default_suffix_rules; *s != 0; s += 2, loop++)
>      {
>
> That assert() doesn't seems to consider Windows.

It's HIGHLY likely that no one has ever tried to run in maintainer mode
on Windows.  Like Eli, I know I've never done it and if neither of us
have tried I don't know who would have.

Even case-insensitive mode is not completely available as you've
discovered.  The problem is that there's no good way to know whether a
given target is a file (which should be treated case-insensitively as
the filesystem does) or not.

So in order for this to really work you'd pretty much have to perform
all comparisons case-insensitively even things like:

  all:
  aLL:
  aLl:

etc. would have to be considered the same target.

Then there's the question of case-preserving or not.  To be case-
preserving, make would have to be doing all string searches and
comparisons using case-insensitive implementations which would be a lot
of code churn.  And we would have to care a lot more about
internationalization since case comparison is highly locale-specific.

Right now make (IIRC, I don't use case-insensitive mode much) assumes
all internal targets in its makefile are case-sensitive and only does
case-insensitivity when it comes to looking up files on disk.  That
means you have to write all your makefile targets and prerequisites
using identical case.

> Besides, there seems to be a mem-leak in that loop.

I see no mem leak in that function...?

_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

Re: Case-insensitive targets

Eli Zaretskii
> From: Paul Smith <[hidden email]>
> Cc: [hidden email]
> Date: Thu, 02 Aug 2018 11:57:53 -0400
>
> Then there's the question of case-preserving or not.  To be case-
> preserving, make would have to be doing all string searches and
> comparisons using case-insensitive implementations which would be a lot
> of code churn.  And we would have to care a lot more about
> internationalization since case comparison is highly locale-specific.

In addition to the above, there's one more reason not to use
case-preserving implementation: in the Windows world, you can never be
sure all the tools that create and process files preserve letter-case
in file names.  So a random foobar program could produce FOO when you
want it to produce Foo, and then things start to break.

_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

Re: Case-insensitive targets

Gisle Vanem-2
In reply to this post by Paul Smith-20
Paul Smith wrote:

> Then there's the question of case-preserving or not.  To be case-
> preserving, make would have to be doing all string searches and
> comparisons using case-insensitive implementations which would be a lot
> of code churn.  And we would have to care a lot more about
> internationalization since case comparison is highly locale-specific.

Thanks for the detailed explanation.

>> Besides, there seems to be a mem-leak in that loop.
>
> I see no mem leak in that function...?

Ops, you're right. But there are tons of them elsewhere.
Won't hurt and maybe intentional. I removed the mentioned
'assert()' and see no aborts anywhere else.

But I made a little <dmalloc.h> implementation using MSVC's
<CrtDbg.h> and dumped the leaks right before 'exit()' in
main.c's 'die()'. The simple case-insensitive-win.mak in my
1st email shows 4410 leaks!

PS. the makefile and diff used for this _DEBUG-mode test is at:
   https://gist.github.com/gvanem/e8d2db10aa6899c752e5df032fd66785

--
--gv

_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

Re: Case-insensitive targets

Paul Smith-20
On Thu, 2018-08-02 at 20:56 +0200, Gisle Vanem wrote:
> But I made a little <dmalloc.h> implementation using MSVC's
> <CrtDbg.h> and dumped the leaks right before 'exit()' in
> main.c's 'die()'. The simple case-insensitive-win.mak in my
> 1st email shows 4410 leaks!

Hm.  I do run the regression test suite under Valgrind on GNU/Linux
before each release and take a look at the results.  There are always
some few issues around argument parsing, IIRC, but nothing major.  I
haven't done this on Git master HEAD for a while I admit (I don't know
what version of GNU make you're using).

There may be leaks that the regression suite doesn't catch.  Also, that
process wouldn't catch leaks that appear in non-GNU/Linux-specific
code.

_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

Re: Case-insensitive targets

David Boyce-3
Going way back upstream to the original test makefile:

-----
default: program_name

PROGRAM_NAME Program_Name program_name:
        @echo 'Do something for $@.'

-----

The thing is that these targets are not actually declared as phony so of course they're treated as files. I'm surprised no one else mentioned it, and the topic wandered off. What is the behavior when you add ".PHONY: default PROGRAM_NAME Program_Name program_name"?

On Thu, Aug 2, 2018 at 12:14 PM, Paul Smith <[hidden email]> wrote:
On Thu, 2018-08-02 at 20:56 +0200, Gisle Vanem wrote:
> But I made a little <dmalloc.h> implementation using MSVC's
> <CrtDbg.h> and dumped the leaks right before 'exit()' in
> main.c's 'die()'. The simple case-insensitive-win.mak in my
> 1st email shows 4410 leaks!

Hm.  I do run the regression test suite under Valgrind on GNU/Linux
before each release and take a look at the results.  There are always
some few issues around argument parsing, IIRC, but nothing major.  I
haven't done this on Git master HEAD for a while I admit (I don't know
what version of GNU make you're using).

There may be leaks that the regression suite doesn't catch.  Also, that
process wouldn't catch leaks that appear in non-GNU/Linux-specific
code.

_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

Re: Case-insensitive targets

Eli Zaretskii
> From: David Boyce <[hidden email]>
> Date: Thu, 2 Aug 2018 17:52:27 -0700
> Cc: bug-make <[hidden email]>
>
> default: program_name
>
> PROGRAM_NAME Program_Name program_name:
>         @echo 'Do something for $@.'
>
> -----
>
> The thing is that these targets are not actually declared as phony so of course they're treated as files. I'm
> surprised no one else mentioned it, and the topic wandered off. What is the behavior when you add ".PHONY:
> default PROGRAM_NAME Program_Name program_name"?

My Make is built without HAVE_CASE_INSENSITIVE_FS, so I cannot answer
the question about the behavior.  The original example doesn't produce
any warnings for me.

In general, I'd expect PHONY targets to be case-sensitive, because
they don't exist as files, and so down-casing of file names doesn't
affect them.

_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make