[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