public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Nicolas Bértolo" <nicolasbertolo@gmail.com>
To: David Malcolm <dmalcolm@redhat.com>
Cc: jit@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] Port libgccjit to Windows.
Date: Mon, 25 May 2020 16:48:26 -0300	[thread overview]
Message-ID: <CAFnS-O=uLi0UrxmFC=xvVgZ_SWP8naH3fhuDpR5Qmo9oR93Axw@mail.gmail.com> (raw)
In-Reply-To: <4b619179a08075bd2ee7f9e98aa2d5918191306d.camel@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1922 bytes --]

Hi Dave,

Thanks for your feedback.

> Do you have copyright assignment paperwork on file?
> https://gcc.gnu.org/contribute.html#legal

My paperwork is done.

> The autotools are not my strongest suit.

> In a previous life I was a Windows developer, but I think it's been
> about 18 years since I've done any coding on Windows, so I'm going to
> have to trust your Windows expertise.

I guess the best solution would be to use libtool and Automake, but
that require major changes in the GCC build system. I came up with a
solution that uses an if statement to choose the way to build the
dynamic library.

> > It is not necessary to use --enable-host-shared in Windows (I tested
> it),
> > but I
> > don't know the proper way to disable that check.

I used case statement to check the value of $(target).

> What's the issue with fchmod on Windows?  Does it not exist, or does it
> not work?
> Please add a comment explaining why.

fchmod does not exist in Windows.

> Please can you fix the indentation here to stay within 80 columns.
> It looks like there's very similar (identical?) code to this below in
> several places.
> Can it be put in a subroutine to avoid repetition?

I created a new file "jit-w32.{h,c}" to store the definitions of
win_mkdtemp() and print_last_error().

> Is there a cast to HMODULE everywhere that m_dso_handle is used?
> If so, does it make the code cleaner if the field becomes an HMODULE on
> Windows?

I added a new type "result::handle_t" that abstracts over this
difference.

> This seems like a very awkward way to get a temporary directory, but
> perhaps it's the best that can be done on Windows?

We could copy an implementation of mkdtemp () for Windows or write
something using a random number generator. I did it this way because
it was the fastest.

> Sorry if this seems excessively like nitpicking - thanks again for the
> patch.

No problem.

Here is a new version.

Nico.

[-- Attachment #2: 0001-Port-libgccjit-to-Windows.patch --]
[-- Type: application/octet-stream, Size: 20919 bytes --]

From a620c16adfadcebabd996a0b1d3761a582143ed7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20B=C3=A9rtolo?= <nicolasbertolo@gmail.com>
Date: Fri, 22 May 2020 17:54:41 -0300
Subject: [PATCH] Port libgccjit to Windows.

* configure: Regenerate.
* configure.ac: Don't require --enable-host-shared when building for Mingw.
* gcc/Makefile.in: don't look for libiberty in the "pic" subdirectory when
building for Mingw. Add dependency on xgcc with the proper extension.
* gcc/c/Make-lang.in: Remove extra slash.
* gcc/jit/Make-lang.in: Remove extra slash. Build libgccjit.dll and its import
library in Windows.
* gcc/jit/jit-w32.h: New file.
* gcc/jit/jit-w32.c (print_last_error): New function that prints the error
string corresponding to GetLastError().
(win_mkdtemp): Create a temporary directory using Windows APIs.
* gcc/jit/jit-playback.c: Do not chmod files in Windows. Use LoadLibrary,
FreeLibrary and GetProcAddress instead of libdl.
* gcc/jit/jit-result.{h,c}: Introduce result::handle_t to abstract over the
types used for dynamic library handles.
* gcc/jit/jit-tempdir.c: Do not use mkdtemp() in Windows, use win_mkdtemp().
---
 configure              |  32 +++++++------
 configure.ac           |  32 +++++++------
 gcc/Makefile.in        |  10 ++--
 gcc/c/Make-lang.in     |   2 +-
 gcc/jit/Make-lang.in   |  55 ++++++++++++++++++----
 gcc/jit/jit-playback.c |  24 ++++++++--
 gcc/jit/jit-result.c   |  39 +++++++++++++---
 gcc/jit/jit-result.h   |  14 +++++-
 gcc/jit/jit-tempdir.c  |  10 ++++
 gcc/jit/jit-w32.c      | 102 +++++++++++++++++++++++++++++++++++++++++
 gcc/jit/jit-w32.h      |  30 ++++++++++++
 11 files changed, 300 insertions(+), 50 deletions(-)
 create mode 100644 gcc/jit/jit-w32.c
 create mode 100644 gcc/jit/jit-w32.h

diff --git a/configure b/configure
index 3af6a530b..b7897446c 100755
--- a/configure
+++ b/configure
@@ -6489,9 +6489,13 @@ $as_echo "$as_me: WARNING: GNAT is required to build $language" >&2;}
         esac
 
         # Disable jit if -enable-host-shared not specified
