[PATCH] Rewrite wineserver main.c in Haskell.

Jefferson Carpenter jeffersoncarpenter2 at gmail.com
Wed Mar 31 19:01:26 CDT 2021


Some or all additions to Makefile.in may be removed pending more 
makedep.c extensions.

Currently builds PC / ghc architecture.  To enable WoW64 builds, we 
intend to use stack to create both 32- and 64-bit ghc and package 
sandboxes as needed.
-------------- next part --------------
From dedc2614b863e8e540e79fa9dd1c224ce1cacd15 Mon Sep 17 00:00:00 2001
From: Jefferson Carpenter <jeffersoncarpenter2 at gmail.com>
Date: Wed, 16 Mar 2242 12:56:21 +10480234
Subject: [PATCH] Rewrite wineserver main.c in Haskell.

---
 Makefile.in          |   9 +++
 configure            |  34 ++++++++--
 configure.ac         |  10 +++
 server/Main.hs       | 102 +++++++++++++++++++++++++++++
 server/Makefile.in   |   4 +-
 server/main.c        | 151 -------------------------------------------
 server/object.c      |   4 ++
 tools/make_makefiles |   6 ++
 tools/makedep.c      |  81 +++++++++++++++++++++--
 9 files changed, 239 insertions(+), 162 deletions(-)
 create mode 100644 server/Main.hs
 delete mode 100644 server/main.c

diff --git a/Makefile.in b/Makefile.in
index b52495f741f..5c219a26b81 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -46,6 +46,7 @@ MSVCRTFLAGS     = @MSVCRTFLAGS@
 TARGETFLAGS     = @TARGETFLAGS@
 LDDLLFLAGS      = @LDDLLFLAGS@
 LDEXECFLAGS     = @LDEXECFLAGS@
+GHC             = ghc
 LIBS            = @LIBS@
 BISON           = @BISON@
 FLEX            = @FLEX@
@@ -101,6 +102,14 @@ include/config.h: include/stamp-h
 include/stamp-h: $(srcdir)/include/config.h.in config.status
 	@./config.status include/config.h include/stamp-h
 
+include/Config.hs: include/config.h
+	@awk 'BEGIN { print "module Config where\n" }; $$0~/^#define/ && NF > 2 { printf "%s = ", tolower($$2); $$1=$$2=""; sub(/^[ \t]+/, ""); print $$0 }' include/config.h >include/Config.hs
+
+include/Config.hi: include/Config.hs
+	@$(GHC) include/Config.hs
+
+server/Main.o: include/Config.hi
+
 # Rules for cleaning
 
 distclean:: clean
diff --git a/configure b/configure
index a19bb0b9581..3560ccfbe61 100755
--- a/configure
+++ b/configure
@@ -5850,6 +5850,30 @@ $as_echo "$wine_cv_builtin_ms_va_list" >&6; }
     ;;
 esac
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ghc is installed" >&5
+$as_echo_n "checking whether ghc is installed... " >&6; }
+if ${wine_cv_have_ghc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  wine_cv_have_ghc=no
+    ghc --help && wine_cv_have_ghc=yes
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $wine_cv_have_ghc" >&5
+$as_echo "$wine_cv_have_ghc" >&6; }
+test $wine_cv_have_ghc != no || as_fn_error $? "Install ghc." "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stack is installed" >&5
+$as_echo_n "checking whether stack is installed... " >&6; }
+if ${wine_cv_have_stack+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  wine_cv_have_stack=no
+    stack && wine_cv_have_stack=yes
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $wine_cv_have_stack" >&5
+$as_echo "$wine_cv_have_stack" >&6; }
+test $wine_cv_have_stack != no || as_fn_error $? "Install stack." "$LINENO" 5
+
 enable_win16=${enable_win16:-no}
 enable_win64=${enable_win64:-no}
 enable_wow64cpu=${enable_wow64cpu:-no}
@@ -6980,7 +7004,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -7026,7 +7050,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -7050,7 +7074,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -7095,7 +7119,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -7119,7 +7143,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
diff --git a/configure.ac b/configure.ac
index eb08e8b0f17..68f125d4d3a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -222,6 +222,16 @@ case $host in
     ;;
 esac
 
