summaryrefslogtreecommitdiff
path: root/rts/RtsMain.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2011-11-15 15:43:28 +0000
committerSimon Marlow <marlowsd@gmail.com>2011-11-16 14:39:24 +0000
commit1df28a805b465a28b61f4cfe4db28f247a183206 (patch)
tree2fff045a1ac1b8468bff2fb892b7059d397d794e /rts/RtsMain.c
parent1790dbe4a5829af5bcdc5bc81eafb67b154008cc (diff)
downloadhaskell-1df28a805b465a28b61f4cfe4db28f247a183206.tar.gz
Generate the C main() function when linking a binary (fixes #5373)
Rather than have main() be statically compiled as part of the RTS, we now generate it into the tiny C file that we compile when linking a binary. The main motivation is that we want to pass the settings for the -rtsotps and -with-rtsopts flags into the RTS, rather than relying on fragile linking semantics to override the defaults, which don't work with DLLs on Windows (#5373). In order to do this, we need to extend the API for initialising the RTS, so now we have: void hs_init_ghc (int *argc, char **argv[], // program arguments RtsConfig rts_config); // RTS configuration hs_init_ghc() can optionally be used instead of hs_init(), and allows passing in configuration options for the RTS. RtsConfig is a struct, which currently has two fields: typedef struct { RtsOptsEnabledEnum rts_opts_enabled; const char *rts_opts; } RtsConfig; but might have more in the future. There is a default value for the struct, defaultRtsConfig, the idea being that you start with this and override individual fields as necessary. In fact, main() was in a separate static library, libHSrtsmain.a. That's now gone.
Diffstat (limited to 'rts/RtsMain.c')
-rw-r--r--rts/RtsMain.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/rts/RtsMain.c b/rts/RtsMain.c
index a822da9749..0f6ca82382 100644
--- a/rts/RtsMain.c
+++ b/rts/RtsMain.c
@@ -13,7 +13,6 @@
#include "RtsAPI.h"
#include "RtsUtils.h"
-#include "RtsMain.h"
#include "Prelude.h"
#include "Task.h"
#if defined(mingw32_HOST_OS)
@@ -33,8 +32,9 @@
static int progargc;
static char **progargv;
static StgClosure *progmain_closure; /* This will be ZCMain_main_closure */
+static RtsConfig rtsconfig;
-/* Hack: we assume that we're building a batch-mode system unless
+/* Hack: we assume that we're building a batch-mode system unless
* INTERPRETER is set
*/
#ifndef INTERPRETER /* Hack */
@@ -43,9 +43,8 @@ static void real_main(void)
{
int exit_status;
SchedulerStatus status;
- /* all GranSim/GUM init is done in startupHaskell; sets IAmMainThread! */
- startupHaskell(progargc,progargv,NULL);
+ hs_init_ghc(&progargc, &progargv, rtsconfig);
/* kick off the computation by creating the main thread with a pointer
to mainIO_closure representing the computation of the overall program;
@@ -89,22 +88,26 @@ static void real_main(void)
shutdownHaskellAndExit(exit_status);
}
-/* The rts entry point from a compiled program using a Haskell main function.
- * This gets called from a tiny main function which gets linked into each
- * compiled Haskell program that uses a Haskell main function.
+/* The rts entry point from a compiled program using a Haskell main
+ * function. This gets called from a tiny main function generated by
+ * GHC and linked into each compiled Haskell program that uses a
+ * Haskell main function.
*
* We expect the caller to pass ZCMain_main_closure for
* main_closure. The reason we cannot refer to this symbol directly
* is because we're inside the rts and we do not know for sure that
* we'll be using a Haskell main function.
*/
-int hs_main(int argc, char *argv[], StgClosure *main_closure)
+int hs_main (int argc, char *argv[], // program args
+ StgClosure *main_closure, // closure for Main.main
+ RtsConfig rts_config) // RTS configuration
{
/* We do this dance with argc and argv as otherwise the SEH exception
stuff (the BEGIN/END CATCH below) on Windows gets confused */
progargc = argc;
progargv = argv;
progmain_closure = main_closure;
+ rtsconfig = rts_config;
#if defined(mingw32_HOST_OS)
BEGIN_CATCH