diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,3 @@
+# 1  -- 2017-01-31
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2017, Oleg Grenrus
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Oleg Grenrus nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,71 @@
+cabal-doctest
+-------------
+
+[![Hackage](https://img.shields.io/hackage/v/cabal-doctest.svg)](https://hackage.haskell.org/package/cabal-doctest) [![Build Status](https://travis-ci.org/phadej/cabal-doctest.svg?branch=master)](https://travis-ci.org/phadej/cabal-doctest)
+
+A `Setup.hs` helper for running `doctests`.
+
+Example Usage
+=============
+
+To use this library in your `Setup.hs`, you should specify a `custom-setup`
+section in your `.cabal` file. For example:
+
+```
+custom-setup
+ setup-depends:
+   base >= 4 && <5,
+   cabal-doctest >= 1 && <1.1
+```
+
+You'll also need to specify `build-type: Custom` at the top of the `.cabal`
+file. Now put this into your `Setup.hs` file:
+
+```haskell
+module Main where
+
+import Distribution.Extra.Doctest (defaultMainWithDoctests)
+
+main :: IO ()
+main = defaultMainWithDoctests "doctests"
+```
+
+When you build your project, this `Setup` will generate a `Build_doctests`
+module. To use it in a testsuite, simply do this:
+
+```haskell
+module Main where
+
+import Build_doctests (flags, pkgs, module_sources)
+import Data.Foldable (traverse_)
+import Test.Doctest (doctest)
+
+main :: IO ()
+main = do
+    traverse_ putStrLn args -- optionally print arguments
+    doctest args
+  where
+    args = flags ++ pkgs ++ module_sources
+```
+
+Notes
+=====
+
+* `custom-setup` section is supported starting from `cabal-install-1.24`.
+  For older `cabal-install's` you have to install custom setup dependencies
+  manually.
+
+* `stack` respects `custom-setup` starting from version 1.3.3. Before that
+  you have to use `explicit-setup-deps` setting in your `stack.yaml`.
+  ([stack/GH-2094](https://github.com/commercialhaskell/stack/issues/2094))
+
+* There is [an issue in the Cabal issue tracker](https://github.com/haskell/cabal/issues/2327 Cabal/2327)
+  about adding `cabal doctest` command. After that command is implemented,
+  this library will be deprecated.
+
+Copyright
+=========
+
+Copyright 2017 Oleg Grenrus.
+
+Available under the BSD 3-clause license.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/cabal-doctest.cabal b/cabal-doctest.cabal
new file mode 100644
--- /dev/null
+++ b/cabal-doctest.cabal
@@ -0,0 +1,46 @@
+name:                cabal-doctest
+version:             1
+synopsis:            A Setup.hs helper for doctests running
+description:
+  Currently (beginning of 2017), there isn't @cabal doctest@
+  command. Yet, to properly work doctest needs plenty of configuration.
+  This library provides the common bits for writing custom Setup.hs
+
+  See <https://github.com/haskell/cabal/issues/2327 Cabal/2327> for the progress
+  of @cabal doctest@, i.e. whether this library is obsolete.
+
+homepage:            https://github.com/phadej/cabal-doctests
+license:             BSD3
+license-file:        LICENSE
+author:              Oleg Grenrus <oleg.grenrus@iki.fi>
+maintainer:          Oleg Grenrus <oleg.grenrus@iki.fi>
+copyright:           (c) 2017 Oleg Grenrus
+category:            Distribution
+build-type:          Simple
+cabal-version:       >=1.10
+extra-source-files:  ChangeLog.md README.md
+tested-with:
+  GHC==7.0.4,
+  GHC==7.2.2,
+  GHC==7.4.2,
+  GHC==7.6.3,
+  GHC==7.8.4,
+  GHC==7.10.3,
+  GHC==8.0.2,
+  GHC==8.1.*
+
+source-repository head
+  type:     git
+  location: https://github.com/phadej/cabal-doctest
+
+library
+  exposed-modules:     Distribution.Extra.Doctest
+  other-modules:
+  other-extensions:
+  build-depends:
+    base >=4.3 && <4.11,
+    Cabal >= 1.10 && <2.1,
+    filepath,
+    directory
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/Distribution/Extra/Doctest.hs b/src/Distribution/Extra/Doctest.hs
new file mode 100644
--- /dev/null
+++ b/src/Distribution/Extra/Doctest.hs
@@ -0,0 +1,246 @@
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE OverloadedStrings #-}
+-- | The provided 'generateBuildModule' generates 'Build_doctests' module.
+-- That module exports enough configuration, so your doctests could be simply
+--
+-- @
+-- module Main where
+-- 
+-- import Build_doctests (flags, pkgs, module_sources)
+-- import Data.Foldable (traverse_)
+-- import Test.Doctest (doctest)
+-- 
+-- main :: IO ()
+-- main = do
+--     traverse_ putStrLn args -- optionally print arguments
+--     doctest args
+--   where
+--     args = flags ++ pkgs ++ module_sources
+-- @
+--
+-- To use this library in the @Setup.hs@, you should specify a @custom-setup@ 
+-- section in the cabal file, for example:
+--
+-- @
+-- custom-setup
+--  setup-depends:
+--    base >= 4 && <5,
+--    cabal-doctest >= 1 && <1.1
+-- @
+--
+-- /Note:/ you don't need to depend on @Cabal@  if you use only
+-- 'defaultMainWithDoctests' in the @Setup.hs".
+--
+module Distribution.Extra.Doctest (
+    defaultMainWithDoctests,
+    doctestsUserHooks,
+    generateBuildModule,
+    ) where
+
+-- Hacky way to suppress few deprecation warnings.
+#if MIN_VERSION_Cabal(1,24,0)
+#define InstalledPackageId UnitId
+#endif
+
+import Control.Monad
+       (when)
+import Data.List
+       (nub)
+import Data.String
+       (fromString)
+import Distribution.Package
+       (InstalledPackageId)
+import Distribution.Package
+       (Package (..), PackageId, packageVersion)
+import Distribution.PackageDescription
+       (BuildInfo (..), Library (..), PackageDescription (), TestSuite (..))
+import Distribution.Simple
+       (UserHooks (..), defaultMainWithHooks, simpleUserHooks)
+import Distribution.Simple.BuildPaths
+       (autogenModulesDir)
+import Distribution.Simple.Compiler
+       (PackageDB (..), showCompilerId)
+import Distribution.Simple.LocalBuildInfo
+       (ComponentLocalBuildInfo (componentPackageDeps), LocalBuildInfo (),
+       compiler, withLibLBI, withPackageDB, withTestLBI)
+import Distribution.Simple.Setup
+       (BuildFlags (buildDistPref, buildVerbosity), fromFlag)
+import Distribution.Simple.Utils
+       (createDirectoryIfMissingVerbose, rewriteFile)
+import Distribution.Text
+       (display, simpleParse)
+import System.FilePath
+       ((</>))
+
+#if MIN_VERSION_Cabal(1,25,0)
+import Distribution.Simple.BuildPaths
+       (autogenComponentModulesDir)
+#endif
+
+#if MIN_VERSION_directory(1,2,2)
+import System.Directory
+       (makeAbsolute)
+#else
+import System.Directory
+       (getCurrentDirectory)
+import System.FilePath
+       (isAbsolute)
+
+makeAbsolute :: FilePath -> IO FilePath
+makeAbsolute p | isAbsolute p = return p
+               | otherwise    = do
+    cwd <- getCurrentDirectory
+    return $ cwd </> p
+#endif
+
+-- | A default main with doctests:
+--
+-- @
+-- import Distribution.Extra.Doctest
+--        (defaultMainWithDoctests)
+--
+-- main :: IO ()
+-- main = defaultMainWithDoctests "doctests"
+-- @
+defaultMainWithDoctests
+    :: String  -- ^ doctests test-suite name
+    -> IO ()
+defaultMainWithDoctests = defaultMainWithHooks . doctestsUserHooks
+
+-- | 'simpleUserHooks' with 'generateBuildModule' prepended to the 'buildHook'.
+doctestsUserHooks
+    :: String  -- ^ doctests test-suite name
+    -> UserHooks
+doctestsUserHooks testsuiteName = simpleUserHooks
+    { buildHook = \pkg lbi hooks flags -> do
+       generateBuildModule testsuiteName flags pkg lbi
+       buildHook simpleUserHooks pkg lbi hooks flags
+    }
+
+-- | Generate a build module for the test suite.
+--
+-- @
+-- import Distribution.Simple
+--        (defaultMainWithHooks, UserHooks(..), simpleUserHooks)
+-- import Distribution.Extra.Doctest
+--        (generateBuildModule)
+--
+-- main :: IO ()
+-- main = defaultMainWithHooks simpleUserHooks
+--     { buildHook = \pkg lbi hooks flags -> do
+--         generateBuildModule "doctests" flags pkg lbi
+--         buildHook simpleUserHooks pkg lbi hooks flags
+--     }
+-- @
+generateBuildModule
+    :: String -- ^ doctests test-suite name
+    -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
+generateBuildModule testSuiteName flags pkg lbi = do
+  let verbosity = fromFlag (buildVerbosity flags)
+  let distPref = fromFlag (buildDistPref flags)
+
+  -- Package DBs
+  let dbStack = withPackageDB lbi ++ [ SpecificPackageDB $ distPref </> "package.conf.inplace" ]
+  let dbFlags = "-hide-all-packages" : packageDbArgs dbStack
+
+  withLibLBI pkg lbi $ \lib libcfg -> do
+    let libBI = libBuildInfo lib
+
+    -- modules
+    let modules = exposedModules lib ++ otherModules libBI
+    -- it seems that doctest is happy to take in module names, not actual files!
+    let module_sources = modules
+
+    -- We need the directory with library's cabal_macros.h!
+#if MIN_VERSION_Cabal(1,25,0)
+    let libAutogenDir = autogenComponentModulesDir lbi libcfg
+#else
+    let libAutogenDir = autogenModulesDir lbi
+#endif
+
+    -- Lib sources and includes
+    iArgs <- mapM (fmap ("-i"++) . makeAbsolute) $ libAutogenDir : hsSourceDirs libBI
+    includeArgs <- mapM (fmap ("-I"++) . makeAbsolute) $ includeDirs libBI
+
+    -- CPP includes, i.e. include cabal_macros.h
+    let cppFlags = map ("-optP"++) $
+            [ "-include", libAutogenDir ++ "/cabal_macros.h" ]
+            ++ cppOptions libBI
+
+    withTestLBI pkg lbi $ \suite suitecfg -> when (testName suite == fromString testSuiteName) $ do
+
+      -- get and create autogen dir
+#if MIN_VERSION_Cabal(1,25,0)
+      let testAutogenDir = autogenComponentModulesDir lbi suitecfg
+#else
+      let testAutogenDir = autogenModulesDir lbi
+#endif
+      createDirectoryIfMissingVerbose verbosity True testAutogenDir
+
+      -- write autogen'd file
+      rewriteFile (testAutogenDir </> "Build_doctests.hs") $ unlines
+        [ "module Build_doctests where"
+        , ""
+        -- -package-id etc. flags
+        , "pkgs :: [String]"
+        , "pkgs = " ++ (show $ formatDeps $ testDeps libcfg suitecfg)
+        , ""
+        , "flags :: [String]"
+        , "flags = " ++ show (iArgs ++ includeArgs ++ dbFlags ++ cppFlags)
+        , ""
+        , "module_sources :: [String]"
+        , "module_sources = " ++ show (map display module_sources)
+        ]
+  where
+    -- we do this check in Setup, as then doctests don't need to depend on Cabal
+    isOldCompiler = maybe False id $ do
+      a <- simpleParse $ showCompilerId $ compiler lbi
+      b <- simpleParse "7.5"
+      return $ packageVersion (a :: PackageId) < b
+
+    formatDeps = map formatOne
+    formatOne (installedPkgId, pkgId)
+      -- The problem is how different cabal executables handle package databases
+      -- when doctests depend on the library
+      | packageId pkg == pkgId = "-package=" ++ display pkgId
+      | otherwise              = "-package-id=" ++ display installedPkgId
+
+    -- From Distribution.Simple.Program.GHC
+    packageDbArgs :: [PackageDB] -> [String]
+    packageDbArgs | isOldCompiler = packageDbArgsConf
+                  | otherwise     = packageDbArgsDb
+
+    -- GHC <7.6 uses '-package-conf' instead of '-package-db'.
+    packageDbArgsConf :: [PackageDB] -> [String]
+    packageDbArgsConf dbstack = case dbstack of
+      (GlobalPackageDB:UserPackageDB:dbs) -> concatMap specific dbs
+      (GlobalPackageDB:dbs)               -> ("-no-user-package-conf")
+                                           : concatMap specific dbs
+      _ -> ierror
+      where
+        specific (SpecificPackageDB db) = [ "-package-conf=" ++ db ]
+        specific _                      = ierror
+        ierror = error $ "internal error: unexpected package db stack: "
+                      ++ show dbstack
+
+    -- GHC >= 7.6 uses the '-package-db' flag. See
+    -- https://ghc.haskell.org/trac/ghc/ticket/5977.
+    packageDbArgsDb :: [PackageDB] -> [String]
+    -- special cases to make arguments prettier in common scenarios
+    packageDbArgsDb dbstack = case dbstack of
+      (GlobalPackageDB:UserPackageDB:dbs)
+        | all isSpecific dbs              -> concatMap single dbs
+      (GlobalPackageDB:dbs)
+        | all isSpecific dbs              -> "-no-user-package-db"
+                                           : concatMap single dbs
+      dbs                                 -> "-clear-package-db"
+                                           : concatMap single dbs
+     where
+       single (SpecificPackageDB db) = [ "-package-db=" ++ db ]
+       single GlobalPackageDB        = [ "-global-package-db" ]
+       single UserPackageDB          = [ "-user-package-db" ]
+       isSpecific (SpecificPackageDB _) = True
+       isSpecific _                     = False
+
+testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId)]
+testDeps xs ys = nub $ componentPackageDeps xs ++ componentPackageDeps ys
