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