Skip to content

Add github action rules for static binaries generation (Linux, Macos) #391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jul 23, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/static-builds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Generate static binaries
on:
push:
branches:
- master
tags:
- '*'
pull_request:
branches:
- '**'
jobs:
static-bin-linux:
name: Builds static Linux binaries
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Generate the binaries
run: |
./scripts/static-build.sh
ldd learn-ocaml learn-ocaml-server learn-ocaml-client
- name: Archive static binaries
uses: actions/upload-artifact@v2
with:
name: static-binaries-linux
path: |
learn-ocaml
learn-ocaml-server
learn-ocaml-client
static-bin-macos:
name: Builds static Macos binaries
runs-on: macos-latest
env:
OPAMYES: 1
OPAMDEPEXTYES: 1
steps:
- name: Check out the repo
uses: actions/checkout@v2
# Need unreleased 2.1.0~rc
# - name: Retrieve opam
# run: |
# mkdir "$HOME/bin"
# wget https://github.com/ocaml/opam/releases/download/2.1.0-beta2/opam-2.1.0-beta2-x86_64-macos -O $HOME/bin/opam
# chmod a+x $HOME/bin/opam
# echo "$HOME/bin" >> $GITHUB_PATH
- name: Install latest opam
run: |
brew install opam --HEAD
Comment on lines +49 to +58
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment somewhere recalling the feature (or PR) that is needed here, and not available in opam 2.0.x?

- name: Prepare build environment
run: |
opam init -a --bare
opam switch create . ocaml-base-compiler 'dune<2' --deps-only
- name: Build the binaries
run: |
opam exec -- make LINKING_MODE=static
otool -L _build/install/default/bin/*
- name: Archive static binaries
uses: actions/upload-artifact@v2
with:
name: static-binaries-macos
path: _build/install/default/bin/*
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,7 @@ travis: # From https://stackoverflow.com/questions/21053657/how-to-run-travis-ci
INSTANCE="travisci/ci-garnet:packer-1512502276-986baf0"; \
docker run --name $$BUILDID -dit $$INSTANCE /sbin/init && \
docker exec -it $$BUILDID bash -l

.PHONY: static-binaries
static-binaries:
./scripts/static-build.sh
2 changes: 1 addition & 1 deletion learn-ocaml-client.opam
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ depends: [
"cohttp-lwt-unix" {>= "1.0.0" & < "2.0.0"}
"ssl" {= "0.5.5"}
"digestif" {>= "0.7.1"}
"dune" {= "2.0.1"}
"dune" {>= "1.11.4" & <= "2.0.1"}
"ezjsonm"
"lwt" {>= "4.0.0"}
"lwt_ssl"
Expand Down
2 changes: 1 addition & 1 deletion learn-ocaml.opam
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ depends: [
"conf-git"
"decompress" {= "0.8.1"}
"digestif" {>= "0.7.1"}
"dune" {= "2.0.1"}
"dune" {>= "1.11.4"}
"easy-format" {>= "1.3.0" }
"ipaddr" {= "2.8.0" }
"ezjsonm"
Expand Down
19 changes: 19 additions & 0 deletions scripts/static-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -ue

LC_ALL=C

cd $(dirname "$0")/..

## Run build in container

tar c $(git ls-files) | \
docker run --rm -i \
ocamlpro/ocaml:4.05 \
sh -uexc \
'tar x >&2 &&
sudo apk add openssl-libs-static >&2 &&
opam switch create . ocaml-system "dune<2" --deps-only >&2 &&
opam exec make LINKING_MODE=static >&2 &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick (if you don't disagree):

Suggested change
opam exec make LINKING_MODE=static >&2 &&
opam exec -- make LINKING_MODE=static >&2 &&

tar c -hC _build/install/default/bin .' | \
tar vx
21 changes: 19 additions & 2 deletions src/main/dune
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
(name learnocaml_main)
(modes byte)
(ocamlc_flags :standard -custom)
(flags :standard -linkall)
(flags (:standard -linkall
(:include linking_main.sexp)))
(modules Learnocaml_main)
(libraries cmdliner
sha
Expand All @@ -29,7 +30,8 @@
(name learnocaml_client)
(modes byte)
(ocamlc_flags :standard -custom)
(flags :standard -linkall)
(flags (:standard -linkall
(:include linking_client.sexp)))
(modules Learnocaml_client)
(libraries cmdliner
sha
Expand All @@ -48,4 +50,19 @@
(name learnocaml_server_main)
(modules learnocaml_server_main)
(libraries learnocaml_server_args)
(flags (:standard
(:include linking_server.sexp)))
)

(rule
(targets linking_main.sexp)
(action (with-stdout-to %{targets}
(run ./linking_flags.sh %{env:LINKING_MODE=dynamic} laolao_stubs threads camlrun))))
(rule
(targets linking_client.sexp)
(action (with-stdout-to %{targets}
(run ./linking_flags.sh %{env:LINKING_MODE=dynamic} threads camlrun))))
(rule
(targets linking_server.sexp)
(action (with-stdout-to %{targets}
(run ./linking_flags.sh %{env:LINKING_MODE=dynamic} laolao_stubs threadsnat))))
61 changes: 61 additions & 0 deletions src/main/linking_flags.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/sh
set -ue

# This script is called by dune to generate the linking flags for static builds
# (on the limited set of supported platforms). It only returns an empty set of
# flags for the default dynamic linking mode.

LC_ALL=C

echo ";; generated by $0"

case "$1" in
dynamic) echo "()"; exit 0;;
static) ;;
*) echo "Invalid linking mode '$1'. Usage: $0 dynamic|static [extra-libs]" >&2; exit 2
esac

shift
EXTRA_LIBS="$*"

## Static linking configuration ##

# The linked C libraries list may need updating on changes to the dependencies.
#
# To get the correct list for manual linking, the simplest way is to set the
# flags to `-verbose`, while on the normal `autolink` mode, then extract them
# from the gcc command-line.

case $(uname -s) in
Linux)
case $(. /etc/os-release && echo $ID) in
alpine)
COMMON_LIBS="camlstr base_stubs ssl_threads_stubs ssl crypto cstruct_stubs lwt_unix_stubs bigarray unix c"
# `m` and `pthreads` are built-in musl
echo '(-noautolink'
echo ' -cclib -Wl,-Bstatic'
echo ' -cclib -static-libgcc'
for l in $EXTRA_LIBS $COMMON_LIBS; do
echo " -cclib -l$l"
done
echo ' -cclib -static)'
;;
*)
echo "Error: static linking is only supported in Alpine, to avoids glibc constraints" >&2
exit 3
esac
;;
Darwin)
COMMON_LIBS="camlstr base_stubs ssl_threads_stubs /usr/local/opt/openssl/lib/libssl.a /usr/local/opt/openssl/lib/libcrypto.a cstruct_stubs lwt_unix_stubs bigarray unix pthread"
echo '(-noautolink'
for l in $EXTRA_LIBS $COMMON_LIBS; do
if [ "${l%.a}" != "${l}" ]; then echo " -cclib $l"
else echo " -cclib -l$l"
fi
done
echo ')'
;;
*)
echo "Static linking is not supported for your platform. See $0 to contribute." >&2
exit 3
esac