diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -7,11 +7,23 @@
 
 ## Installation
 
+### Script
+
 The easiest way to install is via a script, viz.
 
 ```bash
 curl -sSl https://raw.githubusercontent.com/vmchale/atspkg/master/bash/install.sh | bash -s
 ```
+
+Thereafter, you can run
+
+```bash
+atspkg upgrade
+```
+
+to upgrade to the latest release.
+
+### Source
 
 Alternately, you can download
 [Cabal](https://www.haskell.org/cabal/download.html) and
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -5,12 +5,12 @@
 import           Distribution.Types.HookedBuildInfo
 
 installActions :: IO ()
-installActions = foldr (>>) (pure ()) 
+installActions = foldr (>>) (pure ())
     [ writeManpages "man/atspkg.1" "atspkg.1"
     , writeTheFuck
     , writeBashCompletions "atspkg"
     ]
-    
+
 main :: IO ()
 main = defaultMainWithHooks $
     simpleUserHooks { preConf = \_ _ -> installActions >> pure emptyHookedBuildInfo }
diff --git a/ats-pkg.cabal b/ats-pkg.cabal
--- a/ats-pkg.cabal
+++ b/ats-pkg.cabal
@@ -1,5 +1,5 @@
 name:                ats-pkg
-version:             2.2.1.1
+version:             2.3.0.0
 synopsis:            A build tool for ATS
 description:         A collection of scripts to simplify building ATS projects.
 homepage:            https://github.com/vmchale/atspkg#readme
@@ -14,6 +14,7 @@
                    , docs/manual.tex
 extra-source-files:  stack.yaml
                    , man/atspkg.1
+                   , config.dhall
 cabal-version:       1.18
 
 Flag development {
@@ -39,6 +40,7 @@
                      , Language.ATS.Package.Build
                      , Language.ATS.Package.Upgrade
                      , Language.ATS.Package.Tools
+                     , Language.ATS.Package.PackageSet
   build-depends:       base >= 4.7 && < 5
                      , http-client
                      , bytestring
@@ -49,6 +51,7 @@
                      , text
                      , directory
                      , process
+                     , containers
                      , parallel-io
                      , unix
                      , lens
diff --git a/config.dhall b/config.dhall
new file mode 100644
--- /dev/null
+++ b/config.dhall
@@ -0,0 +1,5 @@
+let cfg = 
+  { defaultPkgs = "https://raw.githubusercontent.com/vmchale/atspkg/master/pkgs/pkg-set.dhall"
+  }
+
+in cfg
diff --git a/man/atspkg.1 b/man/atspkg.1
--- a/man/atspkg.1
+++ b/man/atspkg.1
@@ -36,6 +36,10 @@
 .PP
 \f[B]upgrade\f[] \- Download the latest binary release of
 \f[B]atspkg\f[], if available
+.PP
+\f[B]valgrind\f[] \- Run \f[B]valgrind\f[] on the generated binary
+.PP
+\f[B]run\f[] \- Run the generated binary
 .SS OPTIONS
 .TP
 .B \f[B]\-h\f[] \f[B]\-\-help\f[]
diff --git a/src/Language/ATS/Package.hs b/src/Language/ATS/Package.hs
--- a/src/Language/ATS/Package.hs
+++ b/src/Language/ATS/Package.hs
@@ -9,6 +9,8 @@
                             , upgradeAtsPkg
                             , fetchDeps
                             , getCCompiler
+                            , mkBuildPlan
+                            , buildHelper
                             -- * Types
                             , Version (..)
                             , Pkg (..)
@@ -16,6 +18,7 @@
                             , ATSConstraint (..)
                             , ATSDependency (..)
                             , TargetPair (..)
+                            , ATSPackageSet (..)
                             -- * Lenses
                             , dirLens
                             ) where
@@ -23,6 +26,7 @@
 import           Language.ATS.Package.Build
 import           Language.ATS.Package.Compiler
 import           Language.ATS.Package.Dependency
+import           Language.ATS.Package.PackageSet
 import           Language.ATS.Package.Tools
 import           Language.ATS.Package.Type
 import           Language.ATS.Package.Upgrade
diff --git a/src/Language/ATS/Package/Build.hs b/src/Language/ATS/Package/Build.hs
--- a/src/Language/ATS/Package/Build.hs
+++ b/src/Language/ATS/Package/Build.hs
@@ -193,11 +193,9 @@
 
         want [".atspkg/config"]
 
-        let gcV = Version [7,6,4]
-            atomicV = Version [7,6,2]
-            cdps = if any gcBin bs then libcAtomicOps atomicV : libcGC gcV : cds else cds
+        let cdps = if any gcBin bs then "gc" : cds else cds
 
-        liftIO $ fetchDeps False setup ds cdps False >> stopGlobalPool
+        liftIO $ fetchDeps setup (TL.unpack <$> ds) (TL.unpack <$> cdps) False >> stopGlobalPool
 
         let bins = TL.unpack . target <$> bs
         setTargets rs bins mt
diff --git a/src/Language/ATS/Package/Dependency.hs b/src/Language/ATS/Package/Dependency.hs
--- a/src/Language/ATS/Package/Dependency.hs
+++ b/src/Language/ATS/Package/Dependency.hs
@@ -2,9 +2,7 @@
 
 module Language.ATS.Package.Dependency ( -- * Functions
                                          fetchDeps
-                                       -- * Constants
-                                       , libcAtomicOps
-                                       , libcGC
+                                       , buildHelper
                                        ) where
 
 import qualified Codec.Archive.Tar                    as Tar
@@ -20,6 +18,7 @@
 import           Development.Shake.ATS
 import           Dhall
 import           Language.ATS.Package.Error
+import           Language.ATS.Package.PackageSet
 import           Language.ATS.Package.Type
 import           Network.HTTP.Client
 import           Network.HTTP.Client.TLS              (tlsManagerSettings)
@@ -28,27 +27,20 @@
 import           System.Posix.Files
 import           System.Process
 
-libcAtomicOps :: Version -> ATSDependency
-libcAtomicOps v = ATSDependency "atomic-ops" ("atomic-ops-" <> g v) ("https://github.com/ivmai/libatomic_ops/releases/download/v" <> g v <> "/libatomic_ops-" <> g v <> ".tar.gz") v
-    where g = TL.pack . show
-
-libcGC :: Version -> ATSDependency
-libcGC v = ATSDependency "gc" ("gc-" <> g v) ("https://github.com/ivmai/bdwgc/releases/download/v" <> g v <> "/gc-" <> g v <> ".tar.gz") v
-    where g = TL.pack . show
-
-fetchDeps :: Bool -- ^ Set to 'False' if unsure.
-          -> [IO ()] -- ^ Setup steps that can be performed concurrently
-          -> [ATSDependency] -- ^ ATS dependencies
-          -> [ATSDependency] -- ^ C Dependencies
+fetchDeps :: [IO ()] -- ^ Setup steps that can be performed concurrently
+          -> [String] -- ^ ATS dependencies
+          -> [String] -- ^ C Dependencies
           -> Bool -- ^ Whether to perform setup anyhow.
           -> IO ()
-fetchDeps b setup' deps cdeps b' =
+fetchDeps setup' deps cdeps b' =
     unless (null deps && null cdeps && b') $ do
+        deps' <- join <$> setBuildPlan "ats" deps
         putStrLn "Checking ATS dependencies..."
         d <- (<> "lib/") <$> pkgHome
-        let libs' = fmap (buildHelper b) deps
-            unpacked = fmap (over dirLens (TL.pack d <>)) cdeps
-            clibs = fmap (buildHelper b) unpacked
+        let libs' = fmap (buildHelper False) deps'
+        cdeps' <- join <$> setBuildPlan "c" cdeps
+        let unpacked = fmap (over dirLens (TL.pack d <>)) cdeps'
+            clibs = fmap (buildHelper False) unpacked
         parallel_ (setup' ++ libs' ++ clibs)
         mapM_ (setup (GCC Nothing Nothing)) unpacked
 
@@ -85,7 +77,7 @@
 setup :: CCompiler -- ^ C compiler to use
       -> ATSDependency -- ^ ATSDependency itself
       -> IO ()
-setup cc' (ATSDependency lib' dirName' _ _) = do
+setup cc' (ATSDependency lib' dirName' _ _ _) = do
     lib'' <- (<> TL.unpack lib') <$> pkgHome
     b <- doesFileExist lib''
     unless b $ do
@@ -110,7 +102,7 @@
     extractFilesFromArchive [options] (toArchive response)
 
 buildHelper :: Bool -> ATSDependency -> IO ()
-buildHelper b (ATSDependency lib' dirName' url'' _) = do
+buildHelper b (ATSDependency lib' dirName' url'' _ _) = do
 
     let (lib, dirName, url') = (lib', dirName', url'') & each %~ TL.unpack
 
diff --git a/src/Language/ATS/Package/Error.hs b/src/Language/ATS/Package/Error.hs
--- a/src/Language/ATS/Package/Error.hs
+++ b/src/Language/ATS/Package/Error.hs
@@ -2,6 +2,7 @@
 
 module Language.ATS.Package.Error ( -- * Helper functions
                                     unrecognized
+                                  , resolutionFailed
                                   ) where
 
 import           System.Exit
@@ -12,13 +13,18 @@
 unrecognized :: String -> IO a
 unrecognized = printErr . Unrecognized
 
-newtype PackageError = Unrecognized String
+resolutionFailed :: IO a
+resolutionFailed = printErr ResolutionFailed
 
+data PackageError = Unrecognized String
+                  | ResolutionFailed
+
 (<#>) :: Doc -> Doc -> Doc
 (<#>) a b = a <> line <> b
 
 instance Pretty PackageError where
-    pretty (Unrecognized t) = red "Error:" <> "Unrecognized archive format when unpacking" <#> hang 2 (text t)
+    pretty (Unrecognized t) = red "Error:" <+> "Unrecognized archive format when unpacking" <#> hang 2 (text t)
+    pretty ResolutionFailed = red "Error:" <+> "Package resolution failed.\n"
 
 -- TODO monaderror?
 printErr :: PackageError -> IO a
diff --git a/src/Language/ATS/Package/Exec.hs b/src/Language/ATS/Package/Exec.hs
--- a/src/Language/ATS/Package/Exec.hs
+++ b/src/Language/ATS/Package/Exec.hs
@@ -97,8 +97,8 @@
 
 fetchPkg :: String -> IO ()
 fetchPkg pkg = withSystemTempDirectory "atspkg" $ \p -> do
-    let (lib, dirName, url') = ("atspkg", p, pkg) & each %~ TL.pack
-    fetchDeps True mempty [ATSDependency lib dirName url' undefined] [] True
+    let (lib, dirName, url') = (mempty, p, pkg) & each %~ TL.pack
+    buildHelper True (ATSDependency lib dirName url' undefined mempty)
     ps <- getSubdirs p
     pkgDir <- fromMaybe p <$> findFile (p:ps) "atspkg.dhall"
     let a = withCurrentDirectory (takeDirectory pkgDir) (mkPkg False False mempty ["install"] Nothing 0)
diff --git a/src/Language/ATS/Package/PackageSet.hs b/src/Language/ATS/Package/PackageSet.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/ATS/Package/PackageSet.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE RecordWildCards            #-}
+
+module Language.ATS.Package.PackageSet ( ATSPackageSet (..)
+                                       , setBuildPlan
+                                       , mkBuildPlan
+                                       ) where
+
+import           Control.Arrow
+import           Control.Monad
+import           Data.Binary                (decode, encode)
+import           Data.Bool                  (bool)
+import qualified Data.ByteString.Lazy       as BSL
+import           Data.Dependency
+import qualified Data.Map                   as M
+import qualified Data.Set                   as S
+import qualified Data.Text.Lazy             as TL
+import           Dhall                      hiding (bool)
+import           Language.ATS.Package.Error
+import           Language.ATS.Package.Type
+import           System.Directory           (createDirectoryIfMissing, doesFileExist)
+
+-- TODO string instance? string :: Type String
+
+newtype ATSPackageSet = ATSPackageSet [ ATSDependency ]
+    deriving (Interpret, Show)
+
+setBuildPlan :: FilePath -- ^ Filepath for cache inside @.atspkg@
+             -> [String] -- ^ Libraries we want
+             -> IO [[ATSDependency]]
+setBuildPlan p deps = do
+    b <- doesFileExist depCache
+    bool setBuildPlan' (decode <$> BSL.readFile depCache) b
+
+    where depCache = ".atspkg/buildplan-" ++ p
+          setBuildPlan' = do
+            putStrLn "Resolving dependencies..."
+            pkgSet <- input auto "https://raw.githubusercontent.com/vmchale/atspkg/master/pkgs/pkg-set.dhall"
+            case mkBuildPlan pkgSet deps of
+                Just x  -> createDirectoryIfMissing True ".atspkg" >> BSL.writeFile depCache (encode x) >> pure x
+                Nothing -> resolutionFailed
+
+mkBuildPlan :: ATSPackageSet -> [String] -> Maybe [[ATSDependency]]
+mkBuildPlan aps@(ATSPackageSet ps) = finalize . resolve . fmap asDep <=< stringBuildPlan
+    where finalize = fmap (fmap (fmap (lookupVersions aps)))
+          resolve = resolveDependencies (atsPkgsToPkgs aps)
+          stringBuildPlan names = sequence [ lookup x libs | x <- names ]
+              where libs = (TL.unpack . libName &&& id) <$> ps
+
+asDep :: ATSDependency -> Dependency
+asDep ATSDependency{..} = Dependency (TL.unpack libName) mempty (TL.unpack <$> libDeps) libVersion
+
+atsPkgsToPkgs :: ATSPackageSet -> PackageSet Dependency
+atsPkgsToPkgs (ATSPackageSet deps) = PackageSet $ foldr (.) id inserts mempty
+    where inserts = insert <$> deps
+          insert dep = M.insertWith
+            (\_ -> S.insert (asDep dep))
+            (TL.unpack $ libName dep)
+            (S.singleton (asDep dep))
+
+lookupVersions :: ATSPackageSet -> Dependency -> ATSDependency
+lookupVersions (ATSPackageSet deps) (Dependency name _ _ v) = head (filter f deps)
+    where f = (&&) <$> matchName <*> matchVersion
+          libName' = TL.unpack . libName
+          matchName = (== name) . libName'
+          matchVersion = (== v) . libVersion
diff --git a/src/Language/ATS/Package/Type.hs b/src/Language/ATS/Package/Type.hs
--- a/src/Language/ATS/Package/Type.hs
+++ b/src/Language/ATS/Package/Type.hs
@@ -41,6 +41,7 @@
                                    , dir        :: Text -- ^ Directory we should unpack to
                                    , url        :: Text -- ^ Url pointing to tarball
                                    , libVersion :: Version
+                                   , libDeps    :: [Text] -- ^ Strings containing dependencies
                                    }
                 deriving (Eq, Show, Generic, Interpret, Binary)
 
@@ -70,8 +71,8 @@
                , man          :: Maybe Text -- ^ Optional (markdown) manpages to be converted using @pandoc@.
                , version      :: Version -- ^ Library version
                , compiler     :: Version -- ^ Compiler version
-               , dependencies :: [ATSDependency] -- ^ List of dependencies
-               , clib         :: [ATSDependency] -- ^ List of C dependencies
+               , dependencies :: [Text] -- ^ List of dependencies
+               , clib         :: [Text] -- ^ List of C dependencies
                , ccompiler    :: Text -- ^ The C compiler we should use
                , cflags       :: [Text] -- ^ List of flags to pass to the C compiler
                , atsSource    :: [Text] -- ^ Directory containing ATS source to be compile to C.
diff --git a/src/Language/ATS/Package/Upgrade.hs b/src/Language/ATS/Package/Upgrade.hs
--- a/src/Language/ATS/Package/Upgrade.hs
+++ b/src/Language/ATS/Package/Upgrade.hs
@@ -11,7 +11,7 @@
 import           Development.Shake.FilePath
 import           Network.HTTP.Client
 import           Network.HTTP.Client.TLS    (tlsManagerSettings)
-import           System.Directory           (createDirectoryIfMissing)
+import           System.Directory           (createDirectoryIfMissing, renameFile)
 import           System.Environment
 import           System.Info
 import           System.Posix.Files
@@ -48,5 +48,6 @@
 
     atsPath <- atspkgPath
     createDirectoryIfMissing True (takeDirectory atsPath)
-    BSL.writeFile atsPath binBytes
+    BSL.writeFile (atsPath ++ "-new") binBytes
+    renameFile (atsPath ++ "-new") atsPath
     setFileMode atsPath ownerModes
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -9,7 +9,7 @@
   - language-ats-0.2.0.0
   - cli-setup-0.2.0.1
   - hs2ats-0.2.1.3
-  - dependency-0.1.0.0
+  - dependency-0.1.0.3
   - ats-setup-0.3.0.2
 flags:
   ats-pkg:
