[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] dynamic object-file support for *-*-mingw32 and *-*-msys
From: |
Pekka Seppänen |
Subject: |
[PATCH] dynamic object-file support for *-*-mingw32 and *-*-msys |
Date: |
Fri, 18 Aug 2017 16:15:15 +0300 |
User-agent: |
Roundcube Webmail/1.2.4 |
Hello.
It seems that the dynamic object loading via `load' seems to be a bit
incomplete on Windows (~ish) platforms. It has (and hoping to say, was)
mostly to do with the build envinronment, so I decided to fix that.
From what I see, excluding cygwin, the dominant (and up-to-date) POSIX
alike envinroments for Windows are msys and mingw. While they both
execute natively without any external emulation layer, the first doesn't
expose Win32 API by default while the latter does. Currently dynamic
object loading expects Win32 build to be compiled via build_win32.bat --
which neither of the systems do. They both use automake/autoconf, so for
msys no gmk_* functions get exported as it's not detected (as it
shouldn't be) as a Win32 platform. For mingw gmk_* functions are
dllexported, but the resulting libgnumake-1.dll.a import library does
not get installed, so the symbols are unavailable unless you extract
those from the compiled binary. In other words, while possibly doable,
will get ugly right from the very first step.
So, the dynamic object loading is currently compiled-in and working for
all upstream msys/mingw packages, it's just that currently there's no
easy access to the exported functions. Right now it is possible to
dlopen a library, it's just that it's really difficult to use any gmk_*
functions, as there's no way to tell linker where to find those.
My proposal is to split WINDOWSENV to WINDOWSENV and WINDOWSIMPORTLIB.
The first is the full Win32 treatment, as currently done. The latter is,
like the name suggest, Win32-compatible import library creation. Mingw32
systems get both WINDOWSENV (so it uses Win32 API) and WINDOWSIMPORTLIB,
while msys only sees WINDOWSIMPORTLIB (and uses POSIX API). As msys
compiler will not set _WIN32 etc. defines, a new macro value is needed
so that user may request dllimport when including gnumake.h. Also, there
were no extern "C" guards so I went ahead and added those, too.
It's been a while since I've used Autotools, so really couldn't figure
if there's any way of telling Automake not to try to build the _DATA
files, which are to be copied. So, I created a dummy rule to catch
.dll.a and a side effect it may be used to include dependencies that
libgnumake-1.dll.a has. It could be that _DATAs shouldn't appear as
dependencies, but the .dll.a suffix causes something funny, don't know.
Anyway, as you'll see below, the required changes are quite minimal.
-- Pekka
---
diff --git a/Makefile.am b/Makefile.am
index d1bd50e..09f3f4f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -71,6 +71,19 @@ if WINDOWSENV
AM_CPPFLAGS += $(W32INC)
endif
+# Only process if MS-Windows import library is requested
+if WINDOWSIMPORTLIB
+ LIBGNUMAKE_VERSION = 1
+ libgnumakedlladir = $(libdir)
+ libgnumakedlla_DATA = libgnumake-$(LIBGNUMAKE_VERSION).dll.a
+ AM_CPPFLAGS += -DGMK_WIN32_IMPORTLIB
+ AM_LDFLAGS +=
-Wl,--out-implib=libgnumake-$(LIBGNUMAKE_VERSION).dll.a
+
+# No way to tell that libgnumakedlla_DATA is a by-product, so the rule
is needed anyway.
+libgnumake-$(LIBGNUMAKE_VERSION).dll.a: loadapi.c gnumake.h
+ @
+endif
+
# Extra stuff to include in the distribution.
---
diff --git a/configure.ac b/configure.ac
index 1b03135..c1456fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -432,7 +432,9 @@ AC_SUBST([MAKE_HOST])
w32_target_env=no
AM_CONDITIONAL([WINDOWSENV], [false])
+AM_CONDITIONAL([WINDOWSIMPORTLIB], [false])
+# These are complete MS-Windows w/API environments, ...
AS_CASE([$host],
[*-*-mingw32],
[AM_CONDITIONAL([WINDOWSENV], [true])
@@ -440,6 +442,11 @@ AS_CASE([$host],
AC_DEFINE([WINDOWS32], [1], [Use platform specific coding])
AC_DEFINE([HAVE_DOS_PATHS], [1], [Use platform specific coding])
])
+# ...while these are not, but run natively under MS-Windows, hence may
use .DLLs.
+AS_CASE([$host],
+ [*-*-mingw32|*-*-msys],
+ [AM_CONDITIONAL([WINDOWSIMPORTLIB], [true])
+ ])
AC_DEFINE_UNQUOTED([PATH_SEPARATOR_CHAR],['$PATH_SEPARATOR'],
[Define to the character that separates directories in PATH.])
---
diff --git a/makeint.h b/makeint.h
index c79d0b4..eae2c80 100644
--- a/makeint.h
+++ b/makeint.h
@@ -50,8 +50,8 @@ char *alloca ();
/* Include the externally-visible content.
Be sure to use the local one, and not one installed on the system.
Define GMK_BUILDING_MAKE for proper selection of dllexport/dllimport
- declarations for MS-Windows. */
-#ifdef WINDOWS32
+ declarations for MS-Windows or systems running atop MS-Windows. */
+#if defined(WINDOWS32) || defined(GMK_WIN32_IMPORTLIB)
# define GMK_BUILDING_MAKE
#endif
#include "gnumake.h"
---
diff --git a/gnumake.h b/gnumake.h
index c1a44ec..cf55071 100644
--- a/gnumake.h
+++ b/gnumake.h
@@ -19,6 +19,10 @@ this program. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _GNUMAKE_H_
#define _GNUMAKE_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Specify the location of elements read from makefiles. */
typedef struct
{
@@ -28,7 +32,7 @@ typedef struct
typedef char *(*gmk_func_ptr)(const char *nm, unsigned int argc, char
**argv);
-#ifdef _WIN32
+#if defined(_WIN32) || defined(GMK_WIN32_IMPORTLIB)
# ifdef GMK_BUILDING_MAKE
# define GMK_EXPORT __declspec(dllexport)
# else
@@ -76,4 +80,8 @@ GMK_EXPORT void gmk_add_function (const char *name,
gmk_func_ptr func,
#define GMK_FUNC_DEFAULT 0x00
#define GMK_FUNC_NOEXPAND 0x01
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _GNUMAKE_H_ */
- [PATCH] dynamic object-file support for *-*-mingw32 and *-*-msys,
Pekka Seppänen <=