diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+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.
+
+  * The names of its contributors may not 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/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,40 @@
+#! /usr/bin/env runhaskell
+
+> module Main ( main ) where
+>
+> import Data.Char
+> import Data.Maybe
+> import Distribution.PackageDescription
+> import Distribution.Simple
+> import Distribution.Simple.LocalBuildInfo
+> import Distribution.Simple.Program
+> import Distribution.Simple.Setup
+>
+> main :: IO ()
+> main = defaultMainWithHooks simpleUserHooks
+>        { hookedPrograms = map simpleProgram programs
+>        , confHook = configure
+>        }
+>
+> programs :: [String]
+> programs = ["nix-instantiate", "nix-build", "nix-env", "nix-store"]
+>
+> configure :: (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo
+> configure (gpd, hbi) flags = do
+>   lbi' <- confHook simpleUserHooks (gpd, hbi) flags
+>   let paths = map (\p -> (p, maybe p programPath (lookupProgram (simpleProgram p) (withPrograms lbi)))) programs
+>       descr = localPkgDescr lbi'
+>       lib = fromJust (library descr)
+>       libbi = libBuildInfo lib
+>       lbi = lbi' { localPkgDescr = descr
+>                    { library = Just (lib { libBuildInfo = libbi { cppOptions = cppOptions libbi ++ map fmtCppArg paths } })
+>                    }
+>                  }
+>   return lbi
+>
+> fmtCppArg :: (String, FilePath) -> String
+> fmtCppArg (prg, path) = "-DPATH_TO_" ++ map mangle prg ++ "=" ++ show path
+>   where
+>     mangle :: Char -> Char
+>     mangle '-' = '_'
+>     mangle c = toUpper c
diff --git a/nix-paths.cabal b/nix-paths.cabal
new file mode 100644
--- /dev/null
+++ b/nix-paths.cabal
@@ -0,0 +1,35 @@
+name:                   nix-paths
+version:                1
+synopsis:               Knowledge of Nix's installation directories.
+description:            This module provides full paths to various Nix
+                        utilities, like @nix-store@, @nix-instantiate@, and
+                        @nix-env@.
+category:               Distribution
+homepage:               https://github.com/nixos/cabal2nix#readme
+bug-reports:            https://github.com/nixos/cabal2nix/issues
+maintainer:             Peter Simons <simons@cryp.to>
+license:                BSD3
+license-file:           LICENSE
+build-type:             Custom
+cabal-version:          >= 1.10
+
+flag allow-relative-paths
+  description:          If any of the required Nix tools are missing at
+                        build-time, compile a run-time @$PATH@ dependent
+                        variant of this library instead of failing. This is
+                        useful for test environment such as Travis-CI, which
+                        may not have Nix installed.
+  default:              False
+  manual:               True
+
+source-repository head
+  type: git
+  location: https://github.com/nixos/cabal2nix
+
+library
+  default-language:     Haskell2010
+  hs-source-dirs:       src
+  exposed-modules:      Nix.Paths, Nix.FindFile
+  build-depends:        base < 5, process
+  if !flag(allow-relative-paths)
+    build-tools:        nix-instantiate, nix-build, nix-env, nix-store
diff --git a/src/Nix/FindFile.hs b/src/Nix/FindFile.hs
new file mode 100644
--- /dev/null
+++ b/src/Nix/FindFile.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE CPP #-}
+
+module Nix.FindFile ( findFile, findFileWithDefault ) where
+
+import Nix.Paths ( nixInstantiate )
+
+import Data.Maybe
+import System.Exit
+import System.Process
+
+-- | Use @nix-instantiate --find-file@ to resolve an abbreviated path into a
+-- full absolute path using @$NIX_PATH@.
+--
+-- >>> findFile "nixpkgs/pkgs/development/haskell-modules/configuration-hackage2nix.yaml"
+-- Just "/home/foobar/.nix-defexpr/pkgs/development/haskell-modules/configuration-hackage2nix.yaml"
+--
+-- >>> findFile "nixpkgs/crazy/non-existent-path"
+-- Nothing
+
+findFile :: FilePath -> IO (Maybe FilePath)
+findFile path = do
+   (ec, out, _) <- readProcessWithExitCode nixInstantiate ["--find-file", path ] ""
+   case (ec, lines out) of
+      (ExitFailure _, _)     -> return Nothing
+      (ExitSuccess, [path']) -> return (Just path')
+      _                      -> fail "unexpected response from nix-instantiate"
+
+-- | A convenience wrapper around 'findFile' that returns the given default
+-- value in case the function returns nothing.
+--
+-- @
+-- findFileWithDefault def = 'fmap' ('fromMaybe' def) . 'findFile'
+-- @
+
+findFileWithDefault :: FilePath -> FilePath -> IO FilePath
+findFileWithDefault def = fmap (fromMaybe def) . findFile
diff --git a/src/Nix/Paths.hs b/src/Nix/Paths.hs
new file mode 100644
--- /dev/null
+++ b/src/Nix/Paths.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE CPP #-}
+
+module Nix.Paths ( nixInstantiate, nixBuild, nixEnv, nixStore ) where
+
+-- | Complete path to the @nix-instantiate@ executable.
+nixInstantiate :: FilePath
+nixInstantiate = PATH_TO_NIX_INSTANTIATE
+
+-- | Complete path to the @nix-build@ executable.
+nixBuild :: FilePath
+nixBuild = PATH_TO_NIX_BUILD
+
+-- | Complete path to the @nix-env@ executable.
+nixEnv :: FilePath
+nixEnv = PATH_TO_NIX_ENV
+
+-- | Complete path to the @nix-store@ executable.
+nixStore :: FilePath
+nixStore = PATH_TO_NIX_STORE