-        case ${add_this_lang}:${language}:${host_shared} in
-          yes:jit:no)
-	    # PR jit/64780: explicitly specify --enable-host-shared
+        # but not if building for Mingw
+        case $target in
+          *mingw*) ;;
+          *)
+          case ${add_this_lang}:${language}:${host_shared} in
+            yes:jit:no)
+	           # PR jit/64780: explicitly specify --enable-host-shared
 	    as_fn_error $? "
 Enabling language \"jit\" requires --enable-host-shared.
 
@@ -6502,17 +6506,19 @@ If you want to build both the jit and the regular compiler, it is often
 best to do this via two separate configure/builds, in separate
 directories, to avoid imposing the performance cost of
 --enable-host-shared on the regular compiler." "$LINENO" 5
-	    ;;
-          all:jit:no)
-	    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-host-shared required to build $language" >&5
+	            ;;
+            all:jit:no)
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-host-shared required to build $language" >&5
 $as_echo "$as_me: WARNING: --enable-host-shared required to build $language" >&2;}
-            add_this_lang=unsupported
-            ;;
-          *:jit:no)
-            # Silently disable.
-            add_this_lang=unsupported
-            ;;
-	esac
+              add_this_lang=unsupported
+              ;;
+            *:jit:no)
+              # Silently disable.
+              add_this_lang=unsupported
+              ;;
+	        esac
+          ;;
+        esac
 
         # Disable a language that is unsupported by the target.
 	case "${add_this_lang}: $unsupported_languages " in
diff --git a/configure.ac b/configure.ac
index a67801371..edd963d3d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2079,9 +2079,13 @@ if test -d ${srcdir}/gcc; then
         esac
 
         # Disable jit if -enable-host-shared not specified
-        case ${add_this_lang}:${language}:${host_shared} in
-          yes:jit:no)
-	    # PR jit/64780: explicitly specify --enable-host-shared
+        # but not if building for Mingw
+        case $target in
+          *mingw*) ;;
+          *)
+          case ${add_this_lang}:${language}:${host_shared} in
+            yes:jit:no)
+	           # PR jit/64780: explicitly specify --enable-host-shared
 	    AC_MSG_ERROR([
 Enabling language "jit" requires --enable-host-shared.
 
@@ -2092,16 +2096,18 @@ If you want to build both the jit and the regular compiler, it is often
 best to do this via two separate configure/builds, in separate
 directories, to avoid imposing the performance cost of
 --enable-host-shared on the regular compiler.])
-	    ;;
-          all:jit:no)
-	    AC_MSG_WARN([--enable-host-shared required to build $language])
-            add_this_lang=unsupported
-            ;;
-          *:jit:no)
-            # Silently disable.
-            add_this_lang=unsupported
-            ;;
-	esac
+	            ;;
+            all:jit:no)
+	      AC_MSG_WARN([--enable-host-shared required to build $language])
+              add_this_lang=unsupported
+              ;;
+            *:jit:no)
+              # Silently disable.
+              add_this_lang=unsupported
+              ;;
+	        esac
+          ;;
+        esac
 
         # Disable a language that is unsupported by the target.
 	case "${add_this_lang}: $unsupported_languages " in
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 0fe2ba241..45851eca8 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1046,10 +1046,12 @@ ALL_LINKERFLAGS = $(ALL_CXXFLAGS)
 
 # Build and host support libraries.
 
