mirror of
https://git.savannah.gnu.org/git/make.git
synced 2025-01-12 16:45:35 +00:00
* New feature: .LIBPATTERNS controls the way -lfoo dependencies are expanded.
* A few tweaks to the system glob test, after trying it on a system where it's true. * Installed patches to archive handling for AIX 4.3 big archives. * Fix a memory stomp in target-specific variables. * Fix a memory leak in foreach functions.
This commit is contained in:
parent
84f38c9c6f
commit
a66668aabc
10 changed files with 324 additions and 143 deletions
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
||||||
|
1999-02-22 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
|
* NEWS: Mention new .LIBPATTERNS feature.
|
||||||
|
|
||||||
|
* make.texinfo (Libraries/Search): Describe the use and
|
||||||
|
ramifications of the new .LIBPATTERNS variable.
|
||||||
|
|
||||||
|
* remake.c (library_search): Instead of searching only for the
|
||||||
|
hardcoded expansion "libX.a" for a library reference "-lX", we
|
||||||
|
obtain a list of patterns from the .LIBPATTERNS variable and
|
||||||
|
search those in order.
|
||||||
|
|
||||||
|
* default.c: Added a new default variable .LIBPATTERNS. The
|
||||||
|
default for UNIX is "lib%.so lib%.a". Amiga and DOS values are
|
||||||
|
also provided.
|
||||||
|
|
||||||
|
* read.c: Remove bogus HAVE_GLOB_H references; always include
|
||||||
|
vanilla glob.h.
|
||||||
|
|
||||||
|
1999-02-21 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
|
* function.c (expand_function): Set value to 0 to avoid freeing it.
|
||||||
|
* variable.c (pop_variable_scope): Free the value of the variable.
|
||||||
|
(try_variable_definition): For simple variables, use
|
||||||
|
allocated_variable_expand() to avoid stomping on the variable
|
||||||
|
buffer when we still need it for other things.
|
||||||
|
|
||||||
|
* arscan.c: Modified to support AIX 4.3 big archives. The changes
|
||||||
|
are based on information provided by Phil Adams
|
||||||
|
<padams@austin.ibm.com>; thanks!
|
||||||
|
|
||||||
1999-02-19 Paul D. Smith <psmith@gnu.org>
|
1999-02-19 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
* configure.in: Check to see if the GNU glob library is already
|
* configure.in: Check to see if the GNU glob library is already
|
||||||
|
|
26
NEWS
26
NEWS
|
@ -1,12 +1,21 @@
|
||||||
GNU make NEWS -*-indented-text-*-
|
GNU make NEWS -*-indented-text-*-
|
||||||
History of user-visible changes.
|
History of user-visible changes.
|
||||||
19 May 1998
|
22 Feb 1999
|
||||||
|
|
||||||
Copyright (C) 1992,1993,1994,1995,1996,1997,1998 Free Software Foundation, Inc.
|
Copyright (C) 1992,93,94,95,96,97,98,1999 Free Software Foundation, Inc.
|
||||||
See the end for copying conditions.
|
See the end for copying conditions.
|
||||||
|
|
||||||
|
All changes mentioned here are more fully described in the GNU make
|
||||||
|
manual, which is contained in this distribution as the file make.texinfo.
|
||||||
|
|
||||||
Please send GNU make bug reports to bug-make@gnu.org.
|
Please send GNU make bug reports to bug-make@gnu.org.
|
||||||
|
|
||||||
|
Version 3.78
|
||||||
|
|
||||||
|
* Make defines a new variable, .LIBPATTERNS. This variable controls how
|
||||||
|
the link library dependency expansion (dependencies like ``-lfoo'') is
|
||||||
|
performed.
|
||||||
|
|
||||||
Version 3.77
|
Version 3.77
|
||||||
|
|
||||||
* Implement BSD make's "?=" variable assignment operator. The variable
|
* Implement BSD make's "?=" variable assignment operator. The variable
|
||||||
|
@ -659,17 +668,14 @@ Version 3.05
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
Copyright information:
|
Copyright information:
|
||||||
|
|
||||||
Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
Permission is granted to anyone to make or distribute verbatim copies
|
Permission is granted to anyone to make or distribute verbatim copies
|
||||||
of this document as received, in any medium, provided that the
|
of this document as received, in any medium, provided that the
|
||||||
copyright notice and this permission notice are preserved,
|
copyright notice and this permission notice are preserved, thus
|
||||||
thus giving the recipient permission to redistribute in turn.
|
giving the recipient permission to redistribute in turn.
|
||||||
|
|
||||||
Permission is granted to distribute modified versions
|
Permission is granted to distribute modified versions of this
|
||||||
of this document, or of portions of it,
|
document, or of portions of it, under the above conditions, provided
|
||||||
under the above conditions, provided also that they
|
also that they carry prominent notices stating who last changed them.
|
||||||
carry prominent notices stating who last changed them.
|
|
||||||
|
|
||||||
Local variables:
|
Local variables:
|
||||||
version-control: never
|
version-control: never
|
||||||
|
|
198
arscan.c
198
arscan.c
|
@ -213,11 +213,28 @@ ar_scan (archive, function, arg)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* On AIX, define these symbols to be sure to get both archive formats.
|
||||||
|
AIX 4.3 introduced the "big" archive format to support 64-bit object
|
||||||
|
files, so on AIX 4.3 systems we need to support both the "normal" and
|
||||||
|
"big" archive formats. An archive's format is indicated in the
|
||||||
|
"fl_magic" field of the "FL_HDR" structure. For a normal archive,
|
||||||
|
this field will be the string defined by the AIAMAG symbol. For a
|
||||||
|
"big" archive, it will be the string defined by the AIAMAGBIG symbol
|
||||||
|
(at least on AIX it works this way).
|
||||||
|
|
||||||
|
Note: we'll define these symbols regardless of which AIX version
|
||||||
|
we're compiling on, but this is okay since we'll use the new symbols
|
||||||
|
only if they're present. */
|
||||||
|
#ifdef _AIX
|
||||||
|
# define __AR_SMALL__
|
||||||
|
# define __AR_BIG__
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ar.h>
|
#include <ar.h>
|
||||||
|
|
||||||
/* Cray's <ar.h> apparently defines this. */
|
/* Cray's <ar.h> apparently defines this. */
|
||||||
#ifndef AR_HDR_SIZE
|
#ifndef AR_HDR_SIZE
|
||||||
#define AR_HDR_SIZE (sizeof (struct ar_hdr))
|
# define AR_HDR_SIZE (sizeof (struct ar_hdr))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Takes three arguments ARCHIVE, FUNCTION and ARG.
|
/* Takes three arguments ARCHIVE, FUNCTION and ARG.
|
||||||
|
@ -255,6 +272,10 @@ ar_scan (archive, function, arg)
|
||||||
{
|
{
|
||||||
#ifdef AIAMAG
|
#ifdef AIAMAG
|
||||||
FL_HDR fl_header;
|
FL_HDR fl_header;
|
||||||
|
#ifdef AIAMAGBIG
|
||||||
|
int big_archive = 0;
|
||||||
|
FL_HDR_BIG fl_header_big;
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
int long_name = 0;
|
int long_name = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -276,11 +297,42 @@ ar_scan (archive, function, arg)
|
||||||
#ifdef AIAMAG
|
#ifdef AIAMAG
|
||||||
{
|
{
|
||||||
register int nread = read (desc, (char *) &fl_header, FL_HSZ);
|
register int nread = read (desc, (char *) &fl_header, FL_HSZ);
|
||||||
if (nread != FL_HSZ || bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG))
|
|
||||||
|
if (nread != FL_HSZ)
|
||||||
{
|
{
|
||||||
(void) close (desc);
|
(void) close (desc);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
#ifdef AIAMAGBIG
|
||||||
|
/* If this is a "big" archive, then set the flag and
|
||||||
|
re-read the header into the "big" structure. */
|
||||||
|
if (!bcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG))
|
||||||
|
{
|
||||||
|
big_archive = 1;
|
||||||
|
|
||||||
|
/* seek back to beginning of archive */
|
||||||
|
if (lseek (desc, 0, 0) < 0)
|
||||||
|
{
|
||||||
|
(void) close (desc);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* re-read the header into the "big" structure */
|
||||||
|
nread = read (desc, (char *) &fl_header_big, FL_HSZ_BIG);
|
||||||
|
if (nread != FL_HSZ_BIG)
|
||||||
|
{
|
||||||
|
(void) close (desc);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
/* Check to make sure this is a "normal" archive. */
|
||||||
|
if (bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG))
|
||||||
|
{
|
||||||
|
(void) close (desc);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
@ -308,8 +360,18 @@ ar_scan (archive, function, arg)
|
||||||
long int member_offset;
|
long int member_offset;
|
||||||
long int last_member_offset;
|
long int last_member_offset;
|
||||||
|
|
||||||
sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
|
#ifdef AIAMAGBIG
|
||||||
sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
|
if ( big_archive )
|
||||||
|
{
|
||||||
|
sscanf (fl_header_big.fl_fstmoff, "%20ld", &member_offset);
|
||||||
|
sscanf (fl_header_big.fl_lstmoff, "%20ld", &last_member_offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
|
||||||
|
sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
|
||||||
|
}
|
||||||
|
|
||||||
if (member_offset == 0)
|
if (member_offset == 0)
|
||||||
{
|
{
|
||||||
|
@ -330,6 +392,9 @@ ar_scan (archive, function, arg)
|
||||||
{
|
{
|
||||||
register int nread;
|
register int nread;
|
||||||
struct ar_hdr member_header;
|
struct ar_hdr member_header;
|
||||||
|
#ifdef AIAMAGBIG
|
||||||
|
struct ar_hdr_big member_header_big;
|
||||||
|
#endif
|
||||||
#ifdef AIAMAG
|
#ifdef AIAMAG
|
||||||
char name[256];
|
char name[256];
|
||||||
int name_len;
|
int name_len;
|
||||||
|
@ -352,34 +417,73 @@ ar_scan (archive, function, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AIAMAG
|
#ifdef AIAMAG
|
||||||
#define AR_MEMHDR (AR_HDR_SIZE - sizeof (member_header._ar_name))
|
#define AR_MEMHDR_SZ(x) (sizeof(x) - sizeof (x._ar_name))
|
||||||
nread = read (desc, (char *) &member_header, AR_MEMHDR);
|
|
||||||
|
|
||||||
if (nread != AR_MEMHDR)
|
#ifdef AIAMAGBIG
|
||||||
|
if (big_archive)
|
||||||
{
|
{
|
||||||
(void) close (desc);
|
nread = read (desc, (char *) &member_header_big,
|
||||||
return -2;
|
AR_MEMHDR_SZ(member_header_big) );
|
||||||
|
|
||||||
|
if (nread != AR_MEMHDR_SZ(member_header_big))
|
||||||
|
{
|
||||||
|
(void) close (desc);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
sscanf (member_header_big.ar_namlen, "%4d", &name_len);
|
||||||
|
nread = read (desc, name, name_len);
|
||||||
|
|
||||||
|
if (nread != name_len)
|
||||||
|
{
|
||||||
|
(void) close (desc);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
name[name_len] = 0;
|
||||||
|
|
||||||
|
sscanf (member_header_big.ar_date, "%12ld", &dateval);
|
||||||
|
sscanf (member_header_big.ar_uid, "%12d", &uidval);
|
||||||
|
sscanf (member_header_big.ar_gid, "%12d", &gidval);
|
||||||
|
sscanf (member_header_big.ar_mode, "%12o", &eltmode);
|
||||||
|
sscanf (member_header_big.ar_size, "%20ld", &eltsize);
|
||||||
|
|
||||||
|
data_offset = (member_offset + AR_MEMHDR_SZ(member_header_big)
|
||||||
|
+ name_len + 2);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
sscanf (member_header.ar_namlen, "%4d", &name_len);
|
#endif
|
||||||
nread = read (desc, name, name_len);
|
|
||||||
|
|
||||||
if (nread != name_len)
|
|
||||||
{
|
{
|
||||||
(void) close (desc);
|
nread = read (desc, (char *) &member_header,
|
||||||
return -2;
|
AR_MEMHDR_SZ(member_header) );
|
||||||
|
|
||||||
|
if (nread != AR_MEMHDR_SZ(member_header))
|
||||||
|
{
|
||||||
|
(void) close (desc);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
sscanf (member_header.ar_namlen, "%4d", &name_len);
|
||||||
|
nread = read (desc, name, name_len);
|
||||||
|
|
||||||
|
if (nread != name_len)
|
||||||
|
{
|
||||||
|
(void) close (desc);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
name[name_len] = 0;
|
||||||
|
|
||||||
|
sscanf (member_header.ar_date, "%12ld", &dateval);
|
||||||
|
sscanf (member_header.ar_uid, "%12d", &uidval);
|
||||||
|
sscanf (member_header.ar_gid, "%12d", &gidval);
|
||||||
|
sscanf (member_header.ar_mode, "%12o", &eltmode);
|
||||||
|
sscanf (member_header.ar_size, "%12ld", &eltsize);
|
||||||
|
|
||||||
|
data_offset = (member_offset + AR_MEMHDR_SZ(member_header)
|
||||||
|
+ name_len + 2);
|
||||||
}
|
}
|
||||||
|
data_offset += data_offset % 2;
|
||||||
name[name_len] = 0;
|
|
||||||
|
|
||||||
sscanf (member_header.ar_date, "%12ld", &dateval);
|
|
||||||
sscanf (member_header.ar_uid, "%12d", &uidval);
|
|
||||||
sscanf (member_header.ar_gid, "%12d", &gidval);
|
|
||||||
sscanf (member_header.ar_mode, "%12o", &eltmode);
|
|
||||||
sscanf (member_header.ar_size, "%12ld", &eltsize);
|
|
||||||
|
|
||||||
if ((data_offset = member_offset + AR_MEMHDR + name_len + 2) % 2)
|
|
||||||
++data_offset;
|
|
||||||
|
|
||||||
fnval =
|
fnval =
|
||||||
(*function) (desc, name, 0,
|
(*function) (desc, name, 0,
|
||||||
|
@ -493,7 +597,12 @@ ar_scan (archive, function, arg)
|
||||||
/* End of the chain. */
|
/* End of the chain. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
sscanf (member_header.ar_nxtmem, "%12ld", &member_offset);
|
#ifdef AIAMAGBIG
|
||||||
|
if (big_archive)
|
||||||
|
sscanf (member_header_big.ar_nxtmem, "%20ld", &member_offset);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
sscanf (member_header.ar_nxtmem, "%12ld", &member_offset);
|
||||||
|
|
||||||
if (lseek (desc, member_offset, 0) != member_offset)
|
if (lseek (desc, member_offset, 0) != member_offset)
|
||||||
{
|
{
|
||||||
|
@ -562,37 +671,6 @@ ar_name_equal (name, mem, truncated)
|
||||||
if (p != 0)
|
if (p != 0)
|
||||||
name = p + 1;
|
name = p + 1;
|
||||||
|
|
||||||
/* We no longer use this kludge, since we
|
|
||||||
now support long archive member names. */
|
|
||||||
|
|
||||||
#if 0 && !defined (AIAMAG) && !defined (APOLLO)
|
|
||||||
|
|
||||||
{
|
|
||||||
/* `reallylongname.o' matches `reallylongnam.o'.
|
|
||||||
If member names have a trailing slash, that's `reallylongna.o'. */
|
|
||||||
|
|
||||||
struct ar_hdr h;
|
|
||||||
unsigned int max = sizeof (h.ar_name);
|
|
||||||
unsigned int namelen, memlen;
|
|
||||||
|
|
||||||
if (strncmp (name, mem, max - 3))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
namelen = strlen (name);
|
|
||||||
memlen = strlen (mem);
|
|
||||||
|
|
||||||
if (namelen > memlen && memlen >= max - 1
|
|
||||||
&& name[namelen - 2] == '.' && name[namelen - 1] == 'o'
|
|
||||||
&& mem[memlen - 2] == '.' && mem[memlen - 1] == 'o')
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (namelen != memlen)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (namelen < max - 3 || !strcmp (name + max - 3, mem + max - 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* AIX or APOLLO. */
|
|
||||||
#ifndef VMS
|
#ifndef VMS
|
||||||
if (truncated)
|
if (truncated)
|
||||||
{
|
{
|
||||||
|
@ -611,8 +689,6 @@ ar_name_equal (name, mem, truncated)
|
||||||
#endif /* !VMS */
|
#endif /* !VMS */
|
||||||
|
|
||||||
return !strcmp (name, mem);
|
return !strcmp (name, mem);
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef VMS
|
#ifndef VMS
|
||||||
|
|
11
configure.in
11
configure.in
|
@ -154,17 +154,20 @@ rm -f s.conftest conftoast
|
||||||
AC_MSG_CHECKING(if system libc has GNU glob)
|
AC_MSG_CHECKING(if system libc has GNU glob)
|
||||||
AC_CACHE_VAL(make_cv_sys_gnu_glob, [
|
AC_CACHE_VAL(make_cv_sys_gnu_glob, [
|
||||||
AC_TRY_CPP([
|
AC_TRY_CPP([
|
||||||
|
#include <features.h>
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
|
||||||
#define GLOB_INTERFACE_VERSION 1
|
#define GLOB_INTERFACE_VERSION 1
|
||||||
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
|
#if defined _LIBC || !defined __GNU_LIBRARY__ || __GNU_LIBRARY__ <= 1
|
||||||
|
# error no gnu glob
|
||||||
|
#else
|
||||||
# include <gnu-versions.h>
|
# include <gnu-versions.h>
|
||||||
# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
|
# if _GNU_GLOB_INTERFACE_VERSION != GLOB_INTERFACE_VERSION
|
||||||
# error have gnu glob
|
# error no gnu glob
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
], make_cv_sys_gnu_glob=no, make_cv_sys_gnu_glob=yes)])
|
], make_cv_sys_gnu_glob=yes, make_cv_sys_gnu_glob=no)])
|
||||||
case "$make_cv_sys_gnu_glob" in
|
case "$make_cv_sys_gnu_glob" in
|
||||||
yes) AC_MSG_RESULT(yes) ;;
|
yes) AC_MSG_RESULT(yes) ;;
|
||||||
no) AC_MSG_RESULT([no; using local copy])
|
no) AC_MSG_RESULT([no; using local copy])
|
||||||
|
|
10
default.c
10
default.c
|
@ -425,6 +425,16 @@ static char *default_variables[] =
|
||||||
"SCCS_OUTPUT_OPTION", "-G$@",
|
"SCCS_OUTPUT_OPTION", "-G$@",
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _AMIGA
|
||||||
|
".LIBPATTERNS", "%.lib",
|
||||||
|
#else
|
||||||
|
#ifdef __MSDOS__
|
||||||
|
".LIBPATTERNS", "lib%.a $(DJDIR)/lib/lib%.a",
|
||||||
|
#else
|
||||||
|
".LIBPATTERNS", "lib%.so lib%.a",
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* !VMS */
|
#endif /* !VMS */
|
||||||
0, 0
|
0, 0
|
||||||
};
|
};
|
||||||
|
|
|
@ -876,6 +876,7 @@ expand_function (o, function, text, end)
|
||||||
/* Kill the last space. */
|
/* Kill the last space. */
|
||||||
--o;
|
--o;
|
||||||
|
|
||||||
|
v->value = 0;
|
||||||
pop_variable_scope ();
|
pop_variable_scope ();
|
||||||
|
|
||||||
free (var);
|
free (var);
|
||||||
|
|
28
make.texinfo
28
make.texinfo
|
@ -1971,16 +1971,19 @@ directory search with no extra effort.
|
||||||
@cindex @code{VPATH}, and link libraries
|
@cindex @code{VPATH}, and link libraries
|
||||||
@cindex search path for dependencies (@code{VPATH}), and link libraries
|
@cindex search path for dependencies (@code{VPATH}), and link libraries
|
||||||
@cindex @code{-l} (library search)
|
@cindex @code{-l} (library search)
|
||||||
|
@cindex link libraries, patterns matching
|
||||||
|
@cindex @code{.LIBPATTERNS}, and link libraries
|
||||||
|
@vindex .LIBPATTERNS
|
||||||
|
|
||||||
Directory search applies in a special way to libraries used with the
|
Directory search applies in a special way to libraries used with the
|
||||||
linker. This special feature comes into play when you write a dependency
|
linker. This special feature comes into play when you write a dependency
|
||||||
whose name is of the form @samp{-l@var{name}}. (You can tell something
|
whose name is of the form @samp{-l@var{name}}. (You can tell something
|
||||||
strange is going on here because the dependency is normally the name of a
|
strange is going on here because the dependency is normally the name of a
|
||||||
file, and the @emph{file name} of the library looks like
|
file, and the @emph{file name} of a library generally looks like
|
||||||
@file{lib@var{name}.a}, not like @samp{-l@var{name}}.)@refill
|
@file{lib@var{name}.a}, not like @samp{-l@var{name}}.)@refill
|
||||||
|
|
||||||
When a dependency's name has the form @samp{-l@var{name}}, @code{make}
|
When a dependency's name has the form @samp{-l@var{name}}, @code{make}
|
||||||
handles it specially by searching for the file @file{lib@var{name}.a} in
|
handles it specially by searching for the file @file{lib@var{name}.so} in
|
||||||
the current directory, in directories specified by matching @code{vpath}
|
the current directory, in directories specified by matching @code{vpath}
|
||||||
search paths and the @code{VPATH} search path, and then in the
|
search paths and the @code{VPATH} search path, and then in the
|
||||||
directories @file{/lib}, @file{/usr/lib}, and @file{@var{prefix}/lib}
|
directories @file{/lib}, @file{/usr/lib}, and @file{@var{prefix}/lib}
|
||||||
|
@ -1988,7 +1991,11 @@ directories @file{/lib}, @file{/usr/lib}, and @file{@var{prefix}/lib}
|
||||||
@code{make} behave as if @var{prefix} is defined to be the root of the
|
@code{make} behave as if @var{prefix} is defined to be the root of the
|
||||||
DJGPP installation tree).
|
DJGPP installation tree).
|
||||||
|
|
||||||
For example,
|
If that file is not found, then the file @file{lib@var{name}.a} is
|
||||||
|
searched for, in the same directories as above.
|
||||||
|
|
||||||
|
For example, if there is a @file{/usr/lib/libcurses.a} library on your
|
||||||
|
system (and no @file{/usr/lib/libcurses.so} file), then
|
||||||
|
|
||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
|
@ -2002,6 +2009,21 @@ would cause the command @samp{cc foo.c /usr/lib/libcurses.a -o foo} to
|
||||||
be executed when @file{foo} is older than @file{foo.c} or than
|
be executed when @file{foo} is older than @file{foo.c} or than
|
||||||
@file{/usr/lib/libcurses.a}.@refill
|
@file{/usr/lib/libcurses.a}.@refill
|
||||||
|
|
||||||
|
Although the default set of files to be searched for is
|
||||||
|
@file{lib@var{name}.so} and @file{lib@var{name}.a}, this is customizable
|
||||||
|
via the @code{.LIBPATTERNS} variable. Each word in the value of this
|
||||||
|
variable is a pattern string. When a dependency like
|
||||||
|
@samp{-l@var{name}} is seen, @code{make} will replace the percent in
|
||||||
|
each pattern in the list with @var{name} and perform the above directory
|
||||||
|
searches using that library filename. If no library is found, the next
|
||||||
|
word in the list will be used.
|
||||||
|
|
||||||
|
The default value for @code{.LIBPATTERNS} is ``@samp{lib%.so lib%.a}'',
|
||||||
|
which provides the default behavior described above.
|
||||||
|
|
||||||
|
You can turn off link library expansion completely by setting this
|
||||||
|
variable to an empty value.
|
||||||
|
|
||||||
@node Phony Targets, Force Targets, Directory Search, Rules
|
@node Phony Targets, Force Targets, Directory Search, Rules
|
||||||
@section Phony Targets
|
@section Phony Targets
|
||||||
@cindex phony targets
|
@cindex phony targets
|
||||||
|
|
12
read.c
12
read.c
|
@ -18,6 +18,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <glob.h>
|
||||||
|
|
||||||
#include "make.h"
|
#include "make.h"
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
#include "filedef.h"
|
#include "filedef.h"
|
||||||
|
@ -26,12 +28,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include "rule.h"
|
#include "rule.h"
|
||||||
|
|
||||||
/* This is POSIX.2, but most systems using -DPOSIX probably don't have it. */
|
|
||||||
#ifdef HAVE_GLOB_H
|
|
||||||
#include <glob.h>
|
|
||||||
#else
|
|
||||||
#include "glob/glob.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef WINDOWS32
|
#ifndef WINDOWS32
|
||||||
#ifndef _AMIGA
|
#ifndef _AMIGA
|
||||||
|
@ -1564,9 +1560,7 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
|
||||||
if (!pattern_matches (pattern, pattern_percent, name))
|
if (!pattern_matches (pattern, pattern_percent, name))
|
||||||
{
|
{
|
||||||
/* Give a warning if the rule is meaningless. */
|
/* Give a warning if the rule is meaningless. */
|
||||||
error (flocp,
|
error (flocp,"target `%s' doesn't match the target pattern", name);
|
||||||
"target `%s' doesn't match the target pattern",
|
|
||||||
name);
|
|
||||||
this = 0;
|
this = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
137
remake.c
137
remake.c
|
@ -21,6 +21,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include "job.h"
|
#include "job.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "dep.h"
|
#include "dep.h"
|
||||||
|
#include "variable.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
|
@ -1188,82 +1190,111 @@ library_search (lib, mtime_ptr)
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char *libpatterns = NULL;
|
||||||
|
|
||||||
char *libname = &(*lib)[2]; /* Name without the `-l'. */
|
char *libname = &(*lib)[2]; /* Name without the `-l'. */
|
||||||
FILE_TIMESTAMP mtime;
|
FILE_TIMESTAMP mtime;
|
||||||
|
|
||||||
/* Buffer to construct possible names in. */
|
/* Loop variables for the libpatterns value. */
|
||||||
char *buf = xmalloc (sizeof (LIBDIR) + 8 + strlen (libname) + 4 + 2 + 1);
|
char *p, *p2;
|
||||||
|
int len;
|
||||||
|
|
||||||
char *file, **dp;
|
char *file, **dp;
|
||||||
|
|
||||||
/* Look first for `libNAME.a' in the current directory. */
|
/* If we don't have libpatterns, get it. */
|
||||||
|
if (!libpatterns)
|
||||||
#ifndef _AMIGA
|
|
||||||
sprintf (buf, "lib%s.a", libname);
|
|
||||||
#else
|
|
||||||
sprintf (buf, "%s.lib", libname);
|
|
||||||
#endif
|
|
||||||
mtime = name_mtime (buf);
|
|
||||||
if (mtime != (FILE_TIMESTAMP) -1)
|
|
||||||
{
|
{
|
||||||
*lib = buf;
|
int save = warn_undefined_variables_flag;
|
||||||
if (mtime_ptr != 0)
|
warn_undefined_variables_flag = 0;
|
||||||
*mtime_ptr = mtime;
|
|
||||||
return 1;
|
libpatterns = strdup (variable_expand ("$(strip $(.LIBPATTERNS))"));
|
||||||
|
|
||||||
|
warn_undefined_variables_flag = save;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now try VPATH search on that. */
|
/* Loop through all the patterns in .LIBPATTERNS, and search on each one. */
|
||||||
|
p2 = libpatterns;
|
||||||
file = buf;
|
while ((p = find_next_token (&p2, &len)) != 0)
|
||||||
if (vpath_search (&file, mtime_ptr))
|
|
||||||
{
|
{
|
||||||
free (buf);
|
static char *buf = NULL;
|
||||||
*lib = file;
|
static int buflen = 0;
|
||||||
return 1;
|
static int libdir_maxlen = -1;
|
||||||
}
|
char *libbuf = variable_expand ("");
|
||||||
|
|
||||||
/* Now try the standard set of directories. */
|
/* Expand the pattern using LIBNAME as a replacement. */
|
||||||
|
|
||||||
#ifdef __MSDOS__
|
|
||||||
{
|
|
||||||
/* The default library directory is at ${DJDIR}/lib. */
|
|
||||||
struct variable *djdir = lookup_variable ("DJDIR", 5);
|
|
||||||
|
|
||||||
if (djdir)
|
|
||||||
{
|
{
|
||||||
size_t djdir_len = strlen (djdir->value);
|
char c = p[len];
|
||||||
|
char *p3, *p4;
|
||||||
|
|
||||||
if (djdir_len > sizeof(LIBDIR) + 8 + strlen(libname) + 4 + 2)
|
p[len] = '\0';
|
||||||
buf = (char *) xrealloc (djdir_len + 1);
|
p3 = find_percent (p);
|
||||||
sprintf (buf, "%s/lib/lib%s.a", djdir->value, libname);
|
if (!p3)
|
||||||
mtime = name_mtime (buf);
|
|
||||||
if (mtime != (FILE_TIMESTAMP) -1)
|
|
||||||
{
|
{
|
||||||
*lib = buf;
|
/* Give a warning if there is no pattern, then remove the
|
||||||
if (mtime_ptr != 0)
|
pattern so it's ignored next time. */
|
||||||
*mtime_ptr = mtime;
|
error (NILF, ".LIBPATTERNS element `%s' is not a pattern", p);
|
||||||
return 1;
|
for (; len; --len, ++p)
|
||||||
|
*p = ' ';
|
||||||
|
*p = c;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
p4 = variable_buffer_output (libbuf, p, p3-p);
|
||||||
|
p4 = variable_buffer_output (p4, libname, strlen (libname));
|
||||||
|
p4 = variable_buffer_output (p4, p3+1, len - (p3-p));
|
||||||
|
p[len] = c;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (dp = dirs; *dp != 0; ++dp)
|
/* Look first for `libNAME.a' in the current directory. */
|
||||||
{
|
mtime = name_mtime (libbuf);
|
||||||
#ifndef _AMIGA
|
|
||||||
sprintf (buf, "%s/lib%s.a", *dp, libname);
|
|
||||||
#else
|
|
||||||
sprintf (buf, "%s/%s.lib", *dp, libname);
|
|
||||||
#endif
|
|
||||||
mtime = name_mtime (buf);
|
|
||||||
if (mtime != (FILE_TIMESTAMP) -1)
|
if (mtime != (FILE_TIMESTAMP) -1)
|
||||||
{
|
{
|
||||||
*lib = buf;
|
*lib = strdup (libbuf);
|
||||||
if (mtime_ptr != 0)
|
if (mtime_ptr != 0)
|
||||||
*mtime_ptr = mtime;
|
*mtime_ptr = mtime;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now try VPATH search on that. */
|
||||||
|
|
||||||
|
file = libbuf;
|
||||||
|
if (vpath_search (&file, mtime_ptr))
|
||||||
|
{
|
||||||
|
*lib = file;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now try the standard set of directories. */
|
||||||
|
|
||||||
|
if (!buflen)
|
||||||
|
{
|
||||||
|
for (dp = dirs; *dp != 0; ++dp)
|
||||||
|
{
|
||||||
|
int l = strlen (*dp);
|
||||||
|
if (l > libdir_maxlen)
|
||||||
|
libdir_maxlen = l;
|
||||||
|
}
|
||||||
|
buflen = strlen (libbuf);
|
||||||
|
buf = xmalloc(libdir_maxlen + buflen + 2);
|
||||||
|
}
|
||||||
|
else if (buflen < strlen (libbuf))
|
||||||
|
{
|
||||||
|
buflen = strlen (libbuf);
|
||||||
|
buf = xrealloc (buf, libdir_maxlen + buflen + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (dp = dirs; *dp != 0; ++dp)
|
||||||
|
{
|
||||||
|
sprintf (buf, "%s/%s", *dp, libbuf);
|
||||||
|
mtime = name_mtime (buf);
|
||||||
|
if (mtime != (FILE_TIMESTAMP) -1)
|
||||||
|
{
|
||||||
|
*lib = strdup (buf);
|
||||||
|
if (mtime_ptr != 0)
|
||||||
|
*mtime_ptr = mtime;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free (buf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
13
variable.c
13
variable.c
|
@ -265,6 +265,8 @@ pop_variable_scope ()
|
||||||
next = v->next;
|
next = v->next;
|
||||||
|
|
||||||
free (v->name);
|
free (v->name);
|
||||||
|
if (v->value)
|
||||||
|
free (v->value);
|
||||||
free ((char *) v);
|
free ((char *) v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -687,7 +689,7 @@ try_variable_definition (flocp, line, origin)
|
||||||
register char *end;
|
register char *end;
|
||||||
enum { f_bogus,
|
enum { f_bogus,
|
||||||
f_simple, f_recursive, f_append, f_conditional } flavor = f_bogus;
|
f_simple, f_recursive, f_append, f_conditional } flavor = f_bogus;
|
||||||
char *name, *expanded_name, *value;
|
char *name, *expanded_name, *value, *alloc_value=NULL;
|
||||||
struct variable *v;
|
struct variable *v;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -775,8 +777,11 @@ try_variable_definition (flocp, line, origin)
|
||||||
/* Should not be possible. */
|
/* Should not be possible. */
|
||||||
abort ();
|
abort ();
|
||||||
case f_simple:
|
case f_simple:
|
||||||
/* A simple variable definition "var := value". Expand the value. */
|
/* A simple variable definition "var := value". Expand the value.
|
||||||
value = variable_expand (p);
|
We have to allocate memory since otherwise it'll clobber the
|
||||||
|
variable buffer, and we still need that. */
|
||||||
|
alloc_value = allocated_variable_expand (p);
|
||||||
|
value = alloc_value;
|
||||||
break;
|
break;
|
||||||
case f_conditional:
|
case f_conditional:
|
||||||
/* A conditional variable definition "var ?= value".
|
/* A conditional variable definition "var ?= value".
|
||||||
|
@ -931,6 +936,8 @@ try_variable_definition (flocp, line, origin)
|
||||||
v = define_variable (expanded_name, strlen (expanded_name),
|
v = define_variable (expanded_name, strlen (expanded_name),
|
||||||
value, origin, flavor == f_recursive);
|
value, origin, flavor == f_recursive);
|
||||||
|
|
||||||
|
if (alloc_value)
|
||||||
|
free (alloc_value);
|
||||||
free (expanded_name);
|
free (expanded_name);
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
|
Loading…
Reference in a new issue