Skip to content

Commit

Permalink
Static Linux builds with Alpine
Browse files Browse the repository at this point in the history
  • Loading branch information
snoyberg committed Apr 21, 2020
1 parent ab0e190 commit 42aff5a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 13 deletions.
37 changes: 29 additions & 8 deletions .azure/azure-linux-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,40 @@ jobs:
GHC 8.4:
BUILD: stack
STACK_YAML: stack-ghc-84.yaml
EXTRA_SUFFIX: ""
GHC_OPTIONS: "-Werror"
GHC 8.6:
BUILD: stack
STACK_YAML: stack-ghc-86.yaml
EXTRA_SUFFIX: ""
GHC_OPTIONS: "-Werror"
GHC 8.8:
BUILD: stack
STACK_YAML: stack-ghc-88.yaml
EXTRA_SUFFIX: ""
GHC_OPTIONS: "-Werror"
Alpine:
BUILD: stack
STACK_YAML: stack-alpine.yaml
EXTRA_SUFFIX: "alpine"
ARGS: --system-ghc --no-install-ghc
GHC_OPTIONS: "-Werror -optl-static"
style:
BUILD: style
EXTRA_SUFFIX: ""
pedantic:
BUILD: pedantic
STACK_YAML: stack.yaml
EXTRA_SUFFIX: ""
steps:
- script: |
export STACK_ROOT="$(Build.SourcesDirectory)"/.stack-root;
mkdir -p ~/.local/bin
curl -f -L "https://github.com/fpco/cache-s3/releases/download/${CACHE_S3_VERSION}/cache-s3-${CACHE_S3_VERSION}-${OS_NAME}-x86_64.tar.gz" -o ~/.local/bin/cache-s3.tar.gz
tar xzf ~/.local/bin/cache-s3.tar.gz -C ~/.local/bin
export PATH=$HOME/.local/bin:$PATH;
cache-s3 --prefix="${CACHE_S3_PREFIX}" --git-branch="$(Build.SourceBranchName)" --suffix="${OS_NAME}" restore stack --base-branch="${BASE_BRANCH}"
cache-s3 --prefix="${CACHE_S3_PREFIX}" --git-branch="$(Build.SourceBranchName)" --suffix="${OS_NAME}" restore stack work --base-branch="${BASE_BRANCH}"
cache-s3 --prefix="${CACHE_S3_PREFIX}" --git-branch="$(Build.SourceBranchName)" --suffix="${OS_NAME}${EXTRA_SUFFIX}" restore stack --base-branch="${BASE_BRANCH}"
cache-s3 --prefix="${CACHE_S3_PREFIX}" --git-branch="$(Build.SourceBranchName)" --suffix="${OS_NAME}${EXTRA_SUFFIX}" restore stack work --base-branch="${BASE_BRANCH}"
etc/scripts/ci-setup.sh
case "$BUILD" in
style)
Expand All @@ -38,11 +52,9 @@ jobs:
;;
*)
export PATH=$HOME/.local/bin:$PATH
stack --install-ghc $ARGS test --bench --only-dependencies
stack $ARGS test --bench --only-dependencies
;;
esac
GHC_OPTIONS="-Werror"
if [ "$GHCVER" = "8.2.1" ]; then GHC_OPTIONS="$GHC_OPTIONS -Wno-missing-home-modules"; fi
set -ex
case "$BUILD" in
style)
Expand All @@ -51,7 +63,16 @@ jobs:
hlint test/ --cpp-simple
;;
stack)
stack test --haddock --no-haddock-deps --ghc-options="$GHC_OPTIONS"
stack $ARGS test --haddock --no-haddock-deps --ghc-options="$GHC_OPTIONS" --copy-bins --local-bin-path bin
# Get output about whether the exe is dynamically linked
# Ignore the exit code though, we don't want to fail just because it is static
ldd ./bin/stack || true
# Make sure we can run the executable on this OS
# Important to make sure the Alpine exe is properly static
./bin/stack --version
;;
pedantic)
stack --system-ghc build --pedantic
Expand Down Expand Up @@ -94,9 +115,9 @@ jobs:
export AWS_SECRET_ACCESS_KEY="$(AWS_SECRET_ACCESS_KEY)";
export STACK_ROOT="$(Build.SourcesDirectory)"/.stack-root;
if [ "$(Build.SourceBranchName)" = "${BASE_BRANCH}" ]; then
cache-s3 --prefix="${CACHE_S3_PREFIX}" --git-branch="$(Build.SourceBranchName)" --suffix="${OS_NAME}" save stack;
cache-s3 --prefix="${CACHE_S3_PREFIX}" --git-branch="$(Build.SourceBranchName)" --suffix="${OS_NAME}${EXTRA_SUFFIX}" save stack;
fi;
cache-s3 --prefix="${CACHE_S3_PREFIX}" --git-branch="$(Build.SourceBranchName)" --suffix="${OS_NAME}" save stack work
cache-s3 --prefix="${CACHE_S3_PREFIX}" --git-branch="$(Build.SourceBranchName)" --suffix="${OS_NAME}${EXTRA_SUFFIX}" save stack work
condition: and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))
env:
OS_NAME: ${{ parameters.os }}
Expand Down
4 changes: 2 additions & 2 deletions .azure/azure-nightly-template-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
nix-channel --update # Get GHC 8.2.2
export STACK_ROOT="$(Build.SourcesDirectory)"/.stack-root;
export PATH=$HOME/.local/bin:$PATH;
stack etc/scripts/release.hs check
stack etc/scripts/release.hs check --stack-yaml=stack-alpine.yaml
set +ex
displayName: Integration Test
Expand All @@ -49,7 +49,7 @@ jobs:
export STACK_ROOT="$(Build.SourcesDirectory)"/.stack-root;
export PATH=$HOME/.local/bin:$PATH;
stack etc/scripts/release.hs build
stack etc/scripts/release.hs build --stack-yaml=stack-alpine.yaml
cp _release/stack-* $(Build.ArtifactStagingDirectory)
set +ex
Expand Down
21 changes: 18 additions & 3 deletions etc/scripts/release.hs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ main =
-- build the default value of type Global, with predefined constants