-# Use the "pic" build of libiberty if --enable-host-shared.
+# Use the "pic" build of libiberty if --enable-host-shared, unless we are
+# building for mingw.
+LIBIBERTY_PICDIR=$(if $(findstring mingw,$(target)),,pic)
 ifeq ($(enable_host_shared),yes)
-LIBIBERTY = ../libiberty/pic/libiberty.a
-BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/pic/libiberty.a
+LIBIBERTY = ../libiberty/$(LIBIBERTY_PICDIR)/libiberty.a
+BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/$(LIBIBERTY_PICDIR)/libiberty.a
 else
 LIBIBERTY = ../libiberty/libiberty.a
 BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/libiberty.a
@@ -1726,7 +1728,7 @@ MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \
 # This symlink makes the full installation name of the driver be available
 # from within the *build* directory, for use when running the JIT library
 # from there (e.g. when running its testsuite).
-$(FULL_DRIVER_NAME): ./xgcc
+$(FULL_DRIVER_NAME): ./xgcc$(exeext)
 	rm -f $@
 	$(LN_S) $< $@
 
diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
index 8944b9b9f..7efc7c2c3 100644
--- a/gcc/c/Make-lang.in
+++ b/gcc/c/Make-lang.in
@@ -162,7 +162,7 @@ c.install-plugin: installdirs
 # Install import library.
 ifeq ($(plugin_implib),yes)
 	$(mkinstalldirs) $(DESTDIR)$(plugin_resourcesdir)
-	$(INSTALL_DATA) cc1$(exeext).a $(DESTDIR)/$(plugin_resourcesdir)/cc1$(exeext).a
+	$(INSTALL_DATA) cc1$(exeext).a $(DESTDIR)$(plugin_resourcesdir)/cc1$(exeext).a
 endif
 
 c.uninstall:
diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in
index 38ddfad28..39d555650 100644
--- a/gcc/jit/Make-lang.in
+++ b/gcc/jit/Make-lang.in
@@ -40,10 +40,19 @@
 # into the jit rule, but that needs a little bit of work
 # to do the right thing within all.cross.
 
+ifneq (,$(findstring mingw,$(target)))
+LIBGCCJIT_FILENAME = libgccjit.dll
+
+jit: $(LIBGCCJIT_FILENAME) \
+	$(FULL_DRIVER_NAME)
+
+else
+
 LIBGCCJIT_LINKER_NAME = libgccjit.so
 LIBGCCJIT_VERSION_NUM = 0
 LIBGCCJIT_MINOR_NUM = 0
 LIBGCCJIT_RELEASE_NUM = 1
+
 LIBGCCJIT_SONAME = $(LIBGCCJIT_LINKER_NAME).$(LIBGCCJIT_VERSION_NUM)
 LIBGCCJIT_FILENAME = \
   $(LIBGCCJIT_SONAME).$(LIBGCCJIT_MINOR_NUM).$(LIBGCCJIT_RELEASE_NUM)
@@ -68,6 +77,7 @@ jit: $(LIBGCCJIT_FILENAME) \
 	$(LIBGCCJIT_SYMLINK) \
 	$(LIBGCCJIT_LINKER_NAME_SYMLINK) \
 	$(FULL_DRIVER_NAME)
+endif
 
 # Tell GNU make to ignore these if they exist.
 .PHONY: jit
@@ -84,9 +94,27 @@ jit_OBJS = attribs.o \
 	jit/jit-spec.o \
 	gcc.o
 
+ifneq (,$(findstring mingw,$(target)))
+jit_OBJS += jit/jit-w32.o
+endif
+
 # Use strict warnings for this front end.
 jit-warn = $(STRICT_WARN)
 
