diff --git a/shake-ext.cabal b/shake-ext.cabal
--- a/shake-ext.cabal
+++ b/shake-ext.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.18
 name: shake-ext
-version: 2.7.0.2
+version: 2.7.0.3
 license: BSD3
 license-file: LICENSE
 copyright: Copyright: (c) 2018 Vanessa McHale
@@ -41,13 +41,12 @@
         Development.Shake.TH
     default-language: Haskell2010
     ghc-options: -Wall
+    build-tools: cpphs
     build-depends:
         base >=4.10 && <5,
         shake -any,
-        mtl -any,
         composition-prelude,
         directory -any,
-        text -any,
         Cabal >=2.0,
         template-haskell -any
     
diff --git a/src/Development/Shake/C.hs b/src/Development/Shake/C.hs
--- a/src/Development/Shake/C.hs
+++ b/src/Development/Shake/C.hs
@@ -1,9 +1,11 @@
 {-# LANGUAGE CPP             #-}
 {-# LANGUAGE PatternSynonyms #-}
 
+-- | This module provides functions for easy C builds of binaries, static
+-- libraries, and dynamic libraries.
 module Development.Shake.C ( -- * Types
                              CConfig (..)
-                           , CCompiler (GCC, Clang, GHC, Other, GCCStd, GHCStd)
+                           , CCompiler (GCC, Clang, GHC, Other, GCCStd, GHCStd, CompCert)
                            -- * Rules
                            , staticLibR
                            , sharedLibR
@@ -12,7 +14,7 @@
                            , cBin
                            , cToLib
                            -- * Actions
-                           , ccAction
+                           , binaryA
                            , staticLibA
                            , sharedLibA
                            -- * Helper functions
@@ -37,28 +39,35 @@
           f = maybe id (flip mappend)
           h = foldr fmap id
 
+-- | The target triple of the host machine.
 host :: String
 host = arch ++ withManufacturer os
     where withManufacturer "darwin" = "-apple-" ++ os
           withManufacturer _        = "-unknown-" ++ os
 
+-- | Default @gcc@ available
 pattern GCCStd :: CCompiler
 pattern GCCStd = GCC Nothing
 
+-- | Default @ghc@ available
 pattern GHCStd :: CCompiler
 pattern GHCStd = GHC Nothing Nothing
 
+-- | Get the executable name associated with a 'CCompiler'
 ccToString :: CCompiler -> String
 ccToString Clang          = "clang"
 ccToString (Other s)      = s
 ccToString (GCC pre)      = mkQualified pre Nothing "gcc"
 ccToString (GHC pre suff) = mkQualified pre suff "ghc"
+ccToString CompCert       = "ccomp"
 
 arToString :: CCompiler -> String
 arToString (GCC pre)   = mkQualified pre Nothing "ar"
 arToString (GHC pre _) = mkQualified pre Nothing "ar"
 arToString _           = "ar"
 
+-- | Attempt to parse a string as a 'CCompiler', defaulting to @cc@ if parsing
+-- fails.
 ccFromString :: String -> CCompiler
 ccFromString "gcc" = GCC Nothing
 ccFromString "clang" = Clang
@@ -67,68 +76,73 @@
     | "gcc" `isSuffixOf` s = GCC (Just (reverse . drop 3 . reverse $ s))
     | "ghc" `isSuffixOf` s = GHC (Just (reverse . drop 3 . reverse $ s)) Nothing
     | "ghc" `isPrefixOf` s = GHC Nothing (Just (drop 3 s))
-ccFromString _ = GCC Nothing
+ccFromString _ = Other "cc"
 
-data CCompiler = GCC { _prefix :: Maybe String }
+-- | A data type representing the C compiler to be used.
+data CCompiler = GCC { _prefix :: Maybe String -- ^ Usually the target triple
+                     }
                | Clang
-               | GHC { _prefix :: Maybe String, _postfix :: Maybe String }
+               | GHC { _prefix  :: Maybe String -- ^ The target triple
+                     , _postfix :: Maybe String -- ^ The compiler version
+                     }
+               | CompCert
                | Other String
                deriving (Eq)
 
 mapFlags :: String -> ([String] -> [String])
 mapFlags s = fmap (s <>)
 
-data CConfig = CConfig { includes  :: [String] -- ^ Directories to be included.
-                       , libraries :: [String] -- ^ Libraries against which to link.
-                       , libDirs   :: [String] -- ^ Directories to find libraries.
-                       , extras    :: [String] -- ^ Extra flags to be passed to the compiler
+data CConfig = CConfig { includes   :: [String] -- ^ Directories to be included.
+                       , libraries  :: [String] -- ^ Libraries against which to link.
+                       , libDirs    :: [String] -- ^ Directories to find libraries.
+                       , extras     :: [String] -- ^ Extra flags to be passed to the compiler
+                       , staticLink :: Bool -- ^ Whether to link against static versions of libraries
                        }
 
--- | Rules for making a static library from C source files
+-- | Rules for making a static library from C source files. Unlike 'staticLibR',
+-- this also creates rules for creating object files.
 cToLib :: CCompiler
        -> [FilePath] -- ^ C source files
        -> FilePattern -- ^ Static libary output
        -> CConfig
        -> Rules ()
 cToLib cc sources lib cfg =
-    mconcat [ foldr (>>) (pure ()) objRules
+    mconcat [ mconcat objRules
             , staticLibR cc (g sources) lib cfg
             ]
     where objRules = objectFileR cc cfg <$> g sources <*> pure lib
           g = fmap (-<.> "o")
 
+-- | Rules for generating a binary from C source files. At most one can have the
+-- @main@ function.
 cBin :: CCompiler
      -> [FilePath] -- ^ C source files
      -> FilePattern -- ^ Binary file output
      -> CConfig
      -> Rules ()
-cBin cc sources bin cfg = bin %> \out -> ccAction cc sources out cfg
-
--- HAVE:
--- .atspkg/lib
--- .atpskg/x86_64-unknown-redox/lib
--- .atspkg/0.3.10
---
--- WANT:
--- The ability to do cross builds w/ `atspkg install`
--- The ability to install `atslib` as a cross library
+cBin cc sources bin cfg = bin %> \out -> binaryA cc sources out cfg
 
-ccAction :: CmdResult r
+-- | This action builds a binary.
+binaryA :: CmdResult r
          => CCompiler
          -> [FilePath] -- ^ Source files
          -> FilePath -- ^ Binary file output
          -> CConfig
          -> Action r
-ccAction cc sources out cfg =
+binaryA cc sources out cfg =
     need sources >>
     (command [EchoStderr False] (ccToString cc) . (("-o" : out : sources) <>) . cconfigToArgs) cfg
 
 cconfigToArgs :: CConfig -> [String]
-cconfigToArgs (CConfig is ls ds es) = join [ mapFlags "-I" is, mapFlags "-l" ls, mapFlags "-L" ds, es ]
+cconfigToArgs (CConfig is ls ds es sl) = join [ mapFlags "-I" is, mapFlags "-l" (g sl <$> ls), mapFlags "-L" ds, es ]
+    where g :: Bool -> (String -> String)
+          g False = id
+          g True  = (":lib" <>) . (<> ".a")
 
+-- | These rules build a dynamic library (@.so@ on Linux).
 dynLibR :: CCompiler
-        -> [FilePath]
-        -> FilePattern
+        -> [FilePath] -- ^ C source files
+        -> FilePattern -- ^ Shared object file to be generated.
         -> CConfig
         -> Rules ()
 dynLibR cc objFiles shLib cfg =
@@ -136,6 +150,7 @@
         need objFiles >>
         command [EchoStderr False] (ccToString cc) ("-shared" : "-o" : out : objFiles <> cconfigToArgs cfg)
 
+-- | These rules build an object file from a C source file.
 objectFileR :: CCompiler
             -> CConfig
             -> FilePath -- ^ C source file
@@ -174,7 +189,7 @@
 sharedLibR cc objFiles shrLib cfg =
     shrLib %> \out -> sharedLibA cc objFiles out cfg
 
-staticLibR :: CCompiler -- ^ ar binary
+staticLibR :: CCompiler
            -> [FilePath] -- ^ Object files to be linked
            -> FilePattern -- ^ File pattern for static library outputs
            -> CConfig
diff --git a/src/Development/Shake/CCJS.hs b/src/Development/Shake/CCJS.hs
--- a/src/Development/Shake/CCJS.hs
+++ b/src/Development/Shake/CCJS.hs
@@ -1,7 +1,11 @@
+{-# LANGUAGE CPP #-}
+
 module Development.Shake.CCJS ( ccjs
                               ) where
 
+#if __GLASGOW_HASKELL__ < 804
 import           Data.Semigroup
+#endif
 import           Development.Shake
 import           Development.Shake.FilePath
 import           System.Directory           (createDirectoryIfMissing)
diff --git a/src/Development/Shake/Cabal.hs b/src/Development/Shake/Cabal.hs
--- a/src/Development/Shake/Cabal.hs
+++ b/src/Development/Shake/Cabal.hs
@@ -4,8 +4,11 @@
                                , getCabalDepsV
                                , getCabalDepsA
                                , shakeVerbosityToCabalVerbosity
+                               -- * Types
+                               , HsCompiler (..)
                                -- * Helper functions
                                , platform
+                               , hsCompiler
                                -- * Reëxports from "Distribution.Version"
                                , showVersion
                                ) where
@@ -18,7 +21,8 @@
 #if __GLASGOW_HASKELL__ < 804
 import           Data.Semigroup
 #endif
-import           Development.Shake                     as Shake
+import           Development.Shake                     hiding (doesFileExist)
+import qualified Development.Shake                     as Shake
 import           Distribution.ModuleName
 import           Distribution.PackageDescription
 import           Distribution.PackageDescription.Parse
@@ -26,21 +30,35 @@
 import           Distribution.Types.PackageId
 import           Distribution.Verbosity                as Distribution
 import           Distribution.Version
+import           System.Directory                      (doesFileExist)
 import           System.Info                           (arch, os)
 
+data HsCompiler = GHC { _suff :: Maybe String -- ^ Compiler version
+                      }
+                | GHCJS { _suff :: Maybe String -- ^ Compiler version
+                        }
+
+hsCompiler :: HsCompiler -> String
+hsCompiler (GHC Nothing)    = "ghc"
+hsCompiler (GHC (Just v))   = "ghc-" <> v
+hsCompiler (GHCJS Nothing)  = "ghcjs"
+hsCompiler (GHCJS (Just v)) = "ghcjs-" <> v
+
 -- | E.g. @x86_64-linux@
 platform :: String
 platform = arch ++ "-" ++ os
 
 libraryToFiles :: Library -> [FilePath]
-libraryToFiles lib = cs <> is <> ((<> ".hs") . toFilePath <$> explicitLibModules lib)
+libraryToFiles lib = mconcat [cs, is, hs]
     where (cs, is) = (cSources &&& includes) $ libBuildInfo lib
+          hs = (<> ".hs") . toFilePath <$> explicitLibModules lib
 
 extract :: CondTree a b Library -> [Library]
 extract (CondNode d _ []) = [d]
 extract (CondNode d _ bs) = d : (g =<< bs)
     where g (CondBranch _ tb fb) = join $ catMaybes [Just $ extract tb, extract <$> fb]
 
+-- | Assign each shake @Verbosity@ level to a Cabal @Verbosity@ level.
 shakeVerbosityToCabalVerbosity :: Shake.Verbosity -> Distribution.Verbosity
 shakeVerbosityToCabalVerbosity Silent     = silent
 shakeVerbosityToCabalVerbosity Quiet      = normal
@@ -49,6 +67,8 @@
 shakeVerbosityToCabalVerbosity Chatty     = verbose
 shakeVerbosityToCabalVerbosity Diagnostic = deafening
 
+-- | Get cabal dependencies, respecting verbosity level given to
+-- [shake](http://shakebuild.com/).
 getCabalDepsA :: FilePath -> Action (Version, [FilePath])
 getCabalDepsA = join . (g <$> fmap shakeVerbosityToCabalVerbosity getVerbosity <*>) . pure
     where g = liftIO .* getCabalDepsV
@@ -68,4 +88,6 @@
         normalSrc = (libraryToFiles <=< extract) =<< libs
         dir = (fmap (<> "/") . hsSourceDirs . libBuildInfo <=< extract) =<< libs
         dirge = ((<>) <$> dir <*>)
-    pure (vers, extraSrc <> dirge normalSrc)
+        h = filterM doesFileExist
+    norms <- h (dirge normalSrc)
+    pure (vers, extraSrc <> norms)
diff --git a/src/Development/Shake/Clean.hs b/src/Development/Shake/Clean.hs
--- a/src/Development/Shake/Clean.hs
+++ b/src/Development/Shake/Clean.hs
@@ -17,6 +17,6 @@
 cleanHaskell :: Action ()
 cleanHaskell =
     mapM_ (\p -> removeFilesAfter p ["//*"])
-        [ "dist", "dist-newstyle", ".stack-work", ".cabal-sandbox", "ats-deps" ] >>
+        [ "dist", "dist-newstyle", ".stack-work", ".cabal-sandbox" ] >>
     removeFilesAfter "."
         ["//*.o", "//*.ghc.*", "//*_stub.h", "//*.hi", "//*.dyn_o", "//*.p_o", "//*.dyn_hi", "//*.p_hi", "//*.hc", "cabal.sandbox.config"]
diff --git a/src/Development/Shake/Linters.hs b/src/Development/Shake/Linters.hs
--- a/src/Development/Shake/Linters.hs
+++ b/src/Development/Shake/Linters.hs
@@ -27,6 +27,7 @@
     contents <- liftIO $ readFile dh
     command [Stdin contents] "dhall" []
 
+-- join fmap f = f . f
 trim :: String -> String
 trim = join fmap f
    where f = reverse . dropWhile isSpace