+AC_CACHE_CHECK([whether ghc is installed], [wine_cv_have_ghc],
+    [wine_cv_have_ghc=no
+    ghc --help && wine_cv_have_ghc=yes])
+test $wine_cv_have_ghc != no || AC_MSG_ERROR([Install ghc.])
+
+AC_CACHE_CHECK([whether stack is installed], [wine_cv_have_stack],
+    [wine_cv_have_stack=no
+    stack && wine_cv_have_stack=yes])
+test $wine_cv_have_stack != no || AC_MSG_ERROR([Install stack.])
+
 dnl enable_win16 defaults to yes on x86, to no on other CPUs
 enable_win16=${enable_win16:-no}
 enable_win64=${enable_win64:-no}
diff --git a/server/Main.hs b/server/Main.hs
new file mode 100644
index 00000000000..b9f16171380
--- /dev/null
+++ b/server/Main.hs
@@ -0,0 +1,102 @@
+import Config
+
+import Data.Foldable (forM_, mapM_)
+import Data.Int
+import Data.Maybe (fromMaybe)
+import Foreign.C.Types
+import Foreign.Ptr (Ptr)
+import Foreign.Storable (peek, poke)
+import System.Console.GetOpt
+import System.Environment (getArgs, getProgName)
+import System.Exit
+import System.IO (BufferMode(..), hSetBuffering, stderr)
+import System.Posix.Signals
+import Text.Read (readMaybe)
+
+foreign import ccall "&debug_level" debug_level :: Ptr CInt
+foreign import ccall "&foreground"  foreground  :: Ptr CInt
+foreign import ccall "&master_socket_timeout" master_socket_timeout  :: Ptr Int64
+
+foreign import ccall "kill_lock_owner" kill_lock_owner :: CInt -> IO ()
+
+foreign import ccall "sock_init" sock_init :: IO ()
+foreign import ccall "open_master_socket" open_master_socket :: IO ()
+
+foreign import ccall "set_current_time" set_current_time :: IO ()
+foreign import ccall "init_signals" init_signals :: IO ()
+foreign import ccall "load_intl_file" load_intl_file :: IO (Ptr ())
+foreign import ccall "init_directories" init_directories :: Ptr () -> IO ()
+foreign import ccall "main_loop" main_loop :: IO ()
+
+data Option
+  = Debug (Maybe Int)
+  | Foreground
+  | Help
+  | Kill (Maybe Int)
+  | Persistent (Maybe Int)
+  | Version
+  | Wait
+
+parse_int_option :: (Maybe Int -> Option) -> Maybe String -> Option
+parse_int_option = (. (readMaybe =<<))
+
+options :: [OptDescr Option]
+options =
+  [ Option ['d'] ["debug"]      (OptArg (parse_int_option Debug) "n")      "set debug level to n or +1 if n not specified"
+  , Option ['f'] ["foreground"] (NoArg Foreground)                         "remain in the foreground for debugging"
+  , Option ['h'] ["help"]       (NoArg Help)                               "display this help message"
+  , Option ['k'] ["kill"]       (OptArg (parse_int_option Kill) "n")       "kill the current wineserver, optionally with signal n"
+  , Option ['p'] ["persistent"] (OptArg (parse_int_option Persistent) "n") "make server persistent, optionally for n seconds"
+  , Option ['v'] ["version"]    (NoArg Version)                            "display version information and exit"
+  , Option ['w'] ["wait"]       (NoArg Wait)                               "wait until the current wineserver terminates"
+  ]
+
+usage :: IO String
+usage = do
+  prog_name <- getProgName
+  return $ usageInfo ("Usage: " ++ prog_name ++ " [options]\n\nOptions:") options
+
+handle_option :: Option -> IO ()
+handle_option opt = do
+  case opt of
+    Debug Nothing -> do
+      d <- peek debug_level
+      poke debug_level (d + 1)
+    Debug (Just n) -> poke debug_level (fromIntegral n)
+    Foreground -> poke foreground 1
+    Help -> do
+      usage_string <- usage
+      putStrLn usage_string
+      exitSuccess
+    Kill n -> kill_lock_owner . fromIntegral . fromMaybe (-1) $ n
+    Persistent n -> let
+      timeout = case n of
+        Nothing -> maxBound
+        Just n -> fromIntegral n
+      in
+        poke master_socket_timeout timeout
+
+main :: IO ()
+main = do
+  hSetBuffering stderr LineBuffering
+
+  (options, _, _) <- fmap (getOpt Permute options) getArgs
+  mapM_ handle_option options
+
+  installHandler sigPIPE Ignore Nothing
+  mapM_ (\sig -> installHandler sig (Catch exitFailure) Nothing)
+    [ sigHUP
+    , sigINT
+    , sigQUIT
+    , sigTERM
+    , sigABRT
+    ]
+
+  sock_init
+  open_master_socket
+
+  set_current_time
+  init_signals
+  file <- load_intl_file
+  init_directories file
+  main_loop
diff --git a/server/Makefile.in b/server/Makefile.in
index 4264e3db108..f4181f3eb29 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -18,7 +18,6 @@ C_SRCS = \
 	hook.c \
 	mach.c \
 	mailslot.c \
