GNU make NEWS -*-indented-text-*-
History of user-visible changes.
- 05 Oct 2014
+ 12 Jul 2015
See the end of this file for copyrights and conditions.
See the README file and the GNU make manual for instructions for
reporting bugs.
\f
-Version 4.1.90 (05 Oct 2014)
+Version 4.1.90 (12 Jul 2015)
A complete list of bugs fixed in this version is available here:
http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=106&set=custom
+* New variable: $(.SHELLSTATUS) is set to the exit status of the last != or
+ $(shell ...) function invoked in this instance of make. This will be "0" if
+ successful or not "0" if not successful. The variable value is unset if no
+ != or $(shell ...) function has been invoked.
+
* VMS-specific changes:
* Perl test harness now works.
@end example
The shell assignment operator @samp{!=} can be used to execute a
-program and set a variable to its output. This operator first
+shell script and set a variable to its output. This operator first
evaluates the right-hand side, then passes that result to the shell
for execution. If the result of the execution ends in a newline, that
one newline is removed; all other newlines are replaced by spaces.
var := $(shell find . -name "*.c")
@end example
+As with the @code{shell} function, the exit status of the just-invoked
+shell script is stored in the @code{.SHELLSTATUS} variable.
+
@node Appending, Override Directive, Setting, Using Variables
@section Appending More Text to Variables
expanded variables vs.@: simply expanded variables (@pxref{Flavors, ,The
Two Flavors of Variables}).
+@vindex .SHELLSTATUS
+After the @code{shell} function or @samp{!=} assignment operator is
+used, its exit status is placed in the @code{.SHELLSTATUS} variable.
+
Here are some examples of the use of the @code{shell} function:
@example
}
pid_t shell_function_pid = 0;
-int shell_function_completed;
+static int shell_function_completed;
+
+void
+shell_completed (int exit_code, int exit_sig)
+{
+ char buf[256];
+
+ shell_function_pid = 0;
+ if (exit_sig == 0 && exit_code == 127)
+ shell_function_completed = -1;
+ else
+ shell_function_completed = 1;
+
+ sprintf (buf, "%d", exit_code);
+ define_variable_cname (".SHELLSTATUS", buf, o_override, 0);
+}
#ifdef WINDOWS32
/*untested*/
errno = EINTR;
else if (errno == 0)
errno = ENOMEM;
- shell_function_completed = -1;
+ if (fpipe)
+ pclose (fpipe);
+ shell_completed (127, 0);
}
else
{
pipedes[0] = fileno (fpipe);
*pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
errno = e;
- shell_function_completed = 1;
}
return fpipe;
}
#endif
return o;
}
-#endif
+#endif /* !__MSDOS__ */
/* Using a target environment for 'shell' loses in cases like:
export var = $(shell echo foobie)
if (pipedes[0] < 0)
{
/* Open of the pipe failed, mark as failed execution. */
- shell_function_completed = -1;
+ shell_completed (127, 0);
perror_with_name (error_prefix, "pipe");
return o;
}
/* Close the read side of the pipe. */
#ifdef __MSDOS__
if (fpipe)
- (void) pclose (fpipe);
+ {
+ int st = pclose (fpipe);
+ shell_completed (st, 0);
+ }
#else
(void) close (pipedes[0]);
#endif
}
shell_function_pid = 0;
- /* The child_handler function will set shell_function_completed
- to 1 when the child dies normally, or to -1 if it
- dies with status 127, which is most likely an exec fail. */
+ /* shell_completed() will set shell_function_completed to 1 when the
+ child dies normally, or to -1 if it dies with status 127, which is
+ most likely an exec fail. */
if (shell_function_completed == -1)
{
}
extern pid_t shell_function_pid;
-extern int shell_function_completed;
/* Reap all dead children, storing the returned status and the new command
state ('cs_finished') in the 'file' member of the 'struct child' for the
/* Check if this is the child of the 'shell' function. */
if (!remote && pid == shell_function_pid)
{
- /* It is. Leave an indicator for the 'shell' function. */
- if (exit_sig == 0 && exit_code == 127)
- shell_function_completed = -1;
- else
- shell_function_completed = 1;
+ shell_completed (exit_code, exit_sig);
break;
}
$details = '';
+# Test standard shell
+run_make_test('.PHONY: all
+OUT := $(shell echo hi)
+all: ; @echo $(OUT)
+ ','','hi');
# Test shells inside rules.
run_make_test('.PHONY: all
all: ; @echo $(shell echo hi)
-','','hi');
+ ','','hi');
+
+# Verify .SHELLSTATUS
+run_make_test('.PHONY: all
+PRE := $(.SHELLSTATUS)
+$(shell exit 0)
+OK := $(.SHELLSTATUS)
+$(shell exit 1)
+BAD := $(.SHELLSTATUS)
+all: ; @echo PRE=$(PRE) OK=$(OK) BAD=$(BAD)
+ ','','PRE= OK=0 BAD=1');
# Test unescaped comment characters in shells. Savannah bug #20513
export HI = $(shell echo hi)
.PHONY: all
all: ; @echo $$HI
-','','hi');
+ ','','hi');
1;
const char *replace_percent);
char *patsubst_expand (char *o, const char *text, char *pattern, char *replace);
char *func_shell_base (char *o, char **argv, int trim_newlines);
-
+void shell_completed (int exit_code, int exit_sig);
/* expand.c */
char *recursively_expand_for_file (struct variable *v, struct file *file);