+ifneq (,$(findstring mingw,$(target)))
+# We avoid using $(BACKEND) from Makefile.in in order to avoid pulling
+# in main.o
+$(LIBGCCJIT_FILENAME): $(jit_OBJS) \
+	libbackend.a libcommon-target.a libcommon.a \
+	$(CPPLIB) $(LIBDECNUMBER) \
+	$(LIBDEPS) $(srcdir)/jit/libgccjit.map \
+	$(EXTRA_GCC_OBJS)
+	+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ -shared \
+	     $(jit_OBJS) libbackend.a libcommon-target.a libcommon.a \
+	     $(CPPLIB) $(LIBDECNUMBER) $(EXTRA_GCC_LIBS) $(LIBS) $(BACKENDLIBS) \
+	     $(EXTRA_GCC_OBJS) \
+	     -Wl,--out-implib,$(LIBGCCJIT_FILENAME).a
+else
 # We avoid using $(BACKEND) from Makefile.in in order to avoid pulling
 # in main.o
 $(LIBGCCJIT_FILENAME): $(jit_OBJS) \
@@ -106,6 +134,7 @@ $(LIBGCCJIT_SONAME_SYMLINK): $(LIBGCCJIT_FILENAME)
 
 $(LIBGCCJIT_LINKER_NAME_SYMLINK): $(LIBGCCJIT_SONAME_SYMLINK)
 	ln -sf $(LIBGCCJIT_SONAME_SYMLINK) $(LIBGCCJIT_LINKER_NAME_SYMLINK)
+endif
 
 #\f
 # Build hooks:
@@ -275,19 +304,29 @@ selftest-jit:
 
 #\f
 # Install hooks:
-jit.install-common: installdirs
+jit.install-headers:
+	$(INSTALL_DATA) $(srcdir)/jit/libgccjit.h \
+	  $(DESTDIR)$(includedir)/libgccjit.h
+	$(INSTALL_DATA) $(srcdir)/jit/libgccjit++.h \
+	  $(DESTDIR)$(includedir)/libgccjit++.h
+
+ifneq (,$(findstring mingw,$(target)))
+jit.install-common: installdirs jit.install-headers
+	$(INSTALL_PROGRAM) $(LIBGCCJIT_FILENAME).a \
+	  $(DESTDIR)$(libdir)/$(LIBGCCJIT_FILENAME).a
 	$(INSTALL_PROGRAM) $(LIBGCCJIT_FILENAME) \
-	  $(DESTDIR)/$(libdir)/$(LIBGCCJIT_FILENAME)
+	  $(DESTDIR)$(bindir)/$(LIBGCCJIT_FILENAME)
+else
+jit.install-common: installdirs jit.install-headers
+	$(INSTALL_PROGRAM) $(LIBGCCJIT_FILENAME) \
+	  $(DESTDIR)$(libdir)/$(LIBGCCJIT_FILENAME)
 	ln -sf \
 	  $(LIBGCCJIT_FILENAME) \
-	  $(DESTDIR)/$(libdir)/$(LIBGCCJIT_SONAME_SYMLINK)
+	  $(DESTDIR)$(libdir)/$(LIBGCCJIT_SONAME_SYMLINK)
 	ln -sf \
 	  $(LIBGCCJIT_SONAME_SYMLINK)\
-	  $(DESTDIR)/$(libdir)/$(LIBGCCJIT_LINKER_NAME_SYMLINK)
-	$(INSTALL_DATA) $(srcdir)/jit/libgccjit.h \
-	  $(DESTDIR)/$(includedir)/libgccjit.h
-	$(INSTALL_DATA) $(srcdir)/jit/libgccjit++.h \
-	  $(DESTDIR)/$(includedir)/libgccjit++.h
+	  $(DESTDIR)$(libdir)/$(LIBGCCJIT_LINKER_NAME_SYMLINK)
+endif
 
 jit.install-man:
 
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index d2c8bb4c1..d1694e089 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -47,6 +47,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "jit-builtins.h"
 #include "jit-tempdir.h"
 