-	main.c \
 	mapping.c \
 	mutex.c \
 	named_pipe.c \
@@ -52,3 +51,6 @@ MANPAGES = \
 EXTRALIBS = $(LDEXECFLAGS) $(POLL_LIBS) $(RT_LIBS) $(INOTIFY_LIBS)
 
 unicode_EXTRADEFS = -DNLSDIR="\"${nlsdir}\"" -DBIN_TO_NLSDIR=\"`$(MAKEDEP) -R ${bindir} ${nlsdir}`\"
+
+HS_SRCS = \
+	Main.hs
diff --git a/server/main.c b/server/main.c
deleted file mode 100644
index d7aed0da199..00000000000
--- a/server/main.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Server main function
- *
- * Copyright (C) 1998 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <unistd.h>
-#ifdef HAVE_GETOPT_H
-# include <getopt.h>
-#endif
-
-#include "object.h"
-#include "file.h"
-#include "thread.h"
-#include "request.h"
-#include "unicode.h"
-
-/* command-line options */
-int debug_level = 0;
-int foreground = 0;
-timeout_t master_socket_timeout = 3 * -TICKS_PER_SEC;  /* master socket timeout, default is 3 seconds */
-const char *server_argv0;
-
-/* parse-line args */
-
-static void usage( FILE *fh )
-{
-    fprintf(fh, "Usage: %s [options]\n\n", server_argv0);
-    fprintf(fh, "Options:\n");
-    fprintf(fh, "   -d[n], --debug[=n]       set debug level to n or +1 if n not specified\n");
-    fprintf(fh, "   -f,    --foreground      remain in the foreground for debugging\n");
-    fprintf(fh, "   -h,    --help            display this help message\n");
-    fprintf(fh, "   -k[n], --kill[=n]        kill the current wineserver, optionally with signal n\n");
-    fprintf(fh, "   -p[n], --persistent[=n]  make server persistent, optionally for n seconds\n");
-    fprintf(fh, "   -v,    --version         display version information and exit\n");
-    fprintf(fh, "   -w,    --wait            wait until the current wineserver terminates\n");
-    fprintf(fh, "\n");
-}
-
-static void parse_args( int argc, char *argv[] )
-{
-    int ret, optc;
-
-    static struct option long_options[] =
-    {
-        {"debug",       2, NULL, 'd'},
-        {"foreground",  0, NULL, 'f'},
-        {"help",        0, NULL, 'h'},
-        {"kill",        2, NULL, 'k'},
-        {"persistent",  2, NULL, 'p'},
-        {"version",     0, NULL, 'v'},
-        {"wait",        0, NULL, 'w'},
-        { NULL,         0, NULL, 0}
-    };
-
-    server_argv0 = argv[0];
-
-    while ((optc = getopt_long( argc, argv, "d::fhk::p::vw", long_options, NULL )) != -1)
-    {
-        switch(optc)
-        {
-            case 'd':
-                if (optarg && isdigit(*optarg))
-                    debug_level = atoi( optarg );
-                else
-                    debug_level++;
-                break;
-            case 'f':
-                foreground = 1;
-                break;
-            case 'h':
-                usage(stdout);
-                exit(0);
-                break;
-            case 'k':
-                if (optarg && isdigit(*optarg))
-                    ret = kill_lock_owner( atoi( optarg ) );
-                else
-                    ret = kill_lock_owner(-1);
-                exit( !ret );
-            case 'p':
-                if (optarg && isdigit(*optarg))
-                    master_socket_timeout = (timeout_t)atoi( optarg ) * -TICKS_PER_SEC;
-                else
-                    master_socket_timeout = TIMEOUT_INFINITE;
-                break;
-            case 'v':
-                fprintf( stderr, "%s\n", PACKAGE_STRING );
-                exit(0);
-            case 'w':
-                wait_for_lock();
-                exit(0);
-            default:
-                usage(stderr);
-                exit(1);
-        }
-    }
-}
-
-static void sigterm_handler( int signum )
-{
-    exit(1);  /* make sure atexit functions get called */
-}
-
-int main( int argc, char *argv[] )
-{
-    setvbuf( stderr, NULL, _IOLBF, 0 );
-    parse_args( argc, argv );
-
-    /* setup temporary handlers before the real signal initialization is done */
-    signal( SIGPIPE, SIG_IGN );
-    signal( SIGHUP, sigterm_handler );
-    signal( SIGINT, sigterm_handler );
-    signal( SIGQUIT, sigterm_handler );
-    signal( SIGTERM, sigterm_handler );
-    signal( SIGABRT, sigterm_handler );
-
-    sock_init();
-    open_master_socket();
-
-    if (debug_level) fprintf( stderr, "wineserver: starting (pid=%ld)\n", (long) getpid() );
-    set_current_time();
-    init_signals();
-    init_directories( load_intl_file() );
-    init_registry();
-    main_loop();
-    return 0;
-}
diff --git a/server/object.c b/server/object.c
index b2779fd61fe..d020b44463c 100644
--- a/server/object.c
+++ b/server/object.c
@@ -42,6 +42,10 @@
 #include "unicode.h"
 #include "security.h"
 
