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:             1.0.0.0
+version:             1.1.0.0
 synopsis:            Helper functions for linting with shake 
 description:         This package provides several linters out of the box, as well as functionality for building ATS source files with [shake](http://shakebuild.com/).
 homepage:            https://hub.darcs.net/vmchale/shake-ext
diff --git a/src/Development/Shake/ATS.hs b/src/Development/Shake/ATS.hs
--- a/src/Development/Shake/ATS.hs
+++ b/src/Development/Shake/ATS.hs
@@ -22,7 +22,7 @@
 import           Development.Shake
 import           Development.Shake.FilePath
 import           Language.ATS
-import           System.Directory           (copyFile)
+import           System.Directory           (copyFile, createDirectoryIfMissing)
 import           System.Exit                (ExitCode (ExitSuccess))
 
 newtype Version = Version [Integer]
@@ -33,13 +33,14 @@
     show (Version (x:xs)) = show x ++ "." ++ show (Version xs)
 
 patsHome :: Action String
-patsHome = fromMaybe "/usr/local/lib/ats2-postiats-0.3.8" <$> mh
-    where mh = fmap (++ "/.atspkg/compiler/") <$> getEnv "HOME"
+patsHome = fromMaybe "/usr/local/lib/ats2-postiats-0.3.9" <$> mh
+    where mh = fmap (++ "/.atspkg/0.3.8/") <$> getEnv "HOME"
 
 -- TODO install the whole compiler?
 atsCommand :: CmdResult r => Version -> String -> String -> Action r
-atsCommand version sourceFile out = do
-    let home = "/usr/local/lib/ats2-postiats-" ++ show version
+atsCommand v sourceFile out = do
+    h <- patsHome
+    let home = h ++ "lib/ats2-postiats-" ++ show v
     let atsArgs = [EchoStderr False, AddEnv "PATSHOME" home]
         patsc = "patsopt"
     command atsArgs patsc ["--output", out, "-dd", sourceFile, "-cc"]
@@ -48,20 +49,33 @@
 gcFlag False = "-DATS_MEMALLOC_LIBC"
 gcFlag True  = "-DATS_MEMALLOC_GCBDW"
 
+copySources :: Version -> [FilePath] -> Action ()
+copySources v sources =
+    forM_ sources $ \dep -> do
+        h <- patsHome
+        let home = h ++ "lib/ats2-postiats-" ++ show v
+        liftIO $ createDirectoryIfMissing True (home ++ "/" ++ takeDirectory dep)
+        liftIO $ copyFile dep (home ++ "/" ++ dep)
+
 -- TODO musl?
 atsBin :: Version -> Bool -> [String] -> String -> String -> Rules ()
-atsBin v gc libs sourceFile out = do
-
-    atsDeps
+atsBin v gc libs sourceFile out =
 
     out %> \_ -> do
-        need [sourceFile]  --sources
-        let home = "/usr/local/lib/ats2-postiats-" ++ show v
+        sources <- transitiveDeps [sourceFile]
+        h <- patsHome
+        let home = h ++ "lib/ats2-postiats-" ++ show v
+        need sources
+        copySources v sources
         cmd_ ["mkdir", "-p", dropDirectory1 out]
+
         let toLibs = fmap ("-l" <>)
-        command [EchoStderr False, AddEnv "PATSHOME" home] "patscc" ([sourceFile, "-atsccomp", "gcc -flto -I/usr/local/lib/ats2-postiats-0.3.8/ccomp/runtime/ -I/usr/local/lib/ats2-postiats-0.3.8/", gcFlag gc, "-o", out, "-cleanaft", "-O2", "-mtune=native", "-flto"] <> toLibs libs)
+        command
+            [EchoStderr False, AddEnv "PATSHOME" home]
+            "patscc"
+            ([sourceFile, "-atsccomp", "gcc -flto -I" ++ h ++ "/ccomp/runtime/ -I" ++ h, gcFlag gc, "-o", out, "-cleanaft", "-O2", "-mtune=native", "-flto"] <> toLibs libs)
 
--- | Build a @.lats@ file.
+    -- | Build a @.lats@ file.
 lexAts :: Rules ()
 lexAts = priority 0.5 $
     "*.dats" %> \out -> do
@@ -79,44 +93,43 @@
         removeFilesAfter ".atspkg" ["//*"]
         removeFilesAfter "ats-deps" ["//*"]
 
+handleSource :: Version -> FilePath -> Action ()
+handleSource v sourceFile = do
+        sources <- transitiveDeps [sourceFile]
+        need sources
+        copySources v sources
+
 -- | This provides rules for generating C code from ATS source files in the
 -- @ats-src@ directory.
 cgen :: Version -> FilePath -> Rules ()
-cgen version dir = do
-
-    atsDeps
+cgen v dir =
 
     "//*.c" %> \out -> do
         let sourceFile = dir ++ "/" ++ (dropDirectory1 out -<.> "dats")
-        need [sourceFile]
-        atsCommand version sourceFile out
+        handleSource v sourceFile
+        atsCommand v sourceFile out
 
 trim :: String -> String
 trim = init . drop 1
 
-atsDeps :: Rules ()
-atsDeps =
-
-    ["//*.dats", "//*.sats"] |%> \out -> do
-        contents <- liftIO $ readFile out
-        let ats = fromRight mempty . parseATS . lexATS $ contents
-        deps <- filterM doesFileExist $ trim <$> getDependencies ats
-        need deps
-        home <- patsHome
-        forM_ deps $ \dep ->
-            liftIO $ copyFile dep (home ++ "/" ++ dep)
+transitiveDeps :: [FilePath] -> Action [FilePath]
+transitiveDeps [] = pure []
+transitiveDeps ps = fmap join $ forM ps $ \p -> do
+    contents <- liftIO $ readFile p
+    let ats = fromRight mempty . parseATS . lexATS $ contents
+    deps <- filterM doesFileExist $ trim <$> getDependencies ats
+    deps' <- transitiveDeps deps
+    pure $ (p:deps) ++ deps'
 
 -- | This uses @pats-filter@ to prettify the errors.
-cgenPretty :: Version -> Rules ()
-cgenPretty version = do
-
-    atsDeps
+cgenPretty :: Version -> FilePath -> Rules ()
+cgenPretty v dir =
 
     "//*.c" %> \out -> do
 
-        let sourceFile = "ats-src/" ++ (dropDirectory1 out -<.> "dats")
-        need [sourceFile]
-        (Exit c, Stderr err) :: (Exit, Stderr String) <- atsCommand version sourceFile out
+        let sourceFile = dir ++ "/" ++ (dropDirectory1 out -<.> "dats")
+        handleSource v sourceFile
+        (Exit c, Stderr err) :: (Exit, Stderr String) <- atsCommand v sourceFile out
         cmd_ [Stdin err] Shell "pats-filter"
         if c /= ExitSuccess
             then error "patscc failure"
