Skip to content

Commit 18634d2

Browse files
snoybergborsboom
authored andcommitted
Create a Linux static bindist #5288
This implements the final piece of and closes out #5288
1 parent cad6eaa commit 18634d2

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

etc/scripts/release.hs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import System.IO.Error
4646
import System.Process
4747

4848
import qualified Codec.Archive.Tar as Tar
49+
import qualified Codec.Archive.Tar.Entry as TarEntry
4950
import qualified Codec.Archive.Zip as Zip
5051
import qualified Codec.Compression.GZip as GZip
5152
import Data.List.Extra
@@ -84,6 +85,7 @@ main =
8485
gTestHaddocks = True
8586
gProjectRoot = "" -- Set to real value velow.
8687
gBuildArgs = ["--flag", "stack:-developer-mode"]
88+
gStaticLinux = False
8789
gCertificateName = Nothing
8890
global0 = foldl (flip id) Global{..} flags
8991

@@ -118,7 +120,8 @@ options =
118120
(NoArg $ Right $ \g ->
119121
g{gBuildArgs =
120122
gBuildArgs g ++
121-
["--flag=stack:static", "--docker", "--system-ghc", "--no-install-ghc"]})
123+
["--flag=stack:static", "--docker", "--system-ghc", "--no-install-ghc"],
124+
gStaticLinux = True})
122125
"Build a static binary using Alpine Docker image."
123126
, Option "" [buildArgsOptName]
124127
(ReqArg
@@ -194,7 +197,14 @@ rules global@Global{..} args = do
194197

195198
releaseDir </> binaryPkgTarGzFileName %> \out -> do
196199
stageFiles <- getBinaryPkgStageFiles
197-
writeTarGz out releaseStageDir stageFiles
200+
writeTarGz id out releaseStageDir stageFiles
201+
202+
releaseDir </> binaryPkgStaticTarGzFileName %> \out -> do
203+
stageFiles <- getBinaryPkgStageFiles
204+
let fixPath path =
205+
let (x, y) = break (== '/') path
206+
in concat [x, "-static", y]
207+
writeTarGz fixPath out releaseStageDir stageFiles
198208

199209
releaseStageDir </> binaryName </> stackExeFileName %> \out -> do
200210
copyFileChanged (releaseDir </> binaryExeFileName) out
@@ -296,16 +306,21 @@ rules global@Global{..} args = do
296306
binaryPkgFileNames =
297307
case platformOS of
298308
Windows -> [binaryExeFileName, binaryPkgZipFileName, binaryPkgTarGzFileName, binaryInstallerFileName]
309+
Linux -> concat
310+
[ [binaryExeFileName, binaryPkgTarGzFileName]
311+
, [binaryPkgStaticTarGzFileName | gStaticLinux]
312+
]
299313
_ -> [binaryExeFileName, binaryPkgTarGzFileName]
300314
binaryPkgZipFileName = binaryName <.> zipExt
301315
binaryPkgTarGzFileName = binaryName <.> tarGzExt
316+
binaryPkgStaticTarGzFileName = binaryStaticName <.> tarGzExt
302317
-- Adding '-bin' to name to work around https://github.com/commercialhaskell/stack/issues/4961
303318
binaryExeFileName = binaryName ++ "-bin" <.> exe
304319
-- Prefix with 'installer-' so it doesn't get included in release artifacts
305320
-- (due to NSIS limitation, needs to be in same directory as executable)
306321
binaryInstallerNSIFileName = "installer-" ++ binaryName <.> nsiExt
307322
binaryInstallerFileName = binaryName ++ "-installer" <.> exe
308-
binaryName =
323+
mkBinaryName isStatic =
309324
concat
310325
[ stackProgName
311326
, "-"
@@ -314,7 +329,10 @@ rules global@Global{..} args = do
314329
, display platformOS
315330
, "-"
316331
, display gArch
332+
, if isStatic then "-static" else ""
317333
, if null gBinarySuffix then "" else "-" ++ gBinarySuffix ]
334+
binaryName = mkBinaryName False
335+
binaryStaticName = mkBinaryName True
318336
stackExeFileName = stackProgName <.> exe
319337

320338
zipExt = ".zip"
@@ -325,10 +343,21 @@ rules global@Global{..} args = do
325343

326344
-- | Create a .tar.gz files from files. The paths should be absolute, and will
327345
-- be made relative to the base directory in the tarball.
328-
writeTarGz :: FilePath -> FilePath -> [FilePath] -> Action ()
329-
writeTarGz out baseDir inputFiles = liftIO $ do
346+
writeTarGz :: (FilePath -> FilePath) -> FilePath -> FilePath -> [FilePath] -> Action ()
347+
writeTarGz fixPath out baseDir inputFiles = liftIO $ do
330348
content <- Tar.pack baseDir $ map (dropDirectoryPrefix baseDir) inputFiles
331-
L8.writeFile out $ GZip.compress $ Tar.write content
349+
L8.writeFile out $ GZip.compress $ Tar.write $ map fixPath' content
350+
where
351+
fixPath' :: Tar.Entry -> Tar.Entry
352+
fixPath' entry =
353+
case TarEntry.toTarPath isDir $ fixPath $ TarEntry.entryPath entry of
354+
Left e -> error $ show (Tar.entryPath entry, e)
355+
Right tarPath -> entry { TarEntry.entryTarPath = tarPath }
356+
where
357+
isDir =
358+
case TarEntry.entryContent entry of
359+
TarEntry.Directory -> True
360+
_ -> False
332361

333362
-- | Drops a directory prefix from a path. The prefix automatically has a path
334363
-- separator character appended. Fails if the path does not begin with the prefix.
@@ -407,6 +436,7 @@ data Global = Global
407436
, gBinarySuffix :: !String
408437
, gTestHaddocks :: !Bool
409438
, gBuildArgs :: [String]
439+
, gStaticLinux :: !Bool
410440
, gCertificateName :: !(Maybe String)
411441
}
412442
deriving (Show)

0 commit comments

Comments
 (0)