+int debug_level = 0;
+int foreground = 0;
+timeout_t master_socket_timeout = 3 * -TICKS_PER_SEC;  /* master socket timeout, default is 3 seconds */
+const char *server_argv0;
 
 struct namespace
 {
diff --git a/tools/make_makefiles b/tools/make_makefiles
index 3abba2da840..34b4e58ce56 100755
--- a/tools/make_makefiles
+++ b/tools/make_makefiles
@@ -59,6 +59,7 @@ my @source_vars = (
     "C_SRCS",
     "FONT_SRCS",
     "HEADER_SRCS",
+    "HS_SRCS",
     "IDL_SRCS",
     "IN_SRCS",
     "LEX_SRCS",
@@ -360,6 +361,10 @@ sub assign_sources_to_makefiles(@)
         {
             next if $dir ne "include";
         }
+        elsif ($name =~ /\.hs$/)
+        {
+            push @{${$make}{"=HS_SRCS"}}, $name;
+        }
         elsif ($name =~ /\.rc$/)
         {
             push @{${$make}{"=RC_SRCS"}}, $name;
@@ -407,6 +412,7 @@ sub assign_sources_to_makefiles(@)
         my $parent = get_parent_makefile( $file );
         next unless $parent;
         preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "C_SRCS" );
+        preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "HS_SRCS" );
         preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "RC_SRCS" );
         preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "IDL_SRCS" );
         preserve_shared_source_files( $makefiles{$file}, $makefiles{$parent}, "LEX_SRCS" );
diff --git a/tools/makedep.c b/tools/makedep.c
index 8245a324279..94d68d3e181 100644
--- a/tools/makedep.c
+++ b/tools/makedep.c
@@ -109,6 +109,7 @@ struct incl_file
 #define FLAG_C_IMPLIB       0x020000  /* file is part of an import library */
 #define FLAG_C_UNIX         0x040000  /* file is part of a Unix library */
 #define FLAG_SFD_FONTS      0x080000  /* sfd file generated bitmap fonts */
+#define FLAG_HS             0x100000  /* is haskell source file */
 
 static const struct
 {
@@ -206,6 +207,7 @@ struct makefile
     int             is_cross;
     int             is_win16;
     int             is_exe;
+    int             is_hs;
 
     /* values generated at output time */
     struct strarray in_files;
@@ -1016,6 +1018,18 @@ static void parse_include_directive( struct file *source, char *str )
 }
 
 
+/*******************************************************************
+ *         parse_import_directive
+ */
+static void parse_import_directive( struct file *source, char *str )
+{
+    while (*str && isspace(*str)) str++;
+    if (!strncmp("Config", str, 6)) {
+        add_dependency( source, "include/Config.hi", INCL_NORMAL );
+    }
+}
+
+
 /*******************************************************************
  *         parse_pragma_directive
  */
@@ -1095,6 +1109,18 @@ static void parse_cpp_directive( struct file *source, char *str )
 }
 
 
+/*******************************************************************
+ *         parse_hs_directive
+ */
+static void parse_hs_directive( struct file *source, char *str )
+{
+    while (*str && isspace(*str)) str++;
+
+    if (!strncmp( str, "import", 6 ))
+        parse_import_directive( source, str + 6 );
+}
+
+
 /*******************************************************************
  *         parse_idl_file
  */
@@ -1190,6 +1216,23 @@ static void parse_c_file( struct file *source, FILE *file )
 }
 
 
+/*******************************************************************
+ *         parse_hs_file
+ */
+static void parse_hs_file( struct file *source, FILE *file )
+{
+    char *buffer;
+
+    input_line = 0;
+    while ((buffer = get_line( file )))
+    {
+        parse_hs_directive( source, buffer );
+    }
+
+    source->flags |= FLAG_HS;
+}
+
+
 /*******************************************************************
  *         parse_rc_file
  */
@@ -1311,6 +1354,7 @@ static const struct
     { ".rh",  parse_c_file },
     { ".x",   parse_c_file },
     { ".y",   parse_c_file },
+    { ".hs",  parse_hs_file },
     { ".idl", parse_idl_file },
     { ".rc",  parse_rc_file },
     { ".in",  parse_in_file },
@@ -1484,6 +1528,13 @@ static struct file *open_include_file( const struct makefile *make, struct incl_
         return file;
     }
 
+    /* ignore Config.hi */
+
+    if (!strcmp( pFile->name, "include/Config.hi" ))
+    {
+        return NULL;
+    }
+
     /* check for extra targets */
     if (strarray_exists( &make->extra_targets, pFile->name ))
     {
@@ -1644,6 +1695,10 @@ static void parse_file( struct makefile *make, struct incl_file *source, int src
     if (file->flags & FLAG_C_UNIX) source->use_msvcrt = 0;
     else if (file->flags & FLAG_C_IMPLIB) source->use_msvcrt = 1;
 
+    if (file->flags & FLAG_HS) {
+        make->is_hs = 1;
+    }
+
     if (source->sourcename)
     {
         if (strendswith( source->sourcename, ".idl" ))
@@ -3146,16 +3201,26 @@ static void output_source_default( struct makefile *make, struct incl_file *sour
         else
             strarray_add( &make->clean_files, strmake( "%s.o", obj ));
         output( "%s.o: %s\n", obj_dir_path( make, obj ), source->filename );
-        output( "\t%s$(CC) -c -o $@ %s", cmd_prefix( "CC" ), source->filename );
+        if (source->file->flags & FLAG_HS) {
+            output( "\t%s$(GHC) -c -o $@ %s", cmd_prefix( "GHC" ), source->filename );
+        }
+        else {
+            output( "\t%s$(CC) -c -o $@ %s", cmd_prefix( "CC" ), source->filename );
+        }
         output_filenames( defines );
         if (make->module || make->staticlib || make->sharedlib || make->testdll)
         {
             output_filenames( dll_flags );
             if (source->use_msvcrt) output_filenames( msvcrt_flags );
         }
-        output_filenames( extra_cflags );
-        output_filenames( cpp_flags );
-        output_filename( "$(CFLAGS)" );
+        if (source->file->flags & FLAG_HS) {
+            output_filename( "-fPIC -i./include $(GHCFLAGS)" );
+        }
+        else {
+            output_filenames( extra_cflags );
+            output_filenames( cpp_flags );
+            output_filename( "$(CFLAGS)" );
+        }
         output( "\n" );
     }
     if (need_cross)
@@ -3659,7 +3724,12 @@ static void output_programs( struct makefile *make )
         output_filenames_obj_dir( make, objs );
         output_filenames( deps );
         output( "\n" );
-        output( "\t%s$(CC) -o $@", cmd_prefix( "CC" ));
+        if (make->is_hs) {
+            output( "\t%s$(GHC) -package unix -o $@", cmd_prefix( "GHC" ));
+        }
+        else {
+            output( "\t%s$(CC) -o $@", cmd_prefix( "CC" ));
+        }
         output_filenames_obj_dir( make, objs );
         output_filenames( all_libs );
         output_filename( "$(LDFLAGS)" );
@@ -4196,6 +4266,7 @@ static void load_sources( struct makefile *make )
     {
         "SOURCES",
         "C_SRCS",
+        "HS_SRCS",
         "OBJC_SRCS",
         "RC_SRCS",
         "MC_SRCS",
-- 
2.26.2



More information about the wine-devel mailing list