diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,23 @@
+# 2.3.2 (2026-02-19)
+- 'spec': use %ghc_lib_install -m if no modules
+- 'spec': also generate zsh and fish completion files
+- 'spec': also use missingOthers for non-hs deps
+- 'spec': for standalone .cabal SOURCE, don't offset by subpkgs
+- 'spec': move Cabal BR after BR ghc-rpm-macros
+- 'update': early krb and better version/release logic for dist-git & autorelease
+- Dependencies withGhcProfLibType: check for ghc-rpm-macros-quick
+- PackageUtils repoquery: drop --cacheonly
+- Stackage: default to lts-24
+- pkgInstallMissing' now takes yes parameter
+- use simple-cabal-0.2.1
+
+# 2.3.1 (unreleased)
+- PackageUtils: no longer use sudo for repoquery
+- Dependencies: add ghc-internal to excludedPkgs
+- Spec: add exposeOrReexportModules since tar-0.6 only reexports now
+- use fedora-krb
+- put html-entities behind a Cabal flag
+
 # 2.3.0 (2025-02-23)
 - refactor all head/tail usage to safe functions (headMay and tailSafe)
 - spec: explicit url
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -72,7 +72,7 @@
 `$ cabal-rpm --version`
 
 ```
-2.3.0
+2.3.2
 ```
 `$ cabal-rpm --help`
 
@@ -101,6 +101,33 @@
   missingdeps              List dependencies not available
   refresh                  Refresh spec file to latest packaging
   update                   Update package to latest version