-- 'stack build --dry-run' just ensures that 'stack.cabal' is generated from hpack
_ <- readProcess "stack" ["build", "--dry-run"] ""
_ <- readProcess "stack" ["build", "--dry-run", "--system-ghc"] ""
gStackPackageDescription <-
packageDescription <$> readGenericPackageDescription silent "stack.cabal"
gGpgKey <- maybe defaultGpgKey Just <$> lookupEnv gpgKeyEnvVar
Expand All @@ -94,6 +94,7 @@ main =
gBuildArgs = []
gCertificateName = Nothing
gUploadOnly = False
gStackYaml = "stack.yaml"
global0 = foldl (flip id) Global{..} flags

-- Need to get paths after options since the '--arch' argument can effect them.
Expand Down Expand Up @@ -151,6 +152,11 @@ options =
"Certificate name for code signing on Windows"
, Option "" [uploadOnlyOptName] (NoArg $ Right $ \g -> g{gUploadOnly = True})
"Just upload an existing file, but don't try to build it."
, Option "" [stackYamlOptName]
(ReqArg
(\v -> Right $ \g -> g{gStackYaml = v})
"stack.yaml file")
"stack.yaml file to build from"
]

-- | Shake rules.
Expand Down Expand Up @@ -206,7 +212,11 @@ rules global@Global{..} args = do
,[" --haddock" | gTestHaddocks]
,[" stack"]]
let cmd' c = cmd (AddPath [tmpDir] []) stackProgName (stackArgs global) c
() <- cmd' "test" gBuildArgs integrationTestFlagArgs "--pedantic --exec stack-integration-test stack"
() <- cmd
[ gProjectRoot </> releaseBinDir </> binaryName </> stackExeFileName
, "exec"
, gProjectRoot </> releaseBinDir </> binaryName </> "stack-integration-test"
]
return ()
copyFileChanged (releaseBinDir </> binaryName </> stackExeFileName) out

Expand Down Expand Up @@ -546,9 +556,13 @@ certificateNameOptName = "certificate-name"
uploadOnlyOptName :: String
uploadOnlyOptName = "upload-only"

-- | @--stack-yaml@ command-line option name.
stackYamlOptName :: String
stackYamlOptName = "stack-yaml"

-- | Arguments to pass to all 'stack' invocations.
stackArgs :: Global -> [String]
stackArgs Global{..} = ["--install-ghc", "--arch=" ++ display gArch, "--interleaved-output"]
stackArgs Global{..} = ["--install-ghc", "--system-ghc", "--stack-yaml=" ++ gStackYaml, "--arch=" ++ display gArch, "--interleaved-output"]

-- | Name of the 'stack' program.
stackProgName :: FilePath
Expand Down Expand Up @@ -602,5 +616,6 @@ data Global = Global
, gBuildArgs :: [String]
, gCertificateName :: !(Maybe String)
, gUploadOnly :: !Bool
, gStackYaml :: !FilePath
}
deriving (Show)
30 changes: 30 additions & 0 deletions stack-alpine.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
resolver: lts-14.27

packages:
- .

docker:
enable: true
#image: fpco/alpine-haskell-stack:8.6.5
image: fpco/alpine-haskell-stack@sha256:49e7e15f3b1d3f882ba5bb701463b1d508fbf40e5aafce6ea31acd210da570ba

flags:
stack:
hide-dependency-versions: true
supported-build: true

ghc-options:
"$locals": -fhide-source-paths -optl-static

extra-deps:
- Cabal-3.0.0.0@rev:0
- hpack-0.33.0@rev:0
- http-download-0.2.0.0@rev:0
- filelock-0.1.1.4@rev:0
- pantry-0.4.0.1@rev:0
- casa-client-0.0.1@rev:0
- casa-types-0.0.1@rev:0

drop-packages:
# See https://github.com/commercialhaskell/stack/pull/4712
- cabal-install

0 comments on commit 42aff5a

Please sign in to comment.