|
1 |
| -{-# LANGUAGE RecordWildCards, LambdaCase #-} |
2 |
| - |
3 |
| -import Control.Monad |
4 |
| -import Control.Monad.IO.Class |
5 |
| -import Control.Monad.Catch |
| 1 | +{-# LANGUAGE RecordWildCards #-} |
| 2 | +import System.FilePath |
6 | 3 | import Options.Applicative
|
7 | 4 | import Data.Semigroup ((<>))
|
8 |
| -import qualified Data.ByteString.Char8 as BS8 |
9 |
| -import System.FilePath |
10 |
| -import System.Directory |
11 |
| -import Codec.Archive.Zip |
12 |
| -import Codec.Archive.Zip.Unix |
13 |
| -import Text.Printf |
14 |
| - |
15 |
| -import qualified Data.Map as Map |
16 | 5 |
|
17 |
| -import Stg.Program |
18 |
| -import Stg.Foreign.Linker |
19 |
| -import qualified Stg.GHC.Symbols as GHCSymbols |
| 6 | +import Stg.Fullpak |
20 | 7 |
|
21 |
| -data Fullpak |
22 |
| - = Fullpak |
| 8 | +data FullpakOptions |
| 9 | + = FullpakOptions |
23 | 10 | { ghcstgappPath :: FilePath
|
24 | 11 | , stgbinsOnly :: Bool
|
25 | 12 | , includeAll :: Bool
|
26 | 13 | }
|
27 | 14 |
|
28 |
| -fullpak :: Parser Fullpak |
29 |
| -fullpak = Fullpak |
| 15 | +fullpak :: Parser FullpakOptions |
| 16 | +fullpak = FullpakOptions |
30 | 17 | <$> argument str (metavar "FILE" <> help "The .ghc_stgapp file that will be packed")
|
31 | 18 | <*> switch (short 's' <> long "stgbins-only" <> help "Packs the module.stgbin files only")
|
32 | 19 | <*> switch (short 'a' <> long "include-all" <> help "Includes all progam and library modules (without dead module elimination)")
|
33 | 20 |
|
34 |
| -getModuleList :: [StgModuleInfo] -> IO [FilePath] |
35 |
| -getModuleList modinfoList = do |
36 |
| - putStrLn $ "all modules: " ++ show (length modinfoList) |
37 |
| - forM modinfoList $ \StgModuleInfo{..} -> do |
38 |
| - printf "%-60s %s\n" modPackageName modModuleName |
39 |
| - pure modModpakPath |
40 |
| - |
41 | 21 | main :: IO ()
|
42 | 22 | main = do
|
43 | 23 | let opts = info (fullpak <**> helper) mempty
|
44 |
| - Fullpak{..} <- execParser opts |
45 |
| - |
46 |
| - -- mk .fullpak |
47 |
| - modinfoList <- getAppModuleMapping ghcstgappPath |
48 |
| - appModpaks <- if includeAll |
49 |
| - then getModuleList modinfoList |
50 |
| - else collectProgramModules (map modModpakPath modinfoList) "main" "Main" GHCSymbols.liveSymbols |
51 |
| - |
52 |
| - let modpakMap = Map.fromList [(modModpakPath m , m) | m <- modinfoList] |
53 |
| - fullpakModules = [modpakMap Map.! m | m <- appModpaks] |
54 |
| - fullpakName = ghcstgappPath -<.> ".fullpak" |
55 |
| - |
56 |
| - -- collect license info |
57 |
| - StgAppLicenseInfo{..} <- getAppLicenseInfo ghcstgappPath |
58 |
| - |
59 |
| - -- collect cbits sources |
60 |
| - cbitsSourceInfos <- getAppForeignFiles ghcstgappPath |
61 |
| - |
62 |
| - -- link cbits.so |
63 |
| - workDir <- getExtStgWorkDirectory ghcstgappPath |
64 |
| - let soName = workDir </> "cbits.so" |
65 |
| - doesFileExist soName >>= \case |
66 |
| - True -> do |
67 |
| - putStrLn "using existing cbits.so" |
68 |
| - False -> do |
69 |
| - putStrLn "linking cbits.so" |
70 |
| - linkForeignCbitsSharedLib ghcstgappPath |
71 |
| - |
72 |
| - putStrLn $ "creating " ++ fullpakName |
73 |
| - createArchive fullpakName $ do |
74 |
| - -- top level info |
75 |
| - let content = BS8.pack $ unlines |
76 |
| - [ "modules:", printSection $ map modModuleName fullpakModules |
77 |
| - ] |
78 |
| - appinfo <- mkEntrySelector "app.info" |
79 |
| - addEntry Deflate content appinfo |
80 |
| - setExternalFileAttrs (fromFileMode 0o0644) appinfo |
81 |
| - |
82 |
| - -- add .ghc_stgapp to .fullpak |
83 |
| - app_ghcstgapp <- mkEntrySelector "app.ghc_stgapp" |
84 |
| - loadEntry Deflate app_ghcstgapp ghcstgappPath |
85 |
| - setExternalFileAttrs (fromFileMode 0o0644) app_ghcstgapp |
86 |
| - |
87 |
| - -- copy license info |
88 |
| - forM_ stgappUnitConfs $ \unitConf -> do |
89 |
| - add (".package-db-and-license-info" </> takeFileName unitConf) unitConf |
90 |
| - |
91 |
| - -- copy cbits sources |
92 |
| - forM_ cbitsSourceInfos $ \StgAppForeignSourceInfo{..} -> do |
93 |
| - add ("cbits-source" </> stgForeignUnitId </> stgForeignSourceRelPath) stgForeignSourceAbsPath |
94 |
| - |
95 |
| - -- copy cbits.so and related files |
96 |
| - add "cbits/cbits.so" soName |
97 |
| - add "cbits/cbits.so.sh" (soName ++ ".sh") |
98 |
| - add "cbits/stub.c" (workDir </> "stub.c") |
99 |
| - |
100 |
| - -- copy module content |
101 |
| - forM_ fullpakModules $ \StgModuleInfo{..} -> do |
102 |
| - let files = |
103 |
| - [ "module.stgbin" |
104 |
| - ] ++ if stgbinsOnly then [] else |
105 |
| - [ "module.ghcstg" |
106 |
| - , "module.fullcore-hi" |
107 |
| - , "module.ghccore" |
108 |
| - , "module.hs" |
109 |
| - , "module.cmm" |
110 |
| - , "module.s" |
111 |
| - , "module.info" |
112 |
| - , "module_stub.h" |
113 |
| - , "module_stub.c" |
114 |
| - , "module_capi_stub.o" |
115 |
| - ] |
116 |
| - existingFiles <- withArchive modModpakPath $ mapM mkEntrySelector files >>= filterM doesEntryExist |
117 |
| - forM_ existingFiles $ \src -> do |
118 |
| - dst <- mkEntrySelector (modModuleName </> unEntrySelector src) |
119 |
| - copyEntry modModpakPath src dst |
120 |
| - setExternalFileAttrs (fromFileMode 0o0644) dst |
| 24 | + FullpakOptions{..} <- execParser opts |
| 25 | + let fullpakName = ghcstgappPath -<.> ".fullpak" |
121 | 26 |
|
122 |
| -add :: FilePath -> FilePath -> ZipArchive () |
123 |
| -add zipPath srcPath = do |
124 |
| - entry <- mkEntrySelector zipPath |
125 |
| - loadEntry Zstd entry srcPath |
126 |
| - setExternalFileAttrs (fromFileMode 0o0644) entry |
| 27 | + mkFullpak ghcstgappPath stgbinsOnly includeAll fullpakName |
0 commit comments