+```
+
+### `spec` command help
+`$ cabal-rpm spec --help`
+
+```
+Usage: cabal-rpm spec [-m|--ignore-missing] [-q|--quiet]
+                      [-f|--flag "flag1 -flag2 ..."] [-T|--no-tests]
+                      [(-t|--standalone) | (-b|--binary)] [-S|--subpackage]
+                      [-w|--with-ghc VERSION] [-s|--stream STREAM] [PKG[VER]]
+
+  Generate a spec file
+
+Available options:
+  -m,--ignore-missing      Don't check for deps of missing deps
+  -q,--quiet               Silence Cabal
+  -f,--flag "flag1 -flag2 ..."
+                           Set or disable Cabal flags
+  -T,--no-tests            Disable test-suite (even if deps available)
+  -t,--standalone          Create a standalone package that uses cabal-install
+                           to build and install
+  -b,--binary              Make the base package name to be the Haskell package
+                           name
+  -S,--subpackage          Subpackage missing Haskell dependencies
+  -w,--with-ghc VERSION    ghc compiler version
+  -s,--stream STREAM       Stackage stream or Hackage
+  -h,--help                Show this help text
 ```
 
 ## Installation
diff --git a/cabal-rpm.cabal b/cabal-rpm.cabal
--- a/cabal-rpm.cabal
+++ b/cabal-rpm.cabal
@@ -1,6 +1,6 @@
 Cabal-version:       1.18
 Name:                cabal-rpm
-Version:             2.3.0
+Version:             2.3.2
 Synopsis:            RPM packaging tool for Haskell Cabal-based packages
 Description:
     This package provides a RPM packaging tool for Haskell Cabal-based
@@ -24,14 +24,15 @@
                      Bryan O'Sullivan <bos@serpentine.com>
 Maintainer:          Jens Petersen <petersen@fedoraproject.org>
 Copyright:           2007-2008 Bryan O'Sullivan <bos@serpentine.com>,
-                     2012-2024 Jens Petersen <juhpetersen@gmail.com>
+                     2012-2026 Jens Petersen <juhpetersen@gmail.com>
 Category:            Distribution
 Build-type:          Simple
 Extra-doc-files:     ChangeLog.md README.md TODO
 Tested-with:         GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4,
                      GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7,
                      GHC == 9.0.2, GHC == 9.2.8, GHC == 9.4.8,
-                     GHC == 9.6.4, GHC == 9.8.2
+                     GHC == 9.6.7, GHC == 9.8.4, GHC == 9.10.3,
+                     GHC == 9.12.3
 
 source-repository head
   type:     git
@@ -41,6 +42,10 @@
   Description:   Use curl library to query Stackage instead of http-client
   Default:       False
 
+Flag html-entities
+  Description:   Use html-entities library to decode descriptions
+  Default:       True
+
 Executable cabal-rpm
     Main-is:            Main.hs
     Build-depends: base < 5,
@@ -49,11 +54,11 @@
                    cached-json-file,
                    directory,
                    extra,
+                   fedora-krb,
                    filepath >= 1.4,
-                   html-entities,
                    http-query,
                    safe,
-                   simple-cabal >= 0.1.3,
+                   simple-cabal >= 0.2.1,
                    simple-cmd >= 0.2.3,
                    simple-cmd-args >= 0.1.7,
                    time >= 1.5,
@@ -68,7 +73,10 @@
     else
        Build-Depends: curl
        Cpp-options: -DCURL
-    Default-Language:    Haskell2010
+    if flag(html-entities)
+       Build-Depends: html-entities
+       Cpp-options: -DHTML_ENTITIES
+    Default-Language: Haskell2010
     Other-modules:
                   Commands.BuildDep,
                   Commands.Depends,
diff --git a/src/Commands/RpmBuild.hs b/src/Commands/RpmBuild.hs
--- a/src/Commands/RpmBuild.hs
+++ b/src/Commands/RpmBuild.hs
@@ -38,7 +38,7 @@
 rpmBuild stage quiet flags pkgtype subpackage mpvs = do
   pkgdata <- prepare flags Nothing mpvs
   when (stage == Binary) $
-    void $ pkgInstallMissing' pkgdata
+    void $ pkgInstallMissing' True pkgdata
   let pkgDesc = packageDesc pkgdata
       mspec = specFilename pkgdata
   specFile <- maybe (createSpecFile False normal flags False False False pkgtype (if subpackage then Just Nothing else Nothing) Nothing Nothing mpvs)
@@ -47,7 +47,6 @@
   let pkgid = package pkgDesc
   bringTarball pkgid (Just specFile)
   rpmbuild quiet stage specFile
-
   return specFile
 
 rpmBuild_ :: RpmStage -> Bool -> Flags -> PackageType -> Bool
diff --git a/src/Commands/Spec.hs b/src/Commands/Spec.hs
--- a/src/Commands/Spec.hs
+++ b/src/Commands/Spec.hs
@@ -3,11 +3,9 @@
 -- |
 -- Module      :  Commands.Spec
 -- Copyright   :  (C) 2007-2008  Bryan O'Sullivan
---                (C) 2012-2020  Jens Petersen
+--                (C) 2012-2025  Jens Petersen
 --
 -- Maintainer  :  Jens Petersen <petersen@fedoraproject.org>
--- Stability   :  alpha
--- Portability :  portable
 --
 -- Explanation: Generates an RPM spec file from a .cabal file.
 
@@ -29,7 +27,7 @@
 import PackageUtils (builtExecs, dependencySortCabals, PackageData (..),
                      packageMacro, prepare)
 import SimpleCabal (mkPackageName, PackageDescription (..),
-                    PackageIdentifier(..))
+                    PackageIdentifier(..), unUnqualComponentName)
 import SimpleCmd ((+-+), cmd, cmdLines, cmdMaybe, grep, grep_, removePrefix)
 import Types
 
@@ -42,15 +40,18 @@
 import Data.Char        (toUpper)
 import Data.List.Extra
 import Data.Maybe       (isJust, isNothing, fromMaybe, fromJust)
+#ifdef HTML_ENTITIES
 import qualified Data.Text as T
 import qualified Data.Text.Lazy as TL
 import qualified Data.Text.Lazy.Builder as TLB
+#endif
 import Data.Time.Clock  (getCurrentTime)
 import Data.Time.Format (defaultTimeLocale, formatTime)
 import qualified Data.Version as V
 
 import Distribution.PackageDescription (
-                                        Library (exposedModules),
+                                        Library (exposedModules,
+                                                 reexportedModules),
                                         hasExes, hasLibs,
 #if MIN_VERSION_Cabal(2,2,0)
                                         license,
@@ -58,26 +59,23 @@
                                        )
 import Distribution.Simple.Utils (warn)
 import Distribution.Text (display)
-#if MIN_VERSION_Cabal(2,0,0)
-import Distribution.Types.UnqualComponentName (unUnqualComponentName)
+#if MIN_VERSION_Cabal(3,14,0)
+import Distribution.Utils.Path (interpretSymbolicPath)
 #endif
 #if MIN_VERSION_Cabal(3,2,0)
 import qualified Distribution.Utils.ShortText as ST (fromShortText)
 #endif
 import Distribution.Verbosity (Verbosity)
 
-import qualified HTMLEntities.Decoder as HD
+#ifdef HTML_ENTITIES
+import HTMLEntities.Decoder (htmlEncodedText)
+#endif
 import System.Directory (doesFileExist)
 import System.IO     (IOMode (..), hClose, hPutStrLn, openFile)
 import System.FilePath (takeBaseName, takeFileName, (</>), (<.>))
 
 import qualified Paths_cabal_rpm (version)
 
-#if !MIN_VERSION_Cabal(2,0,0)
-unUnqualComponentName :: String -> String
-unUnqualComponentName = id
-#endif
-
 -- FIXME use datatype for options
 createSpecFile :: Bool -> Verbosity -> Flags -> Bool -> Bool -> Bool
                -> PackageType -> Maybe (Maybe Stream) -> Maybe V.Version
@@ -141,8 +139,14 @@
   let hasExec = hasExes pkgDesc
       hasLib = hasLibs pkgDesc
       hasLibPkg = hasLib && not standalone
-      dupdocs = docs `intersect` dataFiles pkgDesc
-      datafiles = dataFiles pkgDesc \\ dupdocs
+      dataFiles' =
+#if MIN_VERSION_Cabal(3,14,0)
+        map (interpretSymbolicPath Nothing) .
+#endif
+         dataFiles
+      origdatafiles = dataFiles' pkgDesc
+      dupdocs = docs `intersect` origdatafiles
+      datafiles = origdatafiles \\ dupdocs
       ghc_name = if isJust mwithghc then "%{ghc_name}" else "ghc"
       majorVer = V.showVersion . V.makeVersion . take 2 . V.versionBranch
       ghcname = "ghc" ++ maybe "" majorVer mwithghc
@@ -341,22 +345,24 @@
   putNewline
   put "# Begin cabal-rpm deps:"
   when revisedDOS $ putHdr "BuildRequires" "dos2unix"
-  when (mkPackageName "Cabal" `notElem` buildDeps pkgdeps || not hasLib || notNull (setupDeps pkgdeps)) $ do
---    put "# Setup"
-    unless (mkPackageName "Cabal" `elem` buildDeps pkgdeps) $
-      putHdr "BuildRequires" $ ghc_name ++ "-Cabal-devel"
-    mapM_ (\d -> (if d `elem` map pkgName subpkgs then putHdrComment else putHdr) "BuildRequires" (showRpm (RpmHsLib Devel d))) $ setupDeps pkgdeps
   putHdr "BuildRequires" $ "ghc-rpm-macros" ++ (if hasSubpkgs then "-extra" else "")
+  when (mkPackageName "Cabal" `notElem` buildDeps pkgdeps && isNothing mwithghc) $
+    putHdr "BuildRequires" $ showRpm $ RpmHsLib Devel $ mkPackageName "Cabal"
 
   unless (null (buildDeps pkgdeps)) $ do
 --    put "# Build"
     when (isJust mwithghc) $ do
       put "%if %{defined ghc_name}"
       putHdr "BuildRequires" $ "%{ghc_name}" ++ "-devel"
-      unless standalone $
+      unless standalone $ do
+        put "%if %{with ghc_prof}"
         putHdr "BuildRequires" $ "%{ghc_name}" ++ "-prof"
+        put "%endif"
       put "%else"
 
+    when (mkPackageName "Cabal" `notElem` buildDeps pkgdeps || not hasLib || notNull (setupDeps pkgdeps)) $ do
+      -- put "# Setup"
+      mapM_ (\d -> (if d `elem` map pkgName subpkgs then putHdrComment else putHdr) "BuildRequires" (showRpm (RpmHsLib Devel d))) $ setupDeps pkgdeps
     let metaPackages = [mkPackageName "haskell-gi-overloading"]
     mapM_ (\d -> (if d `elem` map pkgName subpkgs then putHdrComment else putHdr) "BuildRequires" (showRpm (RpmHsLib Devel d))) $ sort $ buildDeps pkgdeps
     -- FIXME should tracks devel/prof deps finely when subpackaging
@@ -364,19 +370,16 @@
       put "%if %{with ghc_prof}"
       mapM_ (\d -> (if d `elem` map pkgName subpkgs then putHdrComment else putHdr) "BuildRequires" (showRpm (RpmHsLib Prof d))) $ sort $ buildDeps pkgdeps \\ metaPackages
       put "%endif"
-  let otherdeps = sort $ toolDeps pkgdeps ++ clibDeps pkgdeps ++ pkgcfgDeps pkgdeps
-  unless (null otherdeps) $ do
---    put "# Other"
-    missingOthers <- missingOtherPkgs pkgDesc
-    mapM_ (\d -> (if d `elem` missingOthers then putHdrComment else putHdr) "BuildRequires" d) otherdeps
+  missingOthers <- missingOtherPkgs pkgDesc
+  mapM_ (\d -> (if d `elem` missingOthers then putHdrComment else putHdr) "BuildRequires" d) $ sort $ toolDeps pkgdeps
   let testDeps = testsuiteDeps \\ (mkPackageName "Cabal" : (buildDeps pkgdeps ++ setupDeps pkgdeps))
   when (testable && notNull testDeps) $ do
     put "%if %{with tests}"
     mapM_ (putHdr "BuildRequires") $ (sort . map showRpm) (map (RpmHsLib Devel) testDeps ++ map RpmOther (testsuiteTools \\ toolDeps pkgdeps))
     put "%endif"
-
   when (isJust mwithghc) $
     put "%endif"
+  mapM_ (\d -> (if d `elem` missingOthers then putHdrComment else putHdr) "BuildRequires" d) $ sort $ clibDeps pkgdeps ++ pkgcfgDeps pkgdeps
   let usesOptparse = hasExecPkg && any ((`elem` buildDeps pkgdeps) . mkPackageName) ["optparse-applicative","optparse-simple","simple-cmd-args"]
   when (usesOptparse && null manpages) $
     putHdr "BuildRequires" "help2man"
@@ -425,9 +428,9 @@
 
   -- haskell-gi generates lib source files at configure time
   -- (strictly should also check for otherModules (autogenModules?)
-  --  but libraries wihout exposedModules should be useless/redundant)
+  --  but libraries without exposedModules should be useless/redundant)
   let hasModules =
-        hasLib && (isJust (library pkgDesc) && (notNull . exposedModules . fromJust . library) pkgDesc || mkPackageName "haskell-gi" `elem` (buildDeps pkgdeps ++ setupDeps pkgdeps))
+        hasLib && (isJust (library pkgDesc) && (exposeOrReexportModules . fromJust . library) pkgDesc || mkPackageName "haskell-gi" `elem` (buildDeps pkgdeps ++ setupDeps pkgdeps))
       baselibpkg = if binlib then ghc_name ++ "-%{name}" else "%{name}"
 
   when hasLibPkg $ do
@@ -499,7 +502,7 @@
   when revised $
     put $ (if revisedDOS
            then "dos2unix -k -n" else "cp -bp")
-          +-+ "%{SOURCE" ++ show (1 + length subpkgs) ++ "}" +-+ pkg_name <.> "cabal"
+          +-+ "%{SOURCE" ++ show (1 + if standalone then 0 else length subpkgs) ++ "}" +-+ pkg_name <.> "cabal"
   when autopatch $
     put "%autopatch -p1"
   put "# End cabal-rpm setup"
@@ -540,7 +543,7 @@
   else do
     when hasSubpkgs $
       put "%ghc_libs_install %{subpkgs}"
-    put $ "%ghc_" ++ pkgType ++ "_install"
+    put $ "%ghc_" ++ pkgType ++ "_install" +-+ if hasLibPkg && not hasModules then "-m" else ""
 
     unless (null dupdocs) $ do
       putNewline
@@ -559,22 +562,24 @@
   let execs = builtExecs pkgDesc
       execNaming p = let pn = unUnqualComponentName p in
                      if pn == name then "%{name}" else pn
-      -- FIXME check for included file
-      maybeGenerateBashCompletion exn =
+      maybeGenerateCompletions exn = do
         put $ "%{buildroot}%{_bindir}" </> exn +-+ "--bash-completion-script" +-+ exn +-+ "| sed s/filenames/default/ >" +-+ "%{buildroot}%{bash_completions_dir}" </> exn
+        put $ "%{buildroot}%{_bindir}" </> exn +-+ "--fish-completion-script" +-+ exn +-+ ">" +-+ "%{buildroot}%{fish_completions_dir}" </> exn
+        put $ "%{buildroot}%{_bindir}" </> exn +-+ "--zsh-completion-script" +-+ exn +-+ "| sed s/filenames/default/ >" +-+ "%{buildroot}%{zsh_completions_dir}" </> '_' : exn
       generateManpage exn =
         put $ "help2man --no-info %{buildroot}%{_bindir}" </> exn +-+ ">" +-+ "%{buildroot}%{_mandir}/man1" </> exn <.> "1"
 
   when usesOptparse $ do
     putNewline
+    -- try to avoid overwriting included files
     put "set noclobber"
     put "mkdir -p %{buildroot}%{bash_completions_dir}"
-    -- FIXME convert to for loop
-    mapM_ (maybeGenerateBashCompletion . execNaming) execs
+    put "mkdir -p %{buildroot}%{fish_completions_dir}"
+    put "mkdir -p %{buildroot}%{zsh_completions_dir}"
+    mapM_ (maybeGenerateCompletions . execNaming) execs
     when (null manpages) $ do
       putNewline
       put "mkdir -p %{buildroot}%{_mandir}/man1/"
-      -- FIXME convert to for loop
       mapM_ (generateManpage . execNaming) execs
   unless (null manpages) $ do
     putNewline
@@ -610,6 +615,8 @@
       put $ "%{_datadir}" </> pkgver
     when usesOptparse $ do
       mapM_ (put . ("%{bash_completions_dir}" </>) . execNaming) execs
+      mapM_ (put . ("%{fish_completions_dir}" </>) . execNaming) execs
+      mapM_ (put . ("%{zsh_completions_dir}" </>) . ('_' :) . execNaming) execs
       when (null manpages) $
         mapM_ (put . (\e -> "%{_mandir}/man1" </> e <.> "1*") . execNaming) execs
     unless (null manpages) $
@@ -737,4 +744,12 @@
 
 htmlEntityDecode :: String -> String
 htmlEntityDecode =
-  TL.unpack . TLB.toLazyText . HD.htmlEncodedText . T.pack
+#ifdef HTML_ENTITIES
+  TL.unpack . TLB.toLazyText . htmlEncodedText . T.pack
+#else
+  id
+#endif
+
+exposeOrReexportModules :: Library -> Bool
+exposeOrReexportModules lib =
+  notNull (exposedModules lib) || notNull (reexportedModules lib)
diff --git a/src/Commands/Update.hs b/src/Commands/Update.hs
--- a/src/Commands/Update.hs
+++ b/src/Commands/Update.hs
@@ -30,13 +30,13 @@
 import Control.Applicative ((<$>))
 #endif
 import Control.Monad.Extra
-import Data.List.Extra
 import Data.Maybe
 import Distribution.Text (display)
 import Distribution.Verbosity (silent)
+import Fedora.Krb (krbTicket)
 import SimpleCabal (customFieldsPD, package,
                     PackageIdentifier (..), showVersion)
-import SimpleCmd (cmd, cmd_, error', grep_, shell_, (+-+))
+import SimpleCmd (cmd_, error', grep_, shell_, (+-+))
 import SimpleCmd.Git (grepGitConfig, rwGitDir)
 import System.Directory (createDirectoryIfMissing, doesDirectoryExist,
                          removeDirectoryRecursive, renameFile)
@@ -105,30 +105,31 @@
           unless autorelease $ do
             editSpecField "Release" (defrelease ++ suffix) spec
           patchSpec False Nothing curspec newspec
+          rwGit <- rwGitDir
+          distgit <- grepGitConfig "\\(pkgs\\|src\\)."
           ver' <- readVersion <$> getSpecField "Version" spec
-          when (ver' /= newver) $
+          when (ver' /= newver) $ do
+            when (rwGit && distgit) krbTicket
             editSpecField "Version" (showVersion newver) spec
           unless autorelease $
             if updated && not subpkg
             then editSpecField "Release" (defrelease ++ suffix) spec
             else editSpecField "Release" (currel ++ suffix) spec
-          rwGit <- rwGitDir
           autochangelog <- grep_ "^%autochangelog" spec
           when updated $ do
             -- FIXME reset when all subpkgs updated
-            unless (subpkg || autorelease) $
-              editSpecField "Release" ("0" ++ suffix) spec
+            unless subpkg $
+              editSpecField "Release" (if autorelease then "%autorelease" else "0" ++ suffix) spec
             unless autochangelog $
               cmd_ "rpmdev-bumpspec" ["-c", "https://hackage.haskell.org/package/" ++ display newPkgId ++ "/changelog" , spec]
             when (rwGit && subpkg) $ do
               cmd_ "cp" ["-p", "sources", "sources.cblrpm"]
               cmd_ "sed" ["-i", "/" ++ display oldPkgId <.> "tar.gz" ++ "/d", "sources.cblrpm"]
+          when (updated || subpkg) $
             bringTarball newPkgId (Just spec)
-          distgit <- grepGitConfig "\\(pkgs\\|src\\)."
           when (rwGit && distgit) $ do
             if updated
               then do
-              krbTicket
               cmd_ "fedpkg" ["new-sources", display newPkgId <.> "tar.gz"]
               when subpkg $ do
                 shell_ $ "cat sources >>" +-+ "sources.cblrpm"
@@ -160,14 +161,3 @@
       when direxists $ removeDirectoryRecursive dir
       createDirectoryIfMissing True dir
       createSpecFile False silent [] (not revise) False False (SpecFile spec) subpkgStream Nothing (Just dir) (streamPkgToPVS Nothing (Just pkgid))
-
-krbTicket :: IO ()
-krbTicket = do
-  krb <- words . fromMaybe "" . find ("@FEDORAPROJECT.ORG" `isInfixOf`) . lines <$> cmd "klist" ["-l"]
-  if null krb
-    then error' "No krb5 ticket found for FEDORAPROJECT.ORG"
-    else
-    when (last krb == "(Expired)") $ do
-      putStrLn $ unwords krb
-      cmd_ "fkinit" []
-      putStrLn ""
diff --git a/src/Dependencies.hs b/src/Dependencies.hs
--- a/src/Dependencies.hs
+++ b/src/Dependencies.hs
@@ -38,7 +38,6 @@
   ) where
 
 import PackageUtils (PackageData(..), prepare, repoquery, rpmInstall)
-import SysCmd (rpmEval)
 import Types
 
 #if !MIN_VERSION_base(4,8,0)
@@ -47,7 +46,7 @@
 import Control.Monad (filterM, when, unless)
 
 import Data.List (delete, isSuffixOf, nub, (\\))
-import Data.Maybe (catMaybes, fromJust, fromMaybe, isJust, isNothing, mapMaybe)
+import Data.Maybe (catMaybes, fromJust, fromMaybe, isNothing, mapMaybe)
 
 #if !MIN_VERSION_Cabal(2,2,0)
 import Distribution.License (License (..))
@@ -63,11 +62,9 @@
 import Distribution.Types.ExeDependency (ExeDependency(..))
 #endif
 import Safe (headMay)
-import SimpleCabal (allLibraries, buildDependencies, mkPackageName,
-                    exeDepName, Library(..),
-                    PackageDescription (package),
-                    PackageIdentifier(..),
-                    PackageName, pkgcfgDepName, pkgName,
+import SimpleCabal (allLibraries, buildDependencies, mkPackageName, exeDepName,
+                    Library(..), PackageDescription(package),
+                    PackageIdentifier(..), PackageName, pkgcfgDepName, pkgName,
                     setupDependencies, testsuiteDependencies,
 #if !MIN_VERSION_Cabal(2,2,0)
                     showVersion,
@@ -83,7 +80,13 @@
 
 excludedPkgs :: PackageName -> Bool
 excludedPkgs =
-  flip notElem $ map mkPackageName ["ghc-prim", "integer-gmp", "rts", "system-cxx-std-lib"]
+  -- base depends on ghc-internal and ghc-prim
+  -- - ghc-prim depends on rts
+  -- - ghc-internal depends on ghc-bignum, ghc-prim, rts
+  -- system-cxx-std-lib meta-pkg provided by ghc/mk/hadrian
+  flip notElem $
+  map mkPackageName
+  ["ghc-internal", "ghc-prim", "integer-gmp", "rts", "system-cxx-std-lib"]
 
 excludedTools :: String -> Bool
 excludedTools n =
@@ -273,10 +276,10 @@
 pkgInstallMissing :: Flags -> Maybe PackageVersionSpecifier -> IO [PackageName]
 pkgInstallMissing flags mpvs = do
   pkgdata <- prepare flags Nothing mpvs
-  pkgInstallMissing' pkgdata
+  pkgInstallMissing' True pkgdata
 
-pkgInstallMissing' :: PackageData -> IO [PackageName]
-pkgInstallMissing' pkgdata = do
+pkgInstallMissing' :: Bool -> PackageData -> IO [PackageName]
+pkgInstallMissing' yes pkgdata = do
   let pkgDesc = packageDesc pkgdata
       mspec = specFilename pkgdata
   missing <- uninstalledLibraries (hasLibs pkgDesc) pkgDesc
@@ -298,7 +301,7 @@
       -- let nogpgcheck = ["--nogpgcheck" | fedora `elem` []]
       noMacros <- notInstalled (RpmOther "ghc-rpm-macros")
       libtype <- withGhcProfLibType
-      rpmInstall True $ map (showRpm . RpmHsLib libtype) repopkgs ++ ["ghc-rpm-macros" | noMacros]
+      rpmInstall yes $ map (showRpm . RpmHsLib libtype) repopkgs ++ ["ghc-rpm-macros" | noMacros]
     return missing'
       where
         repoqueryPackageConf :: String -> PackageName -> IO (Maybe PackageName)
@@ -309,8 +312,8 @@
 
 withGhcProfLibType :: IO LibPkgType
 withGhcProfLibType = do
-  with_ghc_prof <- rpmEval "{?with_ghc_prof}"
-  return $ if isJust with_ghc_prof then Prof else Devel
+  quick <- notInstalled $ RpmOther "ghc-rpm-macros-quick"
+  return $ if quick then Devel else Prof
 
 showDep :: RpmPackage -> String
 showDep (RpmHsLib _ n) = display n
diff --git a/src/PackageUtils.hs b/src/PackageUtils.hs
--- a/src/PackageUtils.hs
+++ b/src/PackageUtils.hs
@@ -64,7 +64,7 @@
                     showPkgId, tryFindPackageDesc)
 import SimpleCmd (cmd, cmd_, cmdBool, cmdIgnoreErr, cmdLines,
                   cmdStderrToStdoutIn, error', grep, grep_,
-                  removePrefix, sudo, sudo_, (+-+))
+                  removePrefix, sudo_, (+-+))
 import SimpleCmd.Git (isGitDir, grepGitConfig)
 import SimpleCmd.Rpm (rpmspec)
 import System.Directory.Extra (copyFile, createDirectoryIfMissing,
@@ -180,7 +180,6 @@
       havecache <- doesDirectoryExist cacheparent
       unless havecache cabalUpdate
       remotes <- listDirectory' cacheparent
-
       let pkgid' =
             fromMaybe (error' $ "Parse failed for:" +-+ dropExtensions file) $
             simpleParse (dropExtensions file)
@@ -562,9 +561,10 @@
 repoquery :: [String] -> String -> IO String
 repoquery args key = do
   havednf <- optionalProgram "dnf"
+  -- FIXME use frpq
   -- --quiet needed to silence dnf5 unwanted stdout
   let (prog, subcmd) = if havednf then ("dnf", ["repoquery", "--quiet"]) else ("repoquery", [])
-  sudo prog (subcmd ++ args ++ [key])
+  cmd prog (subcmd ++ args ++ [key])
 
 rpmInstall :: Bool -> [String] -> IO ()
 rpmInstall _ [] = return ()
@@ -572,7 +572,7 @@
   pkginstaller <- packageManager
   let (inst, arg) = if pkginstaller == "dnf" then ("dnf", "install") else ("yum", "localinstall")
   tty <- hIsTerminalDevice stdout
-  sudo_ inst $ ["-y" | yes || not tty] ++ [arg] ++ rpms
+  sudo_ inst $ ["--assumeyes" | yes || not tty] ++ [arg] ++ rpms
 
 editSpecField :: String -> String -> FilePath -> IO ()
 editSpecField field new spec =
diff --git a/src/Stackage.hs b/src/Stackage.hs
--- a/src/Stackage.hs
+++ b/src/Stackage.hs
@@ -44,7 +44,7 @@
 import Types
 
 defaultLTS :: Stream
-defaultLTS = LTS 22
+defaultLTS = LTS 24
 
 streamToMajorVer :: Stream -> MV.MajorVer
 streamToMajorVer (LTS n) = MV.LTS n
