Skip to content
Browse files

Clean up buildinfo & add GHCi support

- Enables the use of LLVM from GHCi (and other features that require dynamic loading, such as Template
  Haskell)
- Only tested on Mac OS X with GHC 6.12 and LLVM 2.7
- On Windows, I don't think dynamic loading of the llvm package will work without further tweaks,
  but everything else should be unaffected.
- When configuring the LLVM C package, pass the '--enable-shared' option (without this option, I
  expect that you lose GHCi support, but everything else should still work).
- Setup.lhs -> Setup.hs to be able to use {#- LANGUAGE CPP #-} (which is needed due to shortcomings of
  Cabal)

--HG--
extra : convert_revision : 7a84780864247577ba2761a6f6ce84aac630b9ad
  • Loading branch information...
1 parent 487ad03 commit fa6f102f30062860519984d1368587bbed28fa08 @mchakravarty mchakravarty committed Jun 18, 2010
Showing with 159 additions and 34 deletions.
  1. +118 −0 Setup.hs
  2. +0 −28 Setup.lhs
  3. +18 −2 configure
  4. +17 −2 configure.ac
  5. +4 −1 llvm.buildinfo.in
  6. +2 −1 llvm.cabal
View
118 Setup.hs
@@ -0,0 +1,118 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE PatternGuards #-}
+import System.Directory
+import System.Environment
+import System.FilePath
+import System.Info
+import Control.Monad
+import Data.List
+import Data.Maybe
+import Distribution.Simple
+import Distribution.Simple.Setup
+import Distribution.InstalledPackageInfo
+import Distribution.PackageDescription
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Simple.Install
+import Distribution.Simple.Register
+import Distribution.Simple.Utils
+
+main = do
+ let hooks = autoconfUserHooks { postConf = if os == "mingw32"
+ then generateBuildInfo
+ else postConf autoconfUserHooks
+#if (__GLASGOW_HASKELL__ >= 612)
+ , instHook = installHookWithExtraGhciLibraries
+ , regHook = regHookWithExtraGhciLibraries
+#endif
+ }
+ defaultMainWithHooks hooks
+
+-- On Windows we can't count on the configure script, so generate the
+-- llvm.buildinfo from a template.
+generateBuildInfo _ conf _ _ = do
+ let args = configConfigureArgs conf
+ let pref = "--with-llvm-prefix="
+ let path = case [ p | arg <- args, Just p <- [stripPrefix pref arg] ] of
+ [p] -> p
+ _ -> error $ "Use '--configure-option " ++ pref ++ "PATH' to give LLVM installation path"
+ info <- readFile "llvm.buildinfo.windows.in"
+ writeFile "llvm.buildinfo" $ subst "@llvm_path@" path info
+
+subst from to [] = []
+subst from to xs | Just r <- stripPrefix from xs = to ++ subst from to r
+subst from to (x:xs) = x : subst from to xs
+
+-- To compensate for Cabal's bad design, we need to replicate the default registration hook code here,
+-- to inject a value for extra-ghci-libraries into the package registration info. (Inspired by
+-- 'Gtk2HsSetup.hs'.) This only works for Cabal 1.8, but we can't test for that, so we test for the GHC
+-- version.
+--
+-- We define an extension field 'x-extra-ghci-libraries' in the .buildinfo file to communicate the
+-- version information of the LLVM dynamic library from the configure script to the registration code.
+
+#if (__GLASGOW_HASKELL__ >= 612)
+
+installHookWithExtraGhciLibraries :: PackageDescription -> LocalBuildInfo
+ -> UserHooks -> InstallFlags -> IO ()
+installHookWithExtraGhciLibraries pkg_descr localbuildinfo _ flags = do
+ let copyFlags = defaultCopyFlags {
+ copyDistPref = installDistPref flags,
+ copyDest = toFlag NoCopyDest,
+ copyVerbosity = installVerbosity flags
+ }
+ install pkg_descr localbuildinfo copyFlags
+ let registerFlags = defaultRegisterFlags {
+ regDistPref = installDistPref flags,
+ regInPlace = installInPlace flags,
+ regPackageDB = installPackageDB flags,
+ regVerbosity = installVerbosity flags
+ }
+ when (hasLibs pkg_descr) $ register' pkg_descr localbuildinfo registerFlags
+
+regHookWithExtraGhciLibraries :: PackageDescription -> LocalBuildInfo
+ -> UserHooks -> RegisterFlags -> IO ()
+regHookWithExtraGhciLibraries pkg_descr localbuildinfo _ flags =
+ if hasLibs pkg_descr
+ then register' pkg_descr localbuildinfo flags
+ else setupMessage verbosity
+ "Package contains no library to register:" (packageId pkg_descr)
+ where verbosity = fromFlag (regVerbosity flags)
+
+register' :: PackageDescription -> LocalBuildInfo
+ -> RegisterFlags -- ^Install in the user's database?; verbose
+ -> IO ()
+register' pkg@PackageDescription { library = Just lib }
+ lbi@LocalBuildInfo { libraryConfig = Just clbi } regFlags
+ = do
+
+ installedPkgInfoRaw <- generateRegistrationInfo
+ verbosity pkg lib lbi clbi inplace distPref
+
+ let ghciLibraries = case lookup "x-extra-ghci-libraries" (customFieldsBI (libBuildInfo lib)) of
+ Nothing -> []
+ Just s -> [s]
+ installedPkgInfo = installedPkgInfoRaw {
+ extraGHCiLibraries = ghciLibraries }
+
+ -- Three different modes:
+ case () of
+ _ | modeGenerateRegFile -> die "Generate Reg File not supported"
+ | modeGenerateRegScript -> die "Generate Reg Script not supported"
+ | otherwise -> registerPackage verbosity
+ installedPkgInfo pkg lbi inplace packageDb
+
+ where
+ modeGenerateRegFile = isJust (flagToMaybe (regGenPkgConf regFlags))
+ modeGenerateRegScript = fromFlag (regGenScript regFlags)
+ inplace = fromFlag (regInPlace regFlags)
+ packageDb = case flagToMaybe (regPackageDB regFlags) of
+ Just db -> db
+ Nothing -> registrationPackageDB (withPackageDB lbi)
+ distPref = fromFlag (regDistPref regFlags)
+ verbosity = fromFlag (regVerbosity regFlags)
+
+register' _ _ regFlags = notice verbosity "No package to register"
+ where
+ verbosity = fromFlag (regVerbosity regFlags)
+
+#endif
View
28 Setup.lhs
@@ -1,28 +0,0 @@
-#!/usr/bin/env runhaskell
-> {-# LANGUAGE PatternGuards #-}
-> import System.Environment
-> import System.Info
-> import Control.Monad
-> import Data.List
-> import Distribution.Simple
-> import Distribution.Simple.Setup
->
-> main = do
-> let hooks = if os == "mingw32" then autoconfUserHooks{ postConf = generateBuildInfo }
-> else autoconfUserHooks
-> defaultMainWithHooks hooks
->
-> -- On Windows we can't count on the configure script, so generate the
-> -- llvm.buildinfo from a template.
-> generateBuildInfo _ conf _ _ = do
-> let args = configConfigureArgs conf
-> let pref = "--with-llvm-prefix="
-> let path = case [ p | arg <- args, Just p <- [stripPrefix pref arg] ] of
-> [p] -> p
-> _ -> error $ "Use '--configure-option " ++ pref ++ "PATH' to give LLVM installation path"
-> info <- readFile "llvm.buildinfo.windows.in"
-> writeFile "llvm.buildinfo" $ subst "@llvm_path@" path info
->
-> subst from to [] = []
-> subst from to xs | Just r <- stripPrefix from xs = to ++ subst from to r
-> subst from to (x:xs) = x : subst from to xs
View
20 configure
@@ -639,11 +639,13 @@ ac_includes_default="\
ac_subst_vars='LTLIBOBJS
LIBOBJS
-llvm_ldflags
+llvm_ldoptions
llvm_includedir
llvm_target
-llvm_all_libs
+llvm_extra_libdirs
+llvm_extra_libs
llvm_cppflags
+llvm_version
EGREP
GREP
CPP
@@ -2524,13 +2526,25 @@ x86_64-apple-darwin)
;;
esac
+llvm_version="`$llvm_config --version`"
llvm_cppflags="`$llvm_config --cppflags`"
llvm_includedir="`$llvm_config --includedir`"
llvm_ldflags="`$llvm_config --ldflags`"
llvm_all_libs="`$llvm_config --libs all`"
llvm_target="`$llvm_config --libs engine | sed 's/.*LLVM\(.[^ ]*\)CodeGen.*/\1/'`"
+llvm_extra_libs=""
+llvm_extra_libdirs=""
+llvm_ldoptions=""
+for opt in $llvm_all_libs $llvm_ldflags; do
+ case $opt in
+ -l*) llvm_extra_libs="$llvm_extra_libs `echo $opt | sed 's/-l//'`";;
+ -L*) llvm_extra_libdirs="$llvm_extra_libdirs `echo $opt | sed 's/-L//'`";;
+ *) llvm_ldoptions="$llvm_ldoptions $opt";;
+ esac
+done
+
CPPFLAGS="$llvm_cppflags $CPPFLAGS $TARGET_CPPFLAGS"
LDFLAGS="$llvm_ldflags $LDFLAGS $TARGET_LDFLAGS"
@@ -4087,6 +4101,8 @@ fi
+
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
View
19 configure.ac
@@ -68,13 +68,26 @@ x86_64-apple-darwin)
;;
esac
+llvm_version="`$llvm_config --version`"
llvm_cppflags="`$llvm_config --cppflags`"
llvm_includedir="`$llvm_config --includedir`"
llvm_ldflags="`$llvm_config --ldflags`"
llvm_all_libs="`$llvm_config --libs all`"
llvm_target="`$llvm_config --libs engine | sed 's/.*LLVM\(.[[^ ]]*\)CodeGen.*/\1/'`"
+dnl We need to separate libraries that need to be linked from other linker options.
+llvm_extra_libs=""
+llvm_extra_libdirs=""
+llvm_ldoptions=""
+for opt in $llvm_all_libs $llvm_ldflags; do
+ case $opt in
+ -l*) llvm_extra_libs="$llvm_extra_libs `echo $opt | sed 's/-l//'`";;
+ -L*) llvm_extra_libdirs="$llvm_extra_libdirs `echo $opt | sed 's/-L//'`";;
+ *) llvm_ldoptions="$llvm_ldoptions $opt";;
+ esac
+done
+
CPPFLAGS="$llvm_cppflags $CPPFLAGS $TARGET_CPPFLAGS"
LDFLAGS="$llvm_ldflags $LDFLAGS $TARGET_LDFLAGS"
@@ -89,10 +102,12 @@ CC=$CXX
AC_CHECK_LIB(LLVMCore, LLVMModuleCreateWithName, [],
[AC_MSG_ERROR(could not find LLVM C bindings)])
+AC_SUBST([llvm_version])
AC_SUBST([llvm_cppflags])
-AC_SUBST([llvm_all_libs])
+AC_SUBST([llvm_extra_libs])
+AC_SUBST([llvm_extra_libdirs])
AC_SUBST([llvm_target])
AC_SUBST([llvm_includedir])
-AC_SUBST([llvm_ldflags])
+AC_SUBST([llvm_ldoptions])
AC_OUTPUT
View
5 llvm.buildinfo.in
@@ -1,4 +1,7 @@
cpp-options: @llvm_cppflags@ -DTARGET=@llvm_target@
ghc-options: -pgml @CXX@
-ld-options: @llvm_all_libs@ @llvm_ldflags@ -lstdc++
+extra-libraries: @llvm_extra_libs@ stdc++
+extra-lib-dirs: @llvm_extra_libdirs@
+x-extra-ghci-libraries: LLVM-@llvm_version@
+ld-options: @llvm_ldoptions@
include-dirs: @llvm_includedir@
View
3 llvm.cabal
@@ -78,7 +78,8 @@ library
ghc-options: -Wall
if os(darwin)
- ld-options: -w /System/Library/Frameworks/vecLib.framework/Versions/A/vecLib
+ ld-options: -w
+ frameworks: vecLib
cpp-options: -D__MACOS__
exposed-modules:

0 comments on commit fa6f102

Please sign in to comment.
Something went wrong with that request. Please try again.