mirror of
https://github.com/mirror/make.git
synced 2025-01-26 12:21:02 +08:00
Support dynamic object loading on MS-Windows.
w32/include/dlfcn.h: New file. w32/compat/posixfcn.c: Include dlfcn.h. (dlopen, dlerror, dlsym) [MAKE_LOAD]: New functions, in support of dynamic loading. config.h.W32.template (MAKE_LOAD): Define. load.c (load_object) [HAVE_DOS_PATHS]: Support backslashes and drive letters in file names of dynamic objects.
This commit is contained in:
parent
9a7fe22b19
commit
19a69bafc0
11
ChangeLog
11
ChangeLog
@ -1,5 +1,16 @@
|
||||
2013-04-29 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32/include/dlfcn.h: New file.
|
||||
|
||||
* w32/compat/posixfcn.c: Include dlfcn.h.
|
||||
(dlopen, dlerror, dlsym) [MAKE_LOAD]: New functions, in support of
|
||||
dynamic loading.
|
||||
|
||||
* config.h.W32.template (MAKE_LOAD): Define.
|
||||
|
||||
* load.c (load_object) [HAVE_DOS_PATHS]: Support backslashes and
|
||||
drive letters in file names of dynamic objects.
|
||||
|
||||
* job.c (construct_command_argv_internal) [WINDOWS32]: Return
|
||||
right after generating new_argv for one_shell case. This fixes
|
||||
the Windows build for both Unixy shell and stock Windows shells.
|
||||
|
@ -366,6 +366,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define to 1 to enable job server support in GNU make. */
|
||||
#define MAKE_JOBSERVER 1
|
||||
|
||||
/* Define to 1 to enable 'load' support in GNU make. */
|
||||
#define MAKE_LOAD 1
|
||||
|
||||
/* Define to 1 to enable symbolic link timestamp checking. */
|
||||
/* #undef MAKE_SYMLINKS */
|
||||
|
||||
|
20
load.c
20
load.c
@ -49,7 +49,11 @@ load_object (const gmk_floc *flocp, int noerror,
|
||||
void *dlp = NULL;
|
||||
|
||||
/* If the path has no "/", try the current directory first. */
|
||||
if (! strchr (ldname, '/'))
|
||||
if (! strchr (ldname, '/')
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
&& ! strchr (ldname, '\\')
|
||||
#endif
|
||||
)
|
||||
dlp = dlopen (concat (2, "./", ldname), RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
/* If we haven't opened it yet, try the default search path. */
|
||||
@ -134,6 +138,20 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
|
||||
char *p = new;
|
||||
|
||||
fp = strrchr (*ldname, '/');
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
if (fp)
|
||||
{
|
||||
const char *fp2 = strchr (fp, '\\');
|
||||
|
||||
if (fp2 > fp)
|
||||
fp = fp2;
|
||||
}
|
||||
else
|
||||
fp = strrchr (*ldname, '\\');
|
||||
/* The (improbable) case of d:foo. */
|
||||
if (fp && *fp && fp[1] == ':')
|
||||
fp++;
|
||||
#endif
|
||||
if (!fp)
|
||||
fp = *ldname;
|
||||
else
|
||||
|
@ -21,6 +21,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include <errno.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "dlfcn.h"
|
||||
|
||||
#include "makeint.h"
|
||||
#include "job.h"
|
||||
|
||||
@ -256,3 +258,86 @@ same_stream (FILE *f1, FILE *f2)
|
||||
}
|
||||
|
||||
#endif /* OUTPUT_SYNC */
|
||||
|
||||
#if MAKE_LOAD
|
||||
|
||||
/* Support for dynamic loading of objects. */
|
||||
|
||||
|
||||
static DWORD last_err;
|
||||
|
||||
void *
|
||||
dlopen (const char *file, int mode)
|
||||
{
|
||||
char dllfn[MAX_PATH], *p;
|
||||
HANDLE dllhandle;
|
||||
|
||||
if ((mode & ~(RTLD_LAZY | RTLD_NOW | RTLD_GLOBAL)) != 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
last_err = ERROR_INVALID_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!file)
|
||||
dllhandle = GetModuleHandle (NULL);
|
||||
else
|
||||
{
|
||||
/* MSDN says to be sure to use backslashes in the DLL file name. */
|
||||
strcpy (dllfn, file);
|
||||
for (p = dllfn; *p; p++)
|
||||
if (*p == '/')
|
||||
*p = '\\';
|
||||
|
||||
dllhandle = LoadLibrary (dllfn);
|
||||
}
|
||||
if (!dllhandle)
|
||||
last_err = GetLastError ();
|
||||
|
||||
return dllhandle;
|
||||
}
|
||||
|
||||
char *
|
||||
dlerror (void)
|
||||
{
|
||||
static char errbuf[1024];
|
||||
DWORD ret;
|
||||
|
||||
if (!last_err)
|
||||
return NULL;
|
||||
|
||||
ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
|
||||
| FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, last_err, 0, errbuf, sizeof (errbuf), NULL);
|
||||
while (ret > 0 && (errbuf[ret - 1] == '\n' || errbuf[ret - 1] == '\r'))
|
||||
--ret;
|
||||
|
||||
errbuf[ret] = '\0';
|
||||
if (!ret)
|
||||
sprintf (errbuf, "Error code %lu", last_err);
|
||||
|
||||
last_err = 0;
|
||||
return errbuf;
|
||||
}
|
||||
|
||||
void *
|
||||
dlsym (void *handle, const char *name)
|
||||
{
|
||||
FARPROC addr = NULL;
|
||||
|
||||
if (!handle || handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
last_err = ERROR_INVALID_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr = GetProcAddress (handle, name);
|
||||
if (!addr)
|
||||
last_err = GetLastError ();
|
||||
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
|
||||
#endif /* MAKE_LOAD */
|
||||
|
||||
|
13
w32/include/dlfcn.h
Normal file
13
w32/include/dlfcn.h
Normal file
@ -0,0 +1,13 @@
|
||||
/* dlfcn.h replacement for MS-Windows build. */
|
||||
#ifndef DLFCN_H
|
||||
#define DLFCN_H
|
||||
|
||||
#define RTLD_LAZY 1
|
||||
#define RTLD_NOW 2
|
||||
#define RTLD_GLOBAL 4
|
||||
|
||||
extern void *dlopen (const char *, int);
|
||||
extern void *dlsym (void *, const char *);
|
||||
extern char *dlerror (void);
|
||||
|
||||
#endif /* DLFCN_H */
|
Loading…
Reference in New Issue
Block a user