Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

A bug in GNU make ?

by syphilis (Archbishop)
on Aug 27, 2023 at 02:27 UTC ( [id://11154072] : perlquestion . print w/replies, xml ) Need Help??

syphilis has asked for the wisdom of the Perl Monks concerning the following question:


This pertains to the Makefile generated by perl when building Glib-Object-Introspection-0.050.
It's the same problem with version 4.2.1 and version 4.4.1 of GNU make. (I haven't tested with any other versions.)

For Windows only, the Makefile.PL directly inserts a few lines into the generated Makefile.
One of those lines is:
PATH += ;build
The intention is to append ";build" to $ENV{PATH} but it instead appends " ;build".
This means that my PATH, which originally terminated in "...D:\msys64\mingw64\bin" then terminates in "...D:\msys64\mingw64\bin ;build".
Hence the (crucial) "D:\msys64\mingw64\bin" folder is no longer in my PATH - causing baffling load_file failures during 'gmake test'.

Notably, my original PATH doesn't terminate with a ';'. While that is perhaps not a good defensive programming approach, I don't believe it's a bug ?
Or, perhaps, the bug is in the instruction being provided by the Makefile.PL. Here is the relevant excerpt from the G-I-O-0.050 Makefile.PL:
$inherited =~ s/($target)/.IMPORT: PATH\nPATH += ;build\n.EXPORT: PATH +\n$1/;
which results in this entry in the generated Makefile:
.IMPORT: PATH PATH += ;build .EXPORT: PATH test_dynamic :: subdirs-test_dynamic $(FULLPERLRUN) "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "u +ndef *Test::Harness::Switches; test_harness($(TEST_VERBOSE), '$(INST_ +LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES)

PS I tried the obvious and naive fix of changing "PATH += ;build" to "PATH+=;build" but the errant space is still being included in the PATH.

PPS Working around the problem is as simple as ensuring that my original path terminates with a semi-colon.The PATH then ends up terminating with "...D:\msys64\mingw64\bin; ;build", which seems to not be a problem.

Replies are listed 'Best First'.
Re: A bug in GNU make ?
by swl (Parson) on Aug 27, 2023 at 09:42 UTC
      Maybe something like (untested): PATH = $(PATH);build

      I had already tried that, and found it to not work:
      Makefile:1160: *** Recursive variable 'PATH' references itself (eventu +ally). Stop.
      However, encouraged by your suggestion, I went back to it and found that either of the following 2 options do the job as intended:
      PATH := $(PATH);build PATH := ${PATH};build
      Does it seem right that both of those bracket types are acceptable ?

      I've gone with altering the appropriate line in the Makefile.PL to:
      $inherited =~ s/($target)/.IMPORT: PATH\nPATH := \$(PATH);build\n.EXPO +RT: PATH\n$1/;
      I think I'll file a Glib::Object::Introspection bug report, suggesting that this change to the Makefile.PL be made.
      Still interested in hearing opinions regarding the correctness of the way gmake interprets the current form.. (Already answered in the affirmative ... pay attention, Rob ;-)

      Thanks again, swl.


        Does it seem right that both of those bracket types are acceptable ?

        The manual states both bracket types are acceptable. I haven't looked into any history behind it, though.

        And for those wondering about the different assignments operators in GNU make, the := is equivalent to assignment operators in most languages in that variables are evaluated at the time of assignment. Make's = operator defers evaluation until use, which is why Rob's case hit the recursion error. More details are in the linked manual chapter (which I only just read so this is all new to me).

Re: A bug in GNU make ?
by Anonymous Monk on Aug 27, 2023 at 08:53 UTC
    There is maybe a path += #comment forces space addition