Parse the ghc --info values using a Haskell program, and cache the results
authorSimon Marlow <marlowsd@gmail.com>
Mon, 16 Jan 2012 11:48:00 +0000 (11:48 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Mon, 16 Jan 2012 13:31:20 +0000 (13:31 +0000)
Should improve startup time of make in the testsuite, and it is
simpler.

testsuite/Makefile
testsuite/mk/boilerplate.mk
testsuite/mk/ghc-config.hs [new file with mode: 0644]
testsuite/mk/test.mk

index 9bb1c7d..97ee47f 100644 (file)
@@ -21,4 +21,4 @@ endif
 
 clean distclean maintainer-clean:
        $(MAKE) -C $(TOP)/timeout $@
-
+       $(RM) -f mk/*.o mk/*.hi mk/ghc-config mk/ghc-config.exe mk/ghcconfig*.mk
index d8c7c9e..881e8d7 100644 (file)
@@ -35,26 +35,6 @@ endif
 $(call canonicalise,$1)
 endef
 
-define get-ghc-rts-field # $1 = result variable, $2 = field name
-$1 := $$(shell '$$(TEST_HC)' +RTS --info | grep '^ .("$2",' | tr -d '\r' | sed -e 's/.*", *"//' -e 's/")$$$$//')
-endef
-
-define get-ghc-field # $1 = result variable, $2 = field name
-$1 := $$(shell '$$(TEST_HC)' --info | grep '^ .("$2",' | tr -d '\r' | sed -e 's/.*", *"//' -e 's/")$$$$//')
-endef
-
-define get-ghc-feature-bool # $1 = result variable, $2 = field name
-SHELL_RES := $$(shell '$$(TEST_HC)' --info | grep '^ .("$2",' | tr -d '\r' | sed -e 's/.*", *"//' -e 's/")$$$$//')
-$1 := $$(strip \
-         $$(if $$(SHELL_RES), \
-         $$(if $$(subst YES,,$$(SHELL_RES)), \
-            $$(if $$(subst NO,,$$(SHELL_RES)), \
-               $$(warning ghc info field not YES or NO: $2: $$(SHELL_RES)), \
-               NO), \
-            YES), \
-         $$(warning ghc info field not found: $2)))
-endef
-
 ifeq "$(TEST_HC)" ""
 
 STAGE1_GHC := $(abspath $(TOP)/../inplace/bin/ghc-stage1)
@@ -136,9 +116,6 @@ ifeq "$(shell test -x '$(HPC)' && echo exists)" ""
 $(error Cannot find hpc: $(HPC))
 endif
 
-$(eval $(call get-ghc-field,GhcRTSWays,RTS ways))
-
-$(eval $(call get-ghc-field,AR,ar command))
 ifeq "$(AR)" ""
 AR = ar
 endif
@@ -151,7 +128,25 @@ CP = cp
 RM = rm -f
 PYTHON = python
 
-$(eval $(call get-ghc-rts-field,HostOS,Host OS))
+# -----------------------------------------------------------------------------
+# configuration of TEST_HC
+
+# ghc-config.hs is a short Haskell program that runs ghc --info, parses
+# the results, and emits a little .mk file with make bindings for the values.
+# This way we cache the results for different values of $(TEST_HC)
+
+$(TOP_ABS)/mk/ghc-config : $(TOP_ABS)/mk/ghc-config.hs
+       "$(TEST_HC)" --make -o $@ $<
+
+ghc-config-mk = $(TOP_ABS)/mk/ghcconfig$(subst /,_,$(subst \,_,$(TEST_HC))).mk
+
+$(ghc-config-mk) : $(TOP_ABS)/mk/ghc-config
+       $(TOP_ABS)/mk/ghc-config $(TEST_HC) >$@
+
+include $(ghc-config-mk)
+
+# -----------------------------------------------------------------------------
+
 ifeq "$(HostOS)" "mingw32"
 WINDOWS = YES
 else
diff --git a/testsuite/mk/ghc-config.hs b/testsuite/mk/ghc-config.hs
new file mode 100644 (file)
index 0000000..d2e9e7f
--- /dev/null
@@ -0,0 +1,29 @@
+import System.Environment
+import System.Process
+
+main = do
+  [ghc] <- getArgs
+
+  info <- readProcess ghc ["+RTS", "--info"] ""
+  let fields = read info :: [(String,String)]
+  getGhcField fields "HostOS" "Host OS"
+  getGhcField fields "WORDSIZE" "Word size"
+  getGhcField fields "TARGETPLATFORM" "Target platform"
+  getGhcField fields "TargetOS_CPP" "Target OS"
+  getGhcField fields "TargetARCH_CPP" "Target architecture"
+
+  info <- readProcess ghc ["--info"] ""
+  let fields = read info :: [(String,String)]
+  getGhcField fields "GhcStage" "Stage"
+  getGhcField fields "GhcWithNativeCodeGen" "Have native code generator"
+  getGhcField fields "GhcWithInterpreter" "Have interpreter"
+  getGhcField fields "GhcUnregisterised" "Unregisterised"
+  getGhcField fields "GhcWithSMP" "Support SMP"
+  getGhcField fields "GhcRTSWays" "RTS ways"
+  getGhcField fields "AR" "ar command"
+
+getGhcField :: [(String,String)] -> String -> String -> IO ()
+getGhcField fields mkvar key = do
+   case lookup key fields of
+      Nothing  -> fail ("No field: " ++ key)
+      Just val -> putStrLn (mkvar ++ '=':val)
index 789ca9d..23c3495 100644 (file)
@@ -31,10 +31,6 @@ TEST_HC_OPTS = -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-
 
 RUNTEST_OPTS =
 
-$(eval $(call get-ghc-rts-field,WORDSIZE,Word size))
-$(eval $(call get-ghc-rts-field,TARGETPLATFORM,Target platform))
-$(eval $(call get-ghc-rts-field,TargetOS_CPP,Target OS))
-$(eval $(call get-ghc-rts-field,TargetARCH_CPP,Target architecture))
 ifeq "$(filter $(TargetOS_CPP), cygwin32 mingw32)" ""
 exeext =
 else
@@ -43,7 +39,6 @@ endif
 
 RUNTEST_OPTS += -e ghc_compiler_always_flags="'$(TEST_HC_OPTS)'"
 
-$(eval $(call get-ghc-feature-bool,GhcWithNativeCodeGen,Have native code generator))
 ifeq "$(GhcWithNativeCodeGen)" "YES"
 RUNTEST_OPTS += -e ghc_with_native_codegen=1
 else
@@ -71,8 +66,6 @@ else
 RUNTEST_OPTS += -e ghc_with_dynamic_rts=0
 endif
 
-$(eval $(call get-ghc-field,GhcStage,Stage))
-$(eval $(call get-ghc-feature-bool,GhcWithInterpreter,Have interpreter))
 ifeq "$(GhcWithInterpreter)" "NO"
 RUNTEST_OPTS += -e ghc_with_interpreter=0
 else ifeq "$(GhcStage)" "1"
@@ -81,14 +74,12 @@ else
 RUNTEST_OPTS += -e ghc_with_interpreter=1
 endif
 
-$(eval $(call get-ghc-feature-bool,GhcUnregisterised,Unregisterised))
 ifeq "$(GhcUnregisterised)" "YES"
 RUNTEST_OPTS += -e ghc_unregisterised=1
 else
 RUNTEST_OPTS += -e ghc_unregisterised=0
 endif
 
-$(eval $(call get-ghc-feature-bool,GhcWithSMP,Support SMP))
 ifeq "$(GhcWithSMP)" "YES"
 RUNTEST_OPTS += -e ghc_with_smp=1
 else