bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH 2/3] Functioning per-target .ONESHELL...


From: Britton Leo Kerin
Subject: [RFC PATCH 2/3] Functioning per-target .ONESHELL...
Date: Mon, 11 Nov 2024 10:48:53 -0900

It just twiddles global one_shell which should obviously be improved.

I moved all handling of .ONESHELL from check_special() in read.c to
snap_deps().

check_specials() and record_files() both happen before snap_deps(), but
the reason given for check_specials() to exists (to prevent a wrong
    parse of the next line) doesn't seem to actually apply for .ONESHELL
(though I guess it would become applicable if the idea of letting things
 like .ONESHELL become dependencies rather than targets ever got done).
snap_deps() is doing similar things to .ONESHELL so it seems like a nice
place for it, but I guess it could go elsewhere if it really has to.
The handling of .ONESHELL in check_specials() would have to be improved
because as it is now it causes .ONESHELL: with_a_target to still set
global one_shell.

It's possible somebody might want to do incremental adoption the other
way, with .ONESHELL: (global) and .NOTONESHELL: targets, but this would
mean yet another special target for a minority sport feature.
---
 src/file.c    | 12 ++++++++++++
 src/filedef.h |  2 ++
 src/job.c     | 28 ++++++++++++++++++++++++++++
 src/main.c    |  5 +++++
 src/read.c    | 10 ++--------
 src/remake.c  |  7 +++++++
 6 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/src/file.c b/src/file.c
index 6f816c8a..ca3b208e 100644
--- a/src/file.c
+++ b/src/file.c
@@ -28,6 +28,7 @@ this program.  If not, see <https://www.gnu.org/licenses/>.  
*/
 #include "shuffle.h"
 #include "rule.h"
 
+#include "myMakeLog.h"
 
 /* Remember whether snap_deps has been invoked: we need this to be sure we
    don't add new rules (via $(eval ...)) afterwards.  In the future it would
@@ -830,6 +831,17 @@ snap_deps (void)
     else
       no_intermediates = 1;
 
+#if !MK_OS_DOS && !MK_OS_OS2
+  for (f = lookup_file (".ONESHELL"); f != 0; f = f->prev)
+    if (f->deps)
+        for (d = f->deps; d != 0; d = d->next)
+          for (f2 = d->file; f2 != 0; f2 = f2->prev)
+              f2->oneshell = 1;
+    /* .ONESHELL with no deps marks all files as one_shell.  (*/
+    else
+      one_shell = 1;
+#endif
+
   /* The same file cannot be both .INTERMEDIATE and .NOTINTERMEDIATE.
      However, it is possible for a file to be .INTERMEDIATE and also match a
      .NOTINTERMEDIATE pattern.  In that case, the intermediate file has
diff --git a/src/filedef.h b/src/filedef.h
index b2ef1a16..8dd3fe08 100644
--- a/src/filedef.h
+++ b/src/filedef.h
@@ -102,6 +102,8 @@ struct file
                                    not delete it.  */
     unsigned int notintermediate:1; /* Nonzero means a file is a prereq to
                                        .NOTINTERMEDIATE.  */
+    unsigned int oneshell:1;    /* Nonzero means entire recipe should be run in
+                                   a single shell.  */
     unsigned int dontcare:1;    /* Nonzero if no complaint is to be made if
                                    this target cannot be remade.  */
     unsigned int ignore_vpath:1;/* Nonzero if we threw out VPATH name.  */
diff --git a/src/job.c b/src/job.c
index e54a9340..ca95261b 100644
--- a/src/job.c
+++ b/src/job.c
@@ -19,6 +19,8 @@ this program.  If not, see <https://www.gnu.org/licenses/>.  
*/
 #include <assert.h>
 #include <string.h>
 
+#include <myMakeLog.h>
+
 /* Default shell to use.  */
 #if MK_OS_W32
 # include <windows.h>
@@ -1161,6 +1163,8 @@ start_job_command (struct child *child)
   char **argv;
 #endif
 
+  int old_one_shell;
+
   /* If we have a completely empty commandset, stop now.  */
   if (!child->command_ptr)
     goto next_command;
@@ -1255,9 +1259,23 @@ start_job_command (struct child *child)
           }
       }
 #else
