diff --git a/shake-ext.cabal b/shake-ext.cabal
--- a/shake-ext.cabal
+++ b/shake-ext.cabal
@@ -1,5 +1,5 @@
 name:                shake-ext
-version:             2.3.0.1
+version:             2.4.0.0
 synopsis:            Helper functions for linting with shake 
 description:         This package provides several linters out of the box, for use with [shake](http://shakebuild.com/).
 homepage:            https://hub.darcs.net/vmchale/shake-ext
@@ -32,7 +32,6 @@
   other-modules:       Development.Shake.TH
   build-depends:       base >= 4.10 && < 5
                      , shake
-                     , language-ats >= 0.1.1.3
                      , mtl
                      , composition-prelude
                      , directory
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,11 +1,149 @@
-module Development.Shake.C ( staticLib
-                           -- , objectFile
-                           -- , dynLib
+{-# LANGUAGE PatternSynonyms #-}
+
+module Development.Shake.C ( -- * Types
+                             CConfig (..)
+                           , CCompiler (GCC, Clang, GHC, Other, GCCStd, GHCStd)
+                           -- * Rules
+                           , staticLibR
+                           , objectFileR
+                           , dynLibR
+                           , cBin
+                           , cToLib
+                           -- * Actions
+                           , ccAction
+                           , staticLibA
+                           -- * Helper functions
+                           , cconfigToArgs
+                           , ccToString
+                           , ccFromString
+                           , host
                            ) where
 
+import           Control.Monad
+import           Data.List                  (isSuffixOf)
+import           Data.Semigroup
 import           Development.Shake
+import           Development.Shake.FilePath
+import           System.Info
 
-staticLib :: [FilePath] -> FilePattern -> Rules ()
-staticLib objFiles stalib =
-    stalib %> \out ->
-        command mempty "ar" ("rcs" : out : objFiles)
+mkQualified :: Monoid a => Maybe a -> a -> a
+mkQualified suff = h (g <$> [suff])
+    where g = maybe id mappend
+          h = foldr fmap id
+
+host :: String
+host = arch ++ withManufacturer os
+    where withManufacturer "darwin" = "-apple-" ++ os
+          withManufacturer _        = "-unknown-" ++ os
+
+pattern GCCStd :: CCompiler
+pattern GCCStd = GCC Nothing
+
+pattern GHCStd :: CCompiler
+pattern GHCStd = GHC Nothing
+
+ccToString :: CCompiler -> String
+ccToString Clang     = "clang"
+ccToString (Other s) = s
+ccToString (GCC pre) = mkQualified pre "gcc"
+ccToString (GHC pre) = mkQualified pre "ghc"
+
+arToString :: CCompiler -> String
+arToString (GCC pre) = mkQualified pre "ar"
+arToString (GHC pre) = mkQualified pre "ar"
+arToString _         = "ar"
+
+ccFromString :: String -> CCompiler
+ccFromString "gcc" = GCC Nothing
+ccFromString "clang" = Clang
+ccFromString "ghc" = GHC Nothing
+ccFromString s
+    | "gcc" `isSuffixOf` s = GCC (Just (reverse . drop 3 . reverse $ s))
+    | "ghc" `isSuffixOf` s = GHC (Just (reverse . drop 3 . reverse $ s))
+ccFromString _ = GCC Nothing
+
+data CCompiler = GCC { _prefix :: Maybe String }
+               | Clang
+               | Other String
+               | GHC { _prefix :: Maybe 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
+                       }
+
+-- | Rules for making a static library from C source files
+cToLib :: CCompiler
+       -> [FilePath] -- ^ C source files
+       -> FilePattern -- ^ Static libary output
+       -> CConfig
+       -> Rules ()
+cToLib cc sources lib cfg =
+    mconcat [ foldr (>>) (pure ()) objRules
+            , staticLibR cc (g sources) lib cfg
+            ]
+    where objRules = objectFileR cc <$> g sources <*> pure lib <*> pure cfg
+          g = fmap (-<.> "o")
+
+cBin :: CCompiler
+     -> [FilePath] -- ^ C source files
+     -> FilePattern -- ^ Binary file output
+     -> CConfig
+     -> Rules ()
+cBin cc sources bin cfg = bin %> \out -> ccAction cc sources out cfg
+
+ccAction :: CmdResult r
+         => CCompiler
+         -> [FilePath] -- ^ Source files
+         -> FilePath -- ^ Binary file output
+         -> CConfig
+         -> Action r
+ccAction 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 ]
+
+dynLibR :: CCompiler
+        -> [FilePath]
+        -> FilePattern
+        -> CConfig
+        -> Rules ()
+dynLibR cc objFiles shLib cfg =
+    shLib %> \out ->
+        need objFiles >>
+        command mempty (ccToString cc) ("-shared" : "-o" : out : objFiles <> cconfigToArgs cfg)
+
+objectFileR :: CCompiler
+            -> FilePath -- ^ C source file
+            -> FilePattern -- ^ Object file output
+            -> CConfig
+            -> Rules ()
+objectFileR cc srcFile objFile cfg =
+    objFile %> \out ->
+        need [srcFile] >>
+        command mempty (ccToString cc) (srcFile : "-c" : "-fPIC" : "-o" : out : cconfigToArgs cfg)
+
+staticLibA :: CmdResult r
+           => CCompiler
+           -> [FilePath] -- ^ Object files to be linked
+           -> FilePattern -- ^ File pattern for static library outputs
+           -> CConfig
+           -> Action r
+staticLibA ar objFiles stalib _ =
+    need objFiles >>
+    command mempty (arToString ar) ("rcs" : stalib : objFiles)
+
+staticLibR :: CCompiler -- ^ ar binary
+           -> [FilePath] -- ^ Object files to be linked
+           -> FilePattern -- ^ File pattern for static library outputs
+           -> CConfig
+           -> Rules ()
+staticLibR ar objFiles stalib cfg =
+    stalib %> \out -> staticLibA ar objFiles out cfg
diff --git a/src/Development/Shake/TH.hs b/src/Development/Shake/TH.hs
--- a/src/Development/Shake/TH.hs
+++ b/src/Development/Shake/TH.hs
@@ -32,7 +32,7 @@
     where expr = VarE 'commonVersion `AppE` (LitE $ StringL s)
 
 mkVersions :: [String] -> Q [Dec]
-mkVersions = pure . (=<<) g
+mkVersions = pure . (g =<<)
     where g s = [mkVersion s, mkSigVersion s]
 
 mkSig :: String -> Dec
