bugmake - Bugs: bug #57778, Stop looking for an included file...

 
 

bug #57778: Stop looking for an included file once found, even if cannot be opened.

Submitter:  Dmitry Goncharov <dgoncharov>
Submitted:  Sun 09 Feb 2020 05:07:07 PM UTC
   
 
Severity:  3 - Normal Item Group:  None
Status:  Fixed Privacy:  Public
Assigned to:  psmith Open/Closed:  Closed
Component Version:  None Operating System:  Any
Fixed Release:  4.4 Triage Status:  Small Effort
* Mandatory Fields

Add a New Comment Rich Markup
   

Tue 07 Sep 2021 12:25:04 AM UTC, comment #2: 

I've applied this fix, lightly edited for other changes since the patch was created.

Thanks!

Paul D. Smith <psmith>
Group administrator
Sun 09 Feb 2020 05:40:19 PM UTC, comment #1: 

diff --git a/src/read.c b/src/read.c
index db52a55..830f582 100644
--- a/src/read.c
+++ b/src/read.c
@@ -379,19 +379,28 @@ eval_makefile (const char *filename, unsigned short flags)
   /* If the makefile wasn't found and it's either a makefile from
      the 'MAKEFILES' variable or an included makefile,
      search the included makefile search path for this makefile.  */
-  if (ebuf.fp == 0 && (flags & RM_INCLUDED) && *filename != '/')
+  if (ebuf.fp == 0 && (flags & RM_INCLUDED) && *filename != '/' &&
+      deps->error == ENOENT)
     {
       unsigned int i;
       for (i = 0; include_directories[i] != 0; ++i)
         {
           const char *included = concat (3, include_directories[i],
                                          "/", filename);
-          ebuf.fp = fopen (included, "r");
+          ENULLLOOP (ebuf.fp, fopen (included, "r"));
           if (ebuf.fp)
             {
               filename = included;
               break;
             }
+          if (errno != ENOENT)
+            {
+              /* Found a file, but cannot open it.
+                 End lookup and remake the file.  */
+              filename = included;
+              deps->error = errno;
+              break;
+            }
         }
     }
 
diff --git a/tests/scripts/features/include b/tests/scripts/features/include
index 0c63c06..90aab9d 100644
--- a/tests/scripts/features/include
+++ b/tests/scripts/features/include
@@ -64,6 +64,19 @@ error: foo.mk ; @echo $@
    512
   );
 
+# The same as above with an additional include directory.
+#
+mkdir 'hellod';
+run_make_test
+  ('
+-include foo.mk
+error: foo.mk ; @echo $@
+',
+   '-Ihellod',
+   "#MAKE#: * No rule to make target 'foo.mk', needed by 'error'.  Stop.\n",
+   512
+  );
+
 # Make sure that target-specific variables don't impact things.  This could
 # happen because a file record is created when a target-specific variable is
 # set.
@@ -159,7 +172,46 @@ inc2:; echo > $@
 !,
               '', "echo > inc2\necho > inc1\nDONE\n");
 
-rmfiles('inc1', 'inc2');
+unlink('inc1');
+unlink('inc2');
+
+# Test include of make-able file doesn't show an error.
+# Specify an additional include directory.
+run_make_test(q!
+.PHONY: default
+default:; @echo DONE
+
+inc1:; echo > $@
+include inc1
+include inc2
+inc2:; echo > $@
+!,
+              '-Ihellod', "echo > inc2\necho > inc1\nDONE\n");
+
+unlink('inc1');
+unlink('inc2');
+
+
+# Test include of make-able file doesn't show an error.
+# inc1 and inc2 are present in the specified include directory.
+touch('hellod/inc1');
+touch('hellod/inc2');
+run_make_test(q!
+.PHONY: default
+default:; @echo DONE
+
+inc1:; echo > $@
+include inc1
+include inc2
+inc2:; echo > $@
+!,
+              '-Ihellod', "DONE\n");
+
+unlink('inc1');
+unlink('inc2');
+unlink('hellod/inc1');
+unlink('hellod/inc2');
+
 
 # No target gets correct error
 run_make_test('', '', '#MAKE#: * No targets.  Stop.', 512);
@@ -167,7 +219,7 @@ run_make_test('', '', '#MAKE#: * No targets.  Stop.', 512);
 # No target in included file either, still gets correct error.
 touch('inc1.mk');
 run_make_test('include inc1.mk', '', '#MAKE#: * No targets.  Stop.', 512);
-rmfiles('inc1.mk');
+unlink('inc1.mk');
 
 # Include same file multiple times
 
@@ -179,7 +231,7 @@ include inc1
 !,
               '', "echo > inc1\nDEFAULT\n");
 
-rmfiles('inc1');
+unlink('inc1');
 
 if (defined $ERR_no_such_file) {
 
@@ -211,7 +263,7 @@ include inc2
 !,
                   '', "#MAKEFILE#:7: inc2: $ERR_no_such_file\n#MAKE#: * No rule to make target 'inc2'.  Stop.\n", 512);
 
-    rmfiles('inc1');
+    unlink('inc1');
 
     # Included file has a prerequisite that fails to build
 
@@ -223,7 +275,7 @@ foo:; exit 1
 !,
                   '', "exit 1\n#MAKEFILE#:3: inc1: $ERR_no_such_file\n#MAKE#: * [#MAKEFILE#:5: foo] Error 1\n", 512);
 
-    rmfiles('inc1');
+    unlink('inc1');
 
     # Included file has a prerequisite we don't know how to build
 
@@ -234,7 +286,7 @@ inc1: foo; echo > $@
 !,
                   '', "#MAKEFILE#:3: inc1: $ERR_no_such_file\n#MAKE#: * No rule to make target 'foo', needed by 'inc1'.  Stop.\n", 512);
 
-    rmfiles('inc1');
+    unlink('inc1');
 }
 
 # Including files that can't be read should show an error
@@ -248,7 +300,21 @@ all:;@echo $(FOO)
 !,
                   '', "#MAKEFILE#:2: inc1: $ERR_unreadable_file\n#MAKE#: * No rule to make target 'inc1'.  Stop.", 512);
 
+# Including files that can't be read should show an error, even when there is a
+# readable file in an additinal include directory.
+    touch("hellod/inc1");
+
+    run_make_test(q!
+include inc1
+all:;@echo $(FOO)
+!,
+                  '-Ihellod', "#MAKEFILE#:2: inc1: $ERR_unreadable_file\n#MAKE#: * No rule to make target 'inc1'.  Stop.", 512);
+}
+
 # Unreadable files that we know how to successfully recreate should work
+unlink('inc1');
+create_file('inc1', 'FOO := foo');
+chmod 0000, 'inc1';
 
 run_make_test(sprintf(q!
 all:;@echo $(FOO)
@@ -257,7 +323,20 @@ inc1:; @%s $@ && echo FOO := bar > $@
 !, $CMD_rmfile),
                   '', "bar");
 
-    rmfiles('inc1');
-}
+# Unreadable files that we know how to successfully recreate should work.
+# Even when there is a readable file in an additional include directory.
+
+touch("hellod/inc1");
+run_make_test(sprintf(q!
+all:;@echo $(FOO)
+include inc1
+inc1:; @%s $@ && echo FOO := bar > $@
+!, $CMD_rmfile),
+                  '-Ihellod', "bar");
+
+unlink('inc1');
+unlink('hellod/inc1');
+unlink('hellod/inc2');
+rmdir('hellod');
 
 1;

Dmitry Goncharov <dgoncharov>
Sun 09 Feb 2020 05:07:07 PM UTC, original submission:  

Good morning.                                                                                                                                                                      
                                                                                                                                                                                   
Stop looking for an included file once found, even if cannot be opened.                                                                                                            
                                                                                                                                                                                   
If the current directory contains a not readable file and an additional include directory contains a readable file the current file is silently ignored and the file from the additional include directory is silently included.
This can come as an unpleasant surprise and is hardly useful.
This behavior contradicts gnu make manual and usual practice in similar situations.

Gnu make manual explicitly states that lookup continues only if the file is missing.
Gnu make itself stops looking for a prerequisite file in vpath directories, once it found one, even if cannot be opened.
Gnu make stops looking for an included file once it found one and the found one turns out to be corrupt or a directory.
Similarly a compiler stops looking for a header once it found one, even if cannot be opened.


The change from rmfiles to unlink in features/included is needed to have the test pass when -keep is specified.

regards, Dmitry

Dmitry Goncharov <dgoncharov>

 

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

Attach Files:
   
   
Comment:
   

Attached Files

 

Depends on the following items: None found

Items that depend on this one: None found

 

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

    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
    2021-09-07 psmith StatusNone Fixed
        Assigned toNone psmith
        Open/ClosedOpen Closed
        Operating SystemNone Any
        Fixed ReleaseNone 4.4
        Triage StatusNone Small Effort
    2020-02-09 dgoncharov Attached File- Added stop_lookup_for_included.diff, #48386

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code