+    // FIXME: WORK POINT: we unexpectedly need to twiddle one_shell here
+    // as well as around chop_commands() calls, so there are likely other
+    // places which didn't get hit in our setup where we need to twiddle it
+    // (at least around all construct_command_argv() calls presumably).  It
+    // seemns sort of awful that it needs to be twiddled both places but that's
+    // the existing architecture.  The chop_commands() happens in two places
+    // also and the second one seems uncertain whether the first has happened
+    // yet, ug.  But it's at least sort of working so clean up and make a 
branch
+    // commit probably.
+    old_one_shell = one_shell;
+    if ( child->file->oneshell ) {
+      one_shell = 1;
+    }
     argv = construct_command_argv (p, &end, child->file,
                                    
child->file->cmds->lines_flags[child->command_line - 1] | 
child->file->command_flags,
                                    &child->sh_batch_file);
+    one_shell = old_one_shell;
 #endif
     if (end == NULL)
       child->command_ptr = NULL;
@@ -1656,6 +1674,14 @@ new_job (struct file *file)
   char **lines;
   unsigned int i;
 
+  int old_one_shell;
+
+  old_one_shell = one_shell;
+  if ( file->oneshell ) {
+    one_shell = 1;
+  }
+  one_shell = old_one_shell;
+
   /* Let any previously decided-upon jobs that are waiting
      for the load to go down start before this new one.  */
   start_waiting_jobs ();
@@ -2846,6 +2872,8 @@ construct_command_argv_internal (char *line, char 
**restp, const char *shell,
     }
 #endif /* MK_OS_W32 */
 
+  mL ("at %s:%i: (function %s) line is %s\n", __FILE__, __LINE__, __func__, 
line);
+
   if (restp != NULL)
     *restp = NULL;
 
diff --git a/src/main.c b/src/main.c
index 78084d09..974234c4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,6 +32,8 @@ this program.  If not, see <https://www.gnu.org/licenses/>.  
*/
 # include <fcntl.h>
 #endif
 
+#include <myMakeLog.h>
+
 #if MK_OS_VMS
 int vms_use_mcr_command = 0;
 int vms_always_use_cmd_file = 0;
@@ -1199,6 +1201,9 @@ main (int argc, char **argv, char **envp)
   unsigned int restarts = 0;
   unsigned int syncing = 0;
   int argv_slots;  /* The jobslot info we got from our parent process.  */
+
+  mLInit ();
+
 #if MK_OS_W32
   const char *unix_path = NULL;
   const char *windows32_path = NULL;
diff --git a/src/read.c b/src/read.c
index 2e30ce17..629afaf3 100644
--- a/src/read.c
+++ b/src/read.c
@@ -38,6 +38,8 @@ struct passwd *getpwnam (char *name);
 #include "hash.h"
 #include "warning.h"
 
+#include "myMakeLog.h"
+
 /* A 'struct ebuffer' controls the origin of the makefile we are currently
    eval'ing.
 */
@@ -1892,14 +1894,6 @@ check_specials (struct nameseq *files, int set_default)
           continue;
         }
 
-#if !MK_OS_DOS && !MK_OS_OS2
-      if (!one_shell && streq (nm, ".ONESHELL"))
-        {
-          one_shell = 1;
-          continue;
-        }
-#endif
-
       /* Determine if this target should be made default.  */
 
       if (set_default && default_goal_var->value[0] == '\0')
diff --git a/src/remake.c b/src/remake.c
index 9d7ae8fd..9b070bbf 100644
--- a/src/remake.c
+++ b/src/remake.c
@@ -23,6 +23,8 @@ this program.  If not, see <https://www.gnu.org/licenses/>.  
*/
 #include "warning.h"
 #include "debug.h"
 
+#include "myMakeLog.h"
+
 #include <assert.h>
 
 #ifdef HAVE_FCNTL_H
@@ -1369,7 +1371,12 @@ remake_file (struct file *file)
     }
   else
     {
+      int old_one_shell = one_shell;
+      if ( file->oneshell ) {
+        one_shell = 1;
+      }
       chop_commands (file->cmds);
+      one_shell = old_one_shell;
 
       /* The normal case: start some commands.  */
       if (!touch_flag || file->cmds->any_recurse)
-- 
2.43.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]