+#ifdef _WIN32
+#include "jit-w32.h"
+#endif
+
 /* Compare with gcc/c-family/c-common.h: DECL_C_BIT_FIELD,
    SET_DECL_C_BIT_FIELD.
    These are redefined here to avoid depending from the C frontend.  */
@@ -2159,8 +2163,10 @@ playback::compile_to_file::copy_file (const char *src_path,
 
   gcc_assert (total_sz_in == total_sz_out);
   if (get_logger ())
-    get_logger ()->log ("total bytes copied: %ld", total_sz_out);
+    get_logger ()->log ("total bytes copied: %zu", total_sz_out);
 
+	/* fchmod does not exist in Windows. */
+	#ifndef _WIN32
   /* Set the permissions of the copy to those of the original file,
      in particular the "executable" bits.  */
   if (fchmod (fileno (f_out), stat_buf.st_mode) == -1)
@@ -2168,6 +2174,7 @@ playback::compile_to_file::copy_file (const char *src_path,
 	       "error setting mode of %s: %s",
 	       dst_path,
 	       xstrerror (errno));
+	#endif
 
   fclose (f_out);
 }
@@ -2644,10 +2651,19 @@ dlopen_built_dso ()
 {
   JIT_LOG_SCOPE (get_logger ());
   auto_timevar load_timevar (get_timer (), TV_LOAD);
-  void *handle = NULL;
-  const char *error = NULL;
+	result::handle_t handle = NULL;
   result *result_obj = NULL;
 
+#ifdef _WIN32
+  /* Clear any existing error.  */
+  SetLastError(0);
+
+  handle = LoadLibrary(m_tempdir->get_path_so_file ());
+  if (GetLastError() != 0)  {
+		print_last_error();
+  }
+#else
+  const char *error = NULL;
   /* Clear any existing error.  */
   dlerror ();
 
@@ -2656,6 +2672,8 @@ dlopen_built_dso ()
   if ((error = dlerror()) != NULL)  {
     add_error (NULL, "%s", error);
   }
+#endif
+
   if (handle)
     {
       /* We've successfully dlopened the result; create a
diff --git a/gcc/jit/jit-result.c b/gcc/jit/jit-result.c
index c10e5a13c..605ae64ee 100644
--- a/gcc/jit/jit-result.c
+++ b/gcc/jit/jit-result.c
@@ -27,13 +27,17 @@ along with GCC; see the file COPYING3.  If not see
 #include "jit-result.h"
 #include "jit-tempdir.h"
 
+#ifdef _WIN32
+#include "jit-w32.h"
+#endif
+
 namespace gcc {
 namespace jit {
 
 /* Constructor for gcc::jit::result.  */
 
 result::
-result(logger *logger, void *dso_handle, tempdir *tempdir_) :
+result(logger *logger, handle_t dso_handle, tempdir *tempdir_) :
   log_user (logger),
   m_dso_handle (dso_handle),
   m_tempdir (tempdir_)
@@ -49,8 +53,11 @@ result::~result()
 {
   JIT_LOG_SCOPE (get_logger ());
 
+#ifdef _WIN32
+  FreeLibrary(m_dso_handle);
+#else
   dlclose (m_dso_handle);
-
+#endif
   /* Responsibility for cleaning up the tempdir (including "fake.so" within
      the filesystem) might have been handed to us by the playback::context,
      so that the cleanup can be delayed (see PR jit/64206).
@@ -72,8 +79,17 @@ get_code (const char *funcname)
   JIT_LOG_SCOPE (get_logger ());
 
   void *code;
-  const char *error;
 
+#ifdef _WIN32
+  /* Clear any existing error.  */
+  SetLastError(0);
+
+  code = (void *)GetProcAddress(m_dso_handle, funcname);
+  if (GetLastError() != 0)  {
+		print_last_error ();
+  }
+#else
+  const char *error;
   /* Clear any existing error.  */
   dlerror ();
 
@@ -81,7 +97,8 @@ get_code (const char *funcname)
 
   if ((error = dlerror()) != NULL)  {
     fprintf(stderr, "%s\n", error);
-  }
+	}
+#endif
 
   return code;
 }
@@ -99,8 +116,17 @@ get_global (const char *name)
   JIT_LOG_SCOPE (get_logger ());
 
   void *global;
-  const char *error;
 
+#ifdef _WIN32
+  /* Clear any existing error.  */
+  SetLastError(0);
+
+  global = (void *)GetProcAddress(m_dso_handle, name);
+  if (GetLastError() != 0)  {
+		print_last_error ();
+  }
+#else
+  const char *error;
   /* Clear any existing error.  */
   dlerror ();
 
@@ -108,7 +134,8 @@ get_global (const char *name)
 
   if ((error = dlerror()) != NULL)  {
     fprintf(stderr, "%s\n", error);
-  }
+	}
+#endif
 
   return global;
 }
