bug-make
[Top][All Lists]
Advanced

[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_ */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]