diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,105 @@
+import Distribution.System
+import Distribution.Verbosity
+import Distribution.PackageDescription
+import Distribution.Simple
+import Distribution.Simple.Program
+import Distribution.Simple.Setup
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Simple.Utils
+
+import System.IO
+import System.Exit
+import System.Directory
+import Control.Exception.Extensible
+
+-- TODO: it's a hack that we use the autoconfUserHooks when we're not actually
+-- using autoconf...
+main :: IO ()
+main = defaultMainWithHooks myHooks
+
+myHooks :: UserHooks
+myHooks
+    | buildOS == Windows    = simpleUserHooks
+    | otherwise = autoconfUserHooks {
+            postConf = \args flags pkgDescr lbi -> do
+                            let Just lib = library pkgDescr
+                            let bi = libBuildInfo lib
+                            bi' <- maybeSetLibiconv flags bi
+                                                        (withPrograms lbi)
+                            let pkgDescr' = pkgDescr {
+                                                library = Just lib {
+                                                    libBuildInfo = bi'}}
+                            postConf simpleUserHooks args flags pkgDescr' lbi
+            }
+
+-- Test whether compiling a c program that links against libiconv needs -liconv.
+maybeSetLibiconv :: ConfigFlags -> BuildInfo -> ProgramConfiguration -> IO BuildInfo
+maybeSetLibiconv flags bi progConf = do
+    let verb = fromFlag (configVerbosity flags)
+    if hasFlagSet flags (FlagName "libiconv")
+        then do
+            putStrLn "Using -liconv."
+            writeBuildInfo "iconv"
+            return bi
+        else do
+    putStr "checking whether to use -liconv... "
+    hFlush stdout
+    worksWithout <- tryCompile iconv_prog bi progConf verb
+    if worksWithout
+        then do
+            putStrLn "not needed."
+            writeBuildInfo ""
+            return bi
+        else do
+    let newBI = addIconv bi
+    worksWith <- tryCompile iconv_prog newBI progConf verb
+    if worksWith
+        then do
+            putStrLn "using -liconv."
+            writeBuildInfo "iconv"
+            return newBI
+        else error "Unable to link against the iconv library."
+  where
+    -- Cabal (at least 1.6.0.1) won't parse an empty buildinfo file.
+    writeBuildInfo libs = writeFile "haskeline.buildinfo"
+                            $ unlines ["extra-libraries: " ++ libs]
+
+hasFlagSet :: ConfigFlags -> FlagName -> Bool
+hasFlagSet cflags flag = Just True == lookup flag (configConfigurationsFlags cflags)
+
+tryCompile :: String -> BuildInfo -> ProgramConfiguration -> Verbosity -> IO Bool
+tryCompile program bi progConf verb = handle processExit $ handle processException $ do
+    tempDir <- getTemporaryDirectory
+    withTempFile tempDir ".c" $ \fname h -> do
+        hPutStr h program
+        hClose h
+        -- TODO take verbosity from the args.
+        rawSystemProgramStdoutConf verb gccProgram progConf (fname : args)
+        return True
+  where
+    processException :: IOException -> IO Bool
+    processException e = return False
+    processExit = return . (==ExitSuccess)
+    args = concat [ []
+                  , ccOptions bi
+                  , cppOptions bi
+                  , ldOptions bi
+                  -- --extra-include-dirs and --extra-lib-dirs are included
+                  -- in the below fields.
+                  , map ("-I" ++) (includeDirs bi)
+                  , map ("-L" ++) (extraLibDirs bi)
+                  , map ("-l" ++) (extraLibs bi)
+                  ]
+
+addIconv :: BuildInfo -> BuildInfo
+addIconv bi = bi {extraLibs = "iconv" : extraLibs bi}
+
+iconv_prog :: String
+iconv_prog = unlines $
+    [ "#include <iconv.h>"
+    , "int main(void) {"
+    , "    iconv_t t = iconv_open(\"UTF-8\", \"UTF-8\");"
+    , "    return 0;"
+    , "}"
+    ]
+    
diff --git a/Setup.lhs b/Setup.lhs
deleted file mode 100644
--- a/Setup.lhs
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/local/bin/runhaskell
-
-\begin{code}
-import Distribution.Simple
-import Distribution.Verbosity
-import Distribution.Simple.LocalBuildInfo
-import Distribution.PackageDescription
-import Distribution.Simple.GHC as GHC
-import Distribution.Simple.PreProcess
-
-main = defaultMainWithHooks simpleUserHooks {runTests = buildTestProg}
-
-buildTestProg :: [String] -> Bool -> PackageDescription -> LocalBuildInfo -> IO ()
-buildTestProg _ _ pkgDescr lbi = do
-    let newPkg = withTest pkgDescr
-    preprocessSources newPkg lbi False normal [("hsc",ppHsc2hs)]
-    GHC.build (withTest pkgDescr) lbi normal
-
-withTest :: PackageDescription -> PackageDescription
-withTest pkg@PackageDescription {library = Just lib} 
-                = pkg {executables = [testProg],
-                        library = Nothing}
-    where
-        testProg = Executable {exeName = "Test",
-                                modulePath = "examples/Test.hs",
-                                buildInfo = alterBuildInfo (libBuildInfo lib)}
-
-alterBuildInfo :: BuildInfo -> BuildInfo
-alterBuildInfo bi = bi {options = (GHC,["-threaded"]) : options bi}
-
-\end{code}
diff --git a/System/Console/Haskeline/Backend/IConv.hsc b/System/Console/Haskeline/Backend/IConv.hsc
--- a/System/Console/Haskeline/Backend/IConv.hsc
+++ b/System/Console/Haskeline/Backend/IConv.hsc
@@ -65,7 +65,14 @@
 foreign import ccall nl_langinfo :: NLItem -> IO CString
 
 getCodeset :: IO String
-getCodeset = nl_langinfo (#const CODESET) >>= peekCString
+getCodeset = do
+    str <- nl_langinfo (#const CODESET) >>= peekCString
+    -- check for codesets which may be returned by Solaris, but not understood
+    -- by GNU iconv.
+    if str `elem` ["","646"]
+        then return "ISO-8859-1"
+        else return str
+
 ----------------
 -- Iconv
 
@@ -81,7 +88,9 @@
                             withCString srcName $ \src -> do
                                 res <- iconv_open dest src
                                 if res == nullPtr `plusPtr` (-1)
-                                    then throwErrno "iconvOpen"
+                                    then throwErrno $ "iconvOpen "
+                                            ++ show (srcName,destName)
+                                    -- list the two it couldn't convert between?
                                     else newForeignPtr iconv_close res
 
 -- really this returns a CInt, but it's easiest to just ignore that, I think.
diff --git a/configure b/configure
new file mode 100644
--- /dev/null
+++ b/configure
@@ -0,0 +1,2 @@
+#!/bin/sh
+# Dummy file to be run by autoconfUserHooks.
diff --git a/haskeline.cabal b/haskeline.cabal
--- a/haskeline.cabal
+++ b/haskeline.cabal
@@ -1,6 +1,6 @@
 Name:           haskeline
 Cabal-Version:  >=1.6
-Version:        0.6.1.2
+Version:        0.6.1.3
 Category:       User Interfaces
 License:        BSD3
 License-File:   LICENSE
@@ -15,12 +15,12 @@
                 it is written in Haskell it is (hopefully) more easily used in other
                 Haskell programs.
                 .
-                Haskeline runs both on POSIX-compatible systems and on Windows
-                (under MinGW).
+                Haskeline runs both on POSIX-compatible systems and on Windows.
 Homepage:       http://trac.haskell.org/haskeline
 Stability:      Experimental
-Build-Type:     Simple
-extra-source-files: examples/Test.hs
+Build-Type:     Custom
+extra-source-files: configure examples/Test.hs
+extra-tmp-files: haskeline.buildinfo
 
 flag old-base
     Description: Use the base packages from before version 6.8
@@ -83,12 +83,6 @@
     } else {
         Build-depends: unix>=2.1 && < 2.4
                         -- unix-2.3 doesn't build on ghc-6.8.1 or earlier
-        -- temporary hack: some OSes provide iconv in (g)libc, and
-        -- some provide it as a separate libiconv.  It would be
-        -- better if we could detect this automatically, though.
-        if os(darwin) || os(freebsd) || flag(libiconv){
-            Extra-libraries: iconv
-        }
         c-sources: cbits/h_iconv.c
         includes: h_iconv.h
         install-includes: h_iconv.h