diff --git a/gcc/jit/jit-result.h b/gcc/jit/jit-result.h
index 025860603..2ba87e58c 100644
--- a/gcc/jit/jit-result.h
+++ b/gcc/jit/jit-result.h
@@ -21,6 +21,10 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef JIT_RESULT_H
 #define JIT_RESULT_H
 
+#ifdef _WIN32
+#include <minwindef.h>
+#endif
+
 namespace gcc {
 
 namespace jit {
@@ -29,7 +33,13 @@ namespace jit {
 class result : public log_user
 {
 public:
-  result(logger *logger, void *dso_handle, tempdir *tempdir_);
+#ifdef _WIN32
+  using handle_t = HMODULE;
+#else
+  using handle_t = void *;
+#endif
+
+  result(logger *logger, handle_t dso_handle, tempdir *tempdir_);
 
   virtual ~result();
 
@@ -40,7 +50,7 @@ public:
   get_global (const char *name);
 
 private:
-  void *m_dso_handle;
+  handle_t m_dso_handle;
   tempdir *m_tempdir;
 };
 
diff --git a/gcc/jit/jit-tempdir.c b/gcc/jit/jit-tempdir.c
index 10c528faf..050d53409 100644
--- a/gcc/jit/jit-tempdir.c
+++ b/gcc/jit/jit-tempdir.c
@@ -24,7 +24,11 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "jit-tempdir.h"
 
+#ifdef _WIN32
+#include "jit-w32.h"
+#endif
 
+#ifndef _WIN32
 /* Construct a tempdir path template suitable for use by mkdtemp
    e.g. "/tmp/libgccjit-XXXXXX", but respecting the rules in
    libiberty's choose_tempdir rather than hardcoding "/tmp/".
@@ -62,6 +66,7 @@ make_tempdir_path_template ()
 
   return result;
 }
+#endif
 
 /* The constructor for the jit::tempdir object.
    The real work is done by the jit::tempdir::create method.  */
@@ -87,6 +92,9 @@ gcc::jit::tempdir::create ()
 {
   JIT_LOG_SCOPE (get_logger ());
 
+#ifdef _WIN32
+  m_path_tempdir = win_mkdtemp ();
+#else
   m_path_template = make_tempdir_path_template ();
   if (!m_path_template)
     return false;
@@ -97,6 +105,8 @@ gcc::jit::tempdir::create ()
      is unique.  Hence no other (non-root) users should have access to
      the paths within it.  */
   m_path_tempdir = mkdtemp (m_path_template);
+#endif
+
   if (!m_path_tempdir)
     return false;
   log ("m_path_tempdir: %s", m_path_tempdir);
diff --git a/gcc/jit/jit-w32.c b/gcc/jit/jit-w32.c
new file mode 100644
index 000000000..03da2d9f4
--- /dev/null
+++ b/gcc/jit/jit-w32.c
@@ -0,0 +1,102 @@
+/* Functions used by the Windows port of libgccjit.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   Contributed by Nicolas Bertolo <nicolasbertolo@gmail.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+
+#include <cstdio>
+#include <cstdint>
+
+#include "jit-w32.h"
+
+#include "libiberty.h"
+
+namespace gcc {
+namespace jit {
+void
+print_last_error (void)
+{
+	LPSTR psz{ nullptr };
+	DWORD dwErrorCode;
+	dwErrorCode = GetLastError();
+	const DWORD cchMsg = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+                                     | FORMAT_MESSAGE_IGNORE_INSERTS
+                                     | FORMAT_MESSAGE_ALLOCATE_BUFFER
+																		 | FORMAT_MESSAGE_MAX_WIDTH_MASK,
+                                     NULL,
+                                     dwErrorCode,
+                                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                                     reinterpret_cast<LPSTR>(&psz),
+                                     0,
+                                     NULL);
+  if (cchMsg > 0)
+		{
+			fprintf (stderr, "%s\n", psz);
+			LocalFree (psz);
+		}
+	else
+    {
+			fprintf (stderr, "Failed to retrieve error message string for error %lu\n",
+							 dwErrorCode);
+		}
+}
+
+char *
+win_mkdtemp (void)
+{
+	char szTempFileName[MAX_PATH];
+	char lpTempPathBuffer[MAX_PATH];
+
+	while (true)
+		{
+			/* Gets the temp path env string (no guarantee it's a valid path). */
+			DWORD dwRetVal = GetTempPath (MAX_PATH, lpTempPathBuffer);
+			if (dwRetVal > MAX_PATH || (dwRetVal == 0))
+				goto error;
+
+			/* Generates a temporary file name. */
+			if (!GetTempFileNameA (lpTempPathBuffer, "gcc", 0, szTempFileName))
+				goto error;
+
+			/* GetTempFileNameA actually creates a file, we are need a directory, so
+				 remove it. */
+			if (!DeleteFileA (szTempFileName))
+				goto error;
+
+			if (CreateDirectoryA (szTempFileName, NULL))
+				break; // success!
+
+			/* If we can't create the directory because we got unlucky and another
+				 process created a file retry, otherwise fail. */
+			if (GetLastError () != ERROR_ALREADY_EXISTS)
+				goto error;
+		}
+
+	{
+		char * result = XNEWVEC (char, MAX_PATH);
+		strcpy (result, szTempFileName);
+		return result;
+	}
+
+ error:
+	print_last_error ();
+	return NULL;
+}
+}
+}
diff --git a/gcc/jit/jit-w32.h b/gcc/jit/jit-w32.h
new file mode 100644
index 000000000..4ab50d259
--- /dev/null
+++ b/gcc/jit/jit-w32.h
@@ -0,0 +1,30 @@
+/* Functions used by the Windows port of libgccjit.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   Contributed by Nicolas Bertolo <nicolasbertolo@gmail.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+
+#include <windows.h>
+
+namespace gcc {
+namespace jit {
+extern void print_last_error (void);
+extern char * win_mkdtemp(void);
+}
+}
-- 
2.25.1.windows.1


  reply	other threads:[~2020-05-25 19:48 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-24 20:02 Nicolas Bértolo
2020-05-24 20:48 ` David Malcolm
2020-05-25 19:48   ` Nicolas Bértolo [this message]
2020-05-26 18:40     ` David Malcolm
2020-05-28  1:27       ` Nicolas Bértolo
2020-05-28 19:00         ` David Malcolm
2020-05-28 19:51           ` Nicolas Bértolo
2020-05-28 20:46             ` David Malcolm
2020-06-02 16:26               ` JonY
2020-06-07 16:03                 ` Nicolas Bértolo
2020-06-08  2:11                   ` JonY
2020-06-11 22:02                     ` Nicolas Bértolo
2020-06-12  0:19                       ` JonY
2020-06-16  0:12                         ` JonY
2020-06-16  0:15                           ` Nicolas Bértolo
2020-05-29 14:48           ` NightStrike

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAFnS-O=uLi0UrxmFC=xvVgZ_SWP8naH3fhuDpR5Qmo9oR93Axw@mail.gmail.com' \
    --to=nicolasbertolo@gmail.com \
    --cc=dmalcolm@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jit@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).