Skip to content

Commit b9a3183

Browse files
authored
Merge pull request #19 from vst/18-distribute-statically-compiled-executable
Script for Static Compilation
2 parents 3b472c6 + 82e29c6 commit b9a3183

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

build-static.sh

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env bash
2+
3+
## NOTE: Things would be much easier if we could use Nix, but we can
4+
## not (or I find it rather tedious). So, we have to use Docker.
5+
##
6+
## Also, `cabal install` does not work with
7+
## `--enable-executable-static` flag. So, we have to use `cabal build`
8+
## instead. Finally, `cabal build` does not work with
9+
## `--enable-executable-stripping`, hence the `strip` command usage.
10+
11+
## GHC version:
12+
GHC_VERSION="9.4.8"
13+
14+
## Docker image:
15+
DOCKER_IMAGE="quay.io/benz0li/ghc-musl:${GHC_VERSION}"
16+
17+
## Executable name:
18+
EXECUTABLE_NAME="opsops"
19+
20+
## Final executable name:
21+
FINAL_EXECUTABLE_NAME="${EXECUTABLE_NAME}-static-$(uname --kernel-name | tr '[:upper:]' '[:lower:]')-$(uname --machine)"
22+
23+
## Final executable path:
24+
FINAL_EXECUTABLE_PATH="/tmp/${FINAL_EXECUTABLE_NAME}"
25+
26+
## Docker container name:
27+
CONTAINER_NAME="static-builder-for-${EXECUTABLE_NAME}"
28+
29+
## Create/update .cabal file:
30+
hpack
31+
32+
## Cleanup first:
33+
cabal clean
34+
cabal v1-clean
35+
36+
## First, pin all packages as per Nix:
37+
cabal freeze
38+
39+
## Run the Docker container:
40+
docker run -i --detach -v "$(pwd):/app" --name "${CONTAINER_NAME}" "${DOCKER_IMAGE}" /bin/bash
41+
42+
## Whitelist codebase directory for Git queries:
43+
docker exec "${CONTAINER_NAME}" git config --global --add safe.directory /app
44+
45+
## Update cabal database:
46+
docker exec "${CONTAINER_NAME}" cabal update
47+
48+
## Build the static binary:
49+
docker exec -w "/app" "${CONTAINER_NAME}" cabal build --enable-executable-static
50+
51+
## Get the path to the executable:
52+
BUILD_PATH="$(docker exec -w "/app" "${CONTAINER_NAME}" cabal list-bin "${EXECUTABLE_NAME}")"
53+
54+
## Strip debugging symbols:
55+
docker exec "${CONTAINER_NAME}" strip "${BUILD_PATH}"
56+
57+
## Copy the binary to the host:
58+
docker cp "${CONTAINER_NAME}:${BUILD_PATH}" "${FINAL_EXECUTABLE_PATH}"
59+
60+
## Compress the executable:
61+
upx "${FINAL_EXECUTABLE_PATH}"
62+
63+
## Cleanup:
64+
docker exec -w "/app" "${CONTAINER_NAME}" cabal clean
65+
docker exec -w "/app" "${CONTAINER_NAME}" cabal v1-clean
66+
docker rm -f "${CONTAINER_NAME}"
67+
rm cabal.project.freeze
68+
file "${FINAL_EXECUTABLE_PATH}"

0 commit comments

Comments
 (0)