mirror of
https://github.com/mirror/make.git
synced 2025-03-09 09:10:36 +08:00
Allow dynamically loaded objects to be rebuilt by make.
This commit is contained in:
parent
8e0a5645b8
commit
b70aa3709e
19
ChangeLog
19
ChangeLog
@ -1,5 +1,24 @@
|
||||
2013-01-19 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* doc/make.texi (load Directive): Update to discuss location of
|
||||
loaded object file.
|
||||
(Remaking Loaded Objects): Document remaking of loaded objects.
|
||||
|
||||
* main.c (main): Rename READ_MAKEFILES to READ_FILES.
|
||||
* read.c: Change READ_MAKEFILES to READ_FILES since it now
|
||||
contains loaded object files as well.
|
||||
(read_all_makefiles): Ditto.
|
||||
(eval_makefile): Ditto.
|
||||
(eval): Add any loaded file to the READ_FILES list, so that it
|
||||
will be considered for re-build.
|
||||
|
||||
* load.c (load_file): Return the simple filename (no symbol) in
|
||||
the LDNAME argument (now a const char **).
|
||||
This filename should no longer have "./" prepended: modify the
|
||||
function to always check the current directory if the name has no
|
||||
"/", before using the normal methods.
|
||||
* make.h: Change the load_file() prototype.
|
||||
|
||||
* README.git: Add a bit more documentation on Git workflow & rules.
|
||||
|
||||
2013-01-13 Paul Smith <psmith@gnu.org>
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
@include version.texi
|
||||
@set EDITION 0.72
|
||||
@set RCSID $Id$
|
||||
|
||||
@settitle GNU @code{make}
|
||||
@setchapternewpage odd
|
||||
@ -27,7 +26,7 @@ of @cite{The GNU Make Manual}, for GNU @code{make} version @value{VERSION}.
|
||||
|
||||
Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
|
||||
1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
|
||||
2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||
2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
@ -348,6 +347,7 @@ GNU Guile Integration
|
||||
Loading Dynamic Objects
|
||||
|
||||
* load Directive:: Loading dynamic objects as extensions.
|
||||
* Remaking Loaded Objects:: How loaded objects get remade.
|
||||
|
||||
@end detailmenu
|
||||
@end menu
|
||||
@ -1287,7 +1287,6 @@ in the makefiles. @xref{Include, , Including Other Makefiles}.
|
||||
|
||||
@node Remaking Makefiles, Overriding Makefiles, MAKEFILES Variable, Makefiles
|
||||
@section How Makefiles Are Remade
|
||||
|
||||
@cindex updating makefiles
|
||||
@cindex remaking makefiles
|
||||
@cindex makefile, remaking of
|
||||
@ -6295,7 +6294,6 @@ Has GNU Guile available as an embedded extension language.
|
||||
@item load
|
||||
Supports dynamically loadable objects for creating custom extensions.
|
||||
@xref{Loading Objects, ,Loading Dynamic Objects}.
|
||||
|
||||
@end table
|
||||
|
||||
@vindex .INCLUDE_DIRS @r{(list of include directories)}
|
||||
@ -10539,11 +10537,11 @@ program, although this can be inefficient.
|
||||
In cases where the built-in capabilities of GNU @code{make} are
|
||||
insufficient to your requirements there are two options for extending
|
||||
@code{make}. On systems where it's provided, you can utilize GNU
|
||||
Guile as an embedded scripting language (@pxref{Guile Integration,
|
||||
,GNU Guile Integration}). On systems which support dynamically
|
||||
loadable objects, you can write your own extension in any language
|
||||
(which can be compiled into such an object) and load it to provide
|
||||
extended capabilities (@pxref{load Directive, ,The @code{load} Directive}).
|
||||
Guile as an embedded scripting language (@pxref{Guile Integration,,GNU
|
||||
Guile Integration}). On systems which support dynamically loadable
|
||||
objects, you can write your own extension in any language (which can
|
||||
be compiled into such an object) and load it to provide extended
|
||||
capabilities (@pxref{load Directive, ,The @code{load} Directive}).
|
||||
|
||||
@menu
|
||||
* Guile Integration:: Using Guile as an embedded scripting language.
|
||||
@ -10786,15 +10784,16 @@ providing new capabilities which may then be invoked by your makefile.
|
||||
The @code{load} directive is used to load a dynamic object. Once the
|
||||
object is loaded, a ``setup'' function will be invoked to allow the
|
||||
object to initialize itself and register new facilities with GNU
|
||||
@code{make}. Typically a dynamic object would create new functions,
|
||||
@code{make}. A dynamic object might include new @code{make} functions,
|
||||
for example, and the ``setup'' function would register them with GNU
|
||||
@code{make}'s function handling system.
|
||||
|
||||
@menu
|
||||
* load Directive:: Loading dynamic objects as extensions.
|
||||
* Remaking Loaded Objects:: How loaded objects get remade.
|
||||
@end menu
|
||||
|
||||
@node load Directive, , Loading Objects, Loading Objects
|
||||
@node load Directive, Remaking Loaded Objects, Loading Objects, Loading Objects
|
||||
@subsection The @code{load} Directive
|
||||
@cindex load directive
|
||||
@cindex extensions, load directive
|
||||
@ -10814,21 +10813,33 @@ or:
|
||||
load @var{object-file}(@var{symbol-name}) @dots{}
|
||||
@end example
|
||||
|
||||
In the first form, the file @var{object-file} is dynamically loaded by
|
||||
GNU @code{make}. On failure, @code{make} will print a message and
|
||||
exit. If the load succeeds @code{make} will invoke an initializing
|
||||
function whose name is created by taking the base file name of
|
||||
@var{object-file}, up to the first character which is not a valid
|
||||
symbol name character (alphanumerics and underscores are valid symbol
|
||||
name characters). To this prefix will be appended the suffix
|
||||
@code{_gmake_setup}, then this symbol will be invoked.
|
||||
The file @var{object-file} is dynamically loaded by GNU @code{make}.
|
||||
If @var{object-file} does not include a directory path then it is
|
||||
first looked for in the current directory. If it is not found there,
|
||||
or a directory path is included, then system-specific paths will be
|
||||
searched. If the load fails for any reason, @code{make} will print a
|
||||
message and exit.
|
||||
|
||||
In the second form, the function @var{symbol-name} will be invoked.
|
||||
If the load succeeds @code{make} will invoke an initializing function.
|
||||
|
||||
If @var{symbol-name} is provided, it will be used as the name of the
|
||||
initializing function.
|
||||
|
||||
If no @var{symbol-name} is provided, the initializing function name is
|
||||
created by taking the base file name of @var{object-file}, up to the
|
||||
first character which is not a valid symbol name character
|
||||
(alphanumerics and underscores are valid symbol name characters). To
|
||||
this prefix will be appended the suffix @code{_gmake_setup}.
|
||||
|
||||
More than one object file may be loaded with a single @code{load}
|
||||
directive, and both forms of @code{load} arguments may be used in the
|
||||
same directive.
|
||||
|
||||
The initializing function will be provided the file name and line
|
||||
number of the invocation of the @code{load} operation. It should
|
||||
return a value of type @code{int}, which must be @code{0} on failure
|
||||
and non-@code{0} on success.
|
||||
|
||||
For example:
|
||||
|
||||
@example
|
||||
@ -10864,6 +10875,22 @@ generated if an object fails to load. The failed object is not added
|
||||
to the @code{.LOADED} variable, which can then be consulted to
|
||||
determine if the load was successful.
|
||||
|
||||
@node Remaking Loaded Objects, , load Directive, Loading Objects
|
||||
@subsection How Loaded Objects Are Remade
|
||||
@cindex updating load objects
|
||||
@cindex remaking load objects
|
||||
@cindex load objects, remaking of
|
||||
|
||||
Loaded objects undergo the same re-make procedure as makefiles
|
||||
(@pxref{Remaking Makefiles, ,How Makefiles Are Remade}). If any
|
||||
loaded object is recreated, then @code{make} will start from scratch
|
||||
and re-read all the makefiles, and reload the object files again. It
|
||||
is not necessary for the loaded object to do anything special to
|
||||
support this.@refill
|
||||
|
||||
It's up to the makefile author to provide the rules needed for
|
||||
rebuilding the loaded object.
|
||||
|
||||
@node Features, Missing, Extending make, Top
|
||||
@chapter Features of GNU @code{make}
|
||||
@cindex features of GNU @code{make}
|
||||
@ -11007,6 +11034,12 @@ nonexistent file comes from SunOS 4 @code{make}. (But note that SunOS 4
|
||||
The @code{!=} shell assignment operator exists in many BSD of
|
||||
@code{make} and is purposefully implemented here to behave identically
|
||||
to those implementations.
|
||||
|
||||
@item
|
||||
Various build management tools are implemented using scripting
|
||||
languages such as Perl or Python and thus provide a natural embedded
|
||||
scripting language, similar to GNU @code{make}'s integration of GNU
|
||||
Guile.
|
||||
@end itemize
|
||||
|
||||
The remaining features are inventions new in GNU @code{make}:
|
||||
@ -11116,6 +11149,10 @@ Various new built-in implicit rules.
|
||||
The built-in variable @samp{MAKE_VERSION} gives the version number of
|
||||
@code{make}.
|
||||
@vindex MAKE_VERSION
|
||||
|
||||
@item
|
||||
Load dynamic objects which can modify the behavior of @code{make}.
|
||||
@xref{Loading Objects, ,Loading Dynamic Objects}.
|
||||
@end itemize
|
||||
|
||||
@node Missing, Makefile Conventions, Features, Top
|
||||
|
43
load.c
43
load.c
@ -58,12 +58,12 @@ init_symbol (const struct floc *flocp, const char *ldname, load_func_t symp)
|
||||
}
|
||||
|
||||
int
|
||||
load_file (const struct floc *flocp, const char *ldname, int noerror)
|
||||
load_file (const struct floc *flocp, const char **ldname, int noerror)
|
||||
{
|
||||
load_func_t symp;
|
||||
const char *fp;
|
||||
char *symname = NULL;
|
||||
char *new = alloca (strlen (ldname) + CSTRLEN (SYMBOL_EXTENSION) + 1);
|
||||
char *new = alloca (strlen (*ldname) + CSTRLEN (SYMBOL_EXTENSION) + 1);
|
||||
|
||||
if (! global_dl)
|
||||
{
|
||||
@ -73,27 +73,27 @@ load_file (const struct floc *flocp, const char *ldname, int noerror)
|
||||
}
|
||||
|
||||
/* If a symbol name was provided, use it. */
|
||||
fp = strchr (ldname, '(');
|
||||
fp = strchr (*ldname, '(');
|
||||
if (fp)
|
||||
{
|
||||
const char *ep;
|
||||
|
||||
/* If there's an open paren, see if there's a close paren: if so use
|
||||
/* There's an open paren, so see if there's a close paren: if so use
|
||||
that as the symbol name. We can't have whitespace: it would have
|
||||
been chopped up before this function is called. */
|
||||
ep = strchr (fp+1, ')');
|
||||
if (ep && ep[1] == '\0')
|
||||
{
|
||||
int l = fp - ldname;;
|
||||
int l = fp - *ldname;;
|
||||
|
||||
++fp;
|
||||
if (fp == ep)
|
||||
fatal (flocp, _("Empty symbol name for load: %s"), ldname);
|
||||
fatal (flocp, _("Empty symbol name for load: %s"), *ldname);
|
||||
|
||||
/* Make a copy of the ldname part. */
|
||||
memcpy (new, ldname, l);
|
||||
memcpy (new, *ldname, l);
|
||||
new[l] = '\0';
|
||||
ldname = new;
|
||||
*ldname = new;
|
||||
|
||||
/* Make a copy of the symbol name part. */
|
||||
symname = new + l + 1;
|
||||
@ -102,14 +102,17 @@ load_file (const struct floc *flocp, const char *ldname, int noerror)
|
||||
}
|
||||
}
|
||||
|
||||
/* Add this name to the string cache so it can be reused later. */
|
||||
*ldname = strcache_add (*ldname);
|
||||
|
||||
/* If we didn't find a symbol name yet, construct it from the ldname. */
|
||||
if (! symname)
|
||||
{
|
||||
char *p = new;
|
||||
|
||||
fp = strrchr (ldname, '/');
|
||||
fp = strrchr (*ldname, '/');
|
||||
if (!fp)
|
||||
fp = ldname;
|
||||
fp = *ldname;
|
||||
else
|
||||
++fp;
|
||||
while (isalnum (*fp) || *fp == '_')
|
||||
@ -118,12 +121,22 @@ load_file (const struct floc *flocp, const char *ldname, int noerror)
|
||||
symname = new;
|
||||
}
|
||||
|
||||
DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, ldname));
|
||||
DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, *ldname));
|
||||
|
||||
/* See if it's already defined. */
|
||||
symp = (load_func_t) dlsym (global_dl, symname);
|
||||
if (! symp) {
|
||||
void *dlp = dlopen (ldname, RTLD_LAZY|RTLD_GLOBAL);
|
||||
void *dlp = NULL;
|
||||
|
||||
/* If the path has no "/", try the current directory first. */
|
||||
if (! strchr (*ldname, '/'))
|
||||
dlp = dlopen (concat (2, "./", *ldname), RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
/* If we haven't opened it yet, try the default search path. */
|
||||
if (! dlp)
|
||||
dlp = dlopen (*ldname, RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
/* Still no? Then fail. */
|
||||
if (! dlp)
|
||||
{
|
||||
if (noerror)
|
||||
@ -136,17 +149,17 @@ load_file (const struct floc *flocp, const char *ldname, int noerror)
|
||||
symp = dlsym (dlp, symname);
|
||||
if (! symp)
|
||||
fatal (flocp, _("Failed to load symbol %s from %s: %s"),
|
||||
symname, ldname, dlerror());
|
||||
symname, *ldname, dlerror());
|
||||
}
|
||||
|
||||
/* Invoke the symbol to initialize the loaded object. */
|
||||
return init_symbol(flocp, ldname, symp);
|
||||
return init_symbol(flocp, *ldname, symp);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
load_file (const struct floc *flocp, const char *ldname, int noerror)
|
||||
load_file (const struct floc *flocp, const char **ldname, int noerror)
|
||||
{
|
||||
if (! noerror)
|
||||
fatal (flocp, _("The 'load' operation is not supported on this platform."));
|
||||
|
20
main.c
20
main.c
@ -918,7 +918,7 @@ main (int argc, char **argv, char **envp)
|
||||
{
|
||||
static char *stdin_nm = 0;
|
||||
int makefile_status = MAKE_SUCCESS;
|
||||
struct dep *read_makefiles;
|
||||
struct dep *read_files;
|
||||
PATH_VAR (current_directory);
|
||||
unsigned int restarts = 0;
|
||||
#ifdef WINDOWS32
|
||||
@ -1667,7 +1667,7 @@ main (int argc, char **argv, char **envp)
|
||||
|
||||
/* Read all the makefiles. */
|
||||
|
||||
read_makefiles = read_all_makefiles (makefiles == 0 ? 0 : makefiles->list);
|
||||
read_files = read_all_makefiles (makefiles == 0 ? 0 : makefiles->list);
|
||||
|
||||
#ifdef WINDOWS32
|
||||
/* look one last time after reading all Makefiles */
|
||||
@ -1930,7 +1930,7 @@ main (int argc, char **argv, char **envp)
|
||||
/* Initialize the remote job module. */
|
||||
remote_setup ();
|
||||
|
||||
if (read_makefiles != 0)
|
||||
if (read_files != 0)
|
||||
{
|
||||
/* Update any makefiles if necessary. */
|
||||
|
||||
@ -1951,7 +1951,7 @@ main (int argc, char **argv, char **envp)
|
||||
{
|
||||
register struct dep *d, *last;
|
||||
last = 0;
|
||||
d = read_makefiles;
|
||||
d = read_files;
|
||||
while (d != 0)
|
||||
{
|
||||
struct file *f = d->file;
|
||||
@ -1973,14 +1973,14 @@ main (int argc, char **argv, char **envp)
|
||||
f->name));
|
||||
|
||||
if (last == 0)
|
||||
read_makefiles = d->next;
|
||||
read_files = d->next;
|
||||
else
|
||||
last->next = d->next;
|
||||
|
||||
/* Free the storage. */
|
||||
free_dep (d);
|
||||
|
||||
d = last == 0 ? read_makefiles : last->next;
|
||||
d = last == 0 ? read_files : last->next;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -2001,7 +2001,7 @@ main (int argc, char **argv, char **envp)
|
||||
define_makeflags (1, 1);
|
||||
|
||||
rebuilding_makefiles = 1;
|
||||
status = update_goal_chain (read_makefiles);
|
||||
status = update_goal_chain (read_files);
|
||||
rebuilding_makefiles = 0;
|
||||
|
||||
switch (status)
|
||||
@ -2028,7 +2028,7 @@ main (int argc, char **argv, char **envp)
|
||||
unsigned int i;
|
||||
struct dep *d;
|
||||
|
||||
for (i = 0, d = read_makefiles; d != 0; ++i, d = d->next)
|
||||
for (i = 0, d = read_files; d != 0; ++i, d = d->next)
|
||||
{
|
||||
/* Reset the considered flag; we may need to look at the file
|
||||
again to print an error. */
|
||||
@ -2077,7 +2077,7 @@ main (int argc, char **argv, char **envp)
|
||||
}
|
||||
}
|
||||
/* Reset this to empty so we get the right error message below. */
|
||||
read_makefiles = 0;
|
||||
read_files = 0;
|
||||
|
||||
if (any_remade)
|
||||
goto re_exec;
|
||||
@ -2326,7 +2326,7 @@ main (int argc, char **argv, char **envp)
|
||||
|
||||
if (!goals)
|
||||
{
|
||||
if (read_makefiles == 0)
|
||||
if (read_files == 0)
|
||||
fatal (NILF, _("No targets specified and no makefile found"));
|
||||
|
||||
fatal (NILF, _("No targets"));
|
||||
|
4
make.h
4
make.h
@ -476,9 +476,9 @@ int strcache_setbufsize (unsigned int size);
|
||||
int guile_gmake_setup (const struct floc *flocp);
|
||||
#endif
|
||||
|
||||
/* Loadable object support */
|
||||
/* Loadable object support. Sets to the strcached name of the loaded file. */
|
||||
typedef int (*load_func_t)(const struct floc *flocp);
|
||||
int load_file (const struct floc *flocp, const char *filename, int noerror);
|
||||
int load_file (const struct floc *flocp, const char **filename, int noerror);
|
||||
|
||||
#ifdef HAVE_VFORK_H
|
||||
# include <vfork.h>
|
||||
|
42
read.c
42
read.c
@ -127,9 +127,9 @@ static unsigned int max_incl_len;
|
||||
|
||||
const struct floc *reading_file = 0;
|
||||
|
||||
/* The chain of makefiles read by read_makefile. */
|
||||
/* The chain of files read by read_all_makefiles. */
|
||||
|
||||
static struct dep *read_makefiles = 0;
|
||||
static struct dep *read_files = 0;
|
||||
|
||||
static int eval_makefile (const char *filename, int flags);
|
||||
static void eval (struct ebuffer *buffer, int flags);
|
||||
@ -163,7 +163,7 @@ static char *unescape_char (char *string, int c);
|
||||
#define word1eq(s) (wlen == CSTRLEN (s) && strneq (s, p, CSTRLEN (s)))
|
||||
|
||||
|
||||
/* Read in all the makefiles and return the chain of their names. */
|
||||
/* Read in all the makefiles and return a chain of targets to rebuild. */
|
||||
|
||||
struct dep *
|
||||
read_all_makefiles (const char **makefiles)
|
||||
@ -215,18 +215,18 @@ read_all_makefiles (const char **makefiles)
|
||||
if (makefiles != 0)
|
||||
while (*makefiles != 0)
|
||||
{
|
||||
struct dep *tail = read_makefiles;
|
||||
register struct dep *d;
|
||||
struct dep *tail = read_files;
|
||||
struct dep *d;
|
||||
|
||||
if (! eval_makefile (*makefiles, 0))
|
||||
perror_with_name ("", *makefiles);
|
||||
|
||||
/* Find the right element of read_makefiles. */
|
||||
d = read_makefiles;
|
||||
/* Find the first element eval_makefile() added to read_files. */
|
||||
d = read_files;
|
||||
while (d->next != tail)
|
||||
d = d->next;
|
||||
|
||||
/* Use the storage read_makefile allocates. */
|
||||
/* Reuse the storage allocated for the read_file. */
|
||||
*makefiles = dep_name (d);
|
||||
++num_makefiles;
|
||||
++makefiles;
|
||||
@ -259,8 +259,8 @@ read_all_makefiles (const char **makefiles)
|
||||
else
|
||||
{
|
||||
/* No default makefile was found. Add the default makefiles to the
|
||||
'read_makefiles' chain so they will be updated if possible. */
|
||||
struct dep *tail = read_makefiles;
|
||||
'read_files' chain so they will be updated if possible. */
|
||||
struct dep *tail = read_files;
|
||||
/* Add them to the tail, after any MAKEFILES variable makefiles. */
|
||||
while (tail != 0 && tail->next != 0)
|
||||
tail = tail->next;
|
||||
@ -273,7 +273,7 @@ read_all_makefiles (const char **makefiles)
|
||||
made, and main not to die if we can't make this file. */
|
||||
d->changed = RM_DONTCARE;
|
||||
if (tail == 0)
|
||||
read_makefiles = d;
|
||||
read_files = d;
|
||||
else
|
||||
tail->next = d;
|
||||
tail = d;
|
||||
@ -283,7 +283,7 @@ read_all_makefiles (const char **makefiles)
|
||||
}
|
||||
}
|
||||
|
||||
return read_makefiles;
|
||||
return read_files;
|
||||
}
|
||||
|
||||
/* Install a new conditional and return the previous one. */
|
||||
@ -380,8 +380,8 @@ eval_makefile (const char *filename, int flags)
|
||||
|
||||
/* Add FILENAME to the chain of read makefiles. */
|
||||
deps = alloc_dep ();
|
||||
deps->next = read_makefiles;
|
||||
read_makefiles = deps;
|
||||
deps->next = read_files;
|
||||
read_files = deps;
|
||||
deps->file = lookup_file (filename);
|
||||
if (deps->file == 0)
|
||||
deps->file = enter_file (filename);
|
||||
@ -923,20 +923,28 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
Don't expand archive references or strip "./" */
|
||||
p2 = p;
|
||||
files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL,
|
||||
PARSEFS_NOAR|PARSEFS_NOSTRIP);
|
||||
PARSEFS_NOAR);
|
||||
free (p);
|
||||
|
||||
/* Load each file. */
|
||||
/* Load each file and add it to the list "to be rebuilt". */
|
||||
while (files != 0)
|
||||
{
|
||||
struct nameseq *next = files->next;
|
||||
const char *name = files->name;
|
||||
struct dep *deps;
|
||||
|
||||
free_ns (files);
|
||||
files = next;
|
||||
|
||||
if (! load_file (&ebuf->floc, name, noerror) && ! noerror)
|
||||
if (! load_file (&ebuf->floc, &name, noerror) && ! noerror)
|
||||
fatal (&ebuf->floc, _("%s: failed to load"), name);
|
||||
|
||||
deps = alloc_dep ();
|
||||
deps->next = read_files;
|
||||
read_files = deps;
|
||||
deps->file = lookup_file (name);
|
||||
if (deps->file == 0)
|
||||
deps->file = enter_file (name);
|
||||
}
|
||||
|
||||
continue;
|
||||
|
@ -1,3 +1,9 @@
|
||||
2013-01-19 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/load: Test loaded files with and without "./"
|
||||
prefix. Add tests for automatically rebuilding loaded files if
|
||||
they are out of date or non-existent.
|
||||
|
||||
2013-01-13 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/archives: Add a check targets that have parens,
|
||||
|
@ -49,7 +49,7 @@ run_make_test('testload.so: testload.c ; @$(CC) -g -shared -fPIC -o $@ $<',
|
||||
# TEST 1
|
||||
run_make_test(q!
|
||||
all: ; @echo $(func-a foo) $(func-b bar)
|
||||
load ./testload.so
|
||||
load testload.so
|
||||
!,
|
||||
'', "func-a\n");
|
||||
|
||||
@ -64,19 +64,42 @@ load ./testload.so(explicit_setup)
|
||||
# TEST 3
|
||||
# Verify the .LOADED variable
|
||||
run_make_test(q!
|
||||
all: ; @echo $(filter ./testload.so,$(.LOADED)) $(func-a foo) $(func-b bar)
|
||||
load ./testload.so(explicit_setup)
|
||||
all: ; @echo $(filter testload.so,$(.LOADED)) $(func-a foo) $(func-b bar)
|
||||
load testload.so(explicit_setup)
|
||||
!,
|
||||
'', "./testload.so func-b\n");
|
||||
'', "testload.so func-b\n");
|
||||
|
||||
# TEST 4
|
||||
# Check multiple loads
|
||||
run_make_test(q!
|
||||
all: ; @echo $(filter ./testload.so,$(.LOADED)) $(func-a foo) $(func-b bar)
|
||||
all: ; @echo $(filter testload.so,$(.LOADED)) $(func-a foo) $(func-b bar)
|
||||
load ./testload.so
|
||||
load ./testload.so(explicit_setup)
|
||||
load testload.so(explicit_setup)
|
||||
!,
|
||||
'', "./testload.so func-a\n");
|
||||
'', "testload.so func-a\n");
|
||||
|
||||
# TEST 5
|
||||
# Check auto-rebuild of loaded file that's out of date
|
||||
utouch(-10, 'testload.so');
|
||||
touch('testload.c');
|
||||
|
||||
run_make_test(q!
|
||||
all: ; @echo $(func-a foo) $(func-b bar)
|
||||
load ./testload.so
|
||||
testload.so: testload.c ; @echo "rebuilding $@"; $(CC) -g -shared -fPIC -o $@ $<
|
||||
!,
|
||||
'', "rebuilding testload.so\nfunc-a\n");
|
||||
|
||||
# TEST 5
|
||||
# Check auto-rebuild of loaded file when it doesn't exist
|
||||
unlink('testload.so');
|
||||
|
||||
run_make_test(q!
|
||||
all: ; @echo $(func-a foo) $(func-b bar)
|
||||
-load ./testload.so(explicit_setup)
|
||||
%.so: %.c ; @echo "rebuilding $@"; $(CC) -g -shared -fPIC -o $@ $<
|
||||
!,
|
||||
'', "rebuilding testload.so\nfunc-b\n");
|
||||
|
||||
unlink(qw(testload.c testload.so)) unless $keep;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user