summaryrefslogtreecommitdiff
path: root/rts/RtsFlags.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/RtsFlags.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/RtsFlags.c')
-rw-r--r--rts/RtsFlags.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c
index d2b4945c19..d8bcf1c915 100644
--- a/rts/RtsFlags.c
+++ b/rts/RtsFlags.c
@@ -10,7 +10,6 @@
#include "PosixSource.h"
#include "Rts.h"
-#include "RtsOpts.h"
#include "RtsUtils.h"
#include "Profiling.h"
#include "RtsFlags.h"
@@ -396,9 +395,10 @@ strequal(const char *a, const char * b)
return(strcmp(a, b) == 0);
}
-static void splitRtsFlags(char *s)
+static void splitRtsFlags(const char *s)
{
- char *c1, *c2;
+ const char *c1, *c2;
+ char *t;
c1 = s;
do {
@@ -408,10 +408,10 @@ static void splitRtsFlags(char *s)
if (c1 == c2) { break; }
- s = stgMallocBytes(c2-c1+1, "RtsFlags.c:splitRtsFlags()");
- strncpy(s, c1, c2-c1);
- s[c2-c1] = '\0';
- rts_argv[rts_argc++] = s;
+ t = stgMallocBytes(c2-c1+1, "RtsFlags.c:splitRtsFlags()");
+ strncpy(t, c1, c2-c1);
+ t[c2-c1] = '\0';
+ rts_argv[rts_argc++] = t;
c1 = c2;
} while (*c1 != '\0');
@@ -434,7 +434,9 @@ static void splitRtsFlags(char *s)
-------------------------------------------------------------------------- */
-void setupRtsFlags (int *argc, char *argv[])
+void setupRtsFlags (int *argc, char *argv[],
+ RtsOptsEnabledEnum rtsOptsEnabled,
+ const char *ghc_rts_opts)
{
nat mode;
nat total_arg;
@@ -554,14 +556,14 @@ static void checkUnsafe(RtsOptsEnabledEnum enabled)
}
}
-static void procRtsOpts (int rts_argc0, RtsOptsEnabledEnum enabled)
+static void procRtsOpts (int rts_argc0, RtsOptsEnabledEnum rtsOptsEnabled)
{
rtsBool error = rtsFalse;
int arg;
if (!(rts_argc0 < rts_argc)) return;
- if (enabled == RtsOptsNone) {
+ if (rtsOptsEnabled == RtsOptsNone) {
errorBelch("RTS options are disabled. Link with -rtsopts to enable them.");
stg_exit(EXIT_FAILURE);
}
@@ -578,7 +580,7 @@ static void procRtsOpts (int rts_argc0, RtsOptsEnabledEnum enabled)
rtsBool option_checked = rtsFalse;
#define OPTION_SAFE option_checked = rtsTrue;
-#define OPTION_UNSAFE checkUnsafe(enabled); option_checked = rtsTrue;
+#define OPTION_UNSAFE checkUnsafe(rtsOptsEnabled); option_checked = rtsTrue;
if (rts_argv[arg][0] != '-') {
fflush(stdout);
@@ -1142,7 +1144,7 @@ error = rtsTrue;
errorBelch("bad value for -N");
error = rtsTrue;
}
- if (enabled == RtsOptsSafeOnly &&
+ if (rtsOptsEnabled == RtsOptsSafeOnly &&
nNodes > (int)getNumberOfProcessors()) {
errorBelch("Using large values for -N is not allowed by default. Link with -rtsopts to allow full control.");
stg_exit(EXIT_FAILURE);