-
-
Save zenofile/d2acef1a0423e5081e74162cd5a0ae2d to your computer and use it in GitHub Desktop.
| #!/usr/bin/env bash | |
| set -o errexit | |
| MUSL_VERSION=1.2.5 | |
| LIBEVENT_VERSION=2.1.12 | |
| NCURSES_VERSION=6.5 | |
| TMUX_VERSION=3.5a | |
| TARGETDIR=$1 | |
| if [[ "${TARGETDIR}" = "" ]]; then | |
| TARGETDIR="${PWD}/out" | |
| fi | |
| mkdir -p "${TARGETDIR}" | |
| TASKS=$(nproc) | |
| CC=( "${TARGETDIR}/bin/musl-gcc" -static ) | |
| _CFLAGS=( -Os -ffunction-sections -fdata-sections -no-pie) | |
| _LDFLAGS=( "-Wl,--gc-sections" -flto ) | |
| _musl() { | |
| if [[ ! -e musl-${MUSL_VERSION}.tar.gz ]]; then | |
| curl -LO https://www.musl-libc.org/releases/musl-${MUSL_VERSION}.tar.gz | |
| fi | |
| tar zxf musl-${MUSL_VERSION}.tar.gz --skip-old-files | |
| pushd . | |
| cd musl-${MUSL_VERSION} | |
| CFLAGS="${_CFLAGS[*]}" LDFLAGS="${_LDFLAGS[*]}" ./configure --prefix="${TARGETDIR}" --disable-shared --enable-wrapper=gcc | |
| make -j $TASKS | |
| make install | |
| make clean | |
| popd | |
| } | |
| _libevent() { | |
| if [[ ! -e libevent-${LIBEVENT_VERSION}-stable.tar.gz ]]; then | |
| curl -LO https://github.com/libevent/libevent/releases/download/release-${LIBEVENT_VERSION}-stable/libevent-${LIBEVENT_VERSION}-stable.tar.gz | |
| fi | |
| tar zxf libevent-${LIBEVENT_VERSION}-stable.tar.gz --skip-old-files | |
| pushd . | |
| cd libevent-${LIBEVENT_VERSION}-stable | |
| _cflags=("${_CFLAGS[@]}" -flto) | |
| CC="${CC[*]}" CFLAGS="${_cflags[*]}" LDFLAGS="${_LDFLAGS[*]}" ./configure --prefix="${TARGETDIR}" --disable-shared --disable-openssl --disable-samples | |
| make -j $TASKS | |
| make install | |
| make clean | |
| popd | |
| } | |
| _ncurses() { | |
| if [[ ! -e ncurses-${NCURSES_VERSION}.tar.gz ]]; then | |
| curl -LO https://ftp.gnu.org/pub/gnu/ncurses/ncurses-${NCURSES_VERSION}.tar.gz | |
| fi | |
| tar zxvf ncurses-${NCURSES_VERSION}.tar.gz --skip-old-files | |
| pushd . | |
| cd ncurses-${NCURSES_VERSION} | |
| _cflags=( "${_CFLAGS[@]}" -flto ) | |
| CC="${CC[*]}" CFLAGS="${_cflags[*]}" LDFLAGS="${_LDFLAGS[*]}" ./configure --prefix $TARGETDIR \ | |
| --with-default-terminfo-dir=/usr/share/terminfo \ | |
| --with-terminfo-dirs="/etc/terminfo:/lib/terminfo:/usr/share/terminfo" \ | |
| --enable-pc-files \ | |
| --with-pkg-config-libdir="${TARGETDIR}/lib/pkgconfig" \ | |
| --without-ada \ | |
| --without-debug \ | |
| --with-termlib \ | |
| --without-cxx \ | |
| --without-progs \ | |
| --without-manpages \ | |
| --disable-db-install \ | |
| --without-tests | |
| make -j $TASKS | |
| make install | |
| make clean | |
| popd | |
| } | |
| _tmux() { | |
| if [[ ! -e tmux-${TMUX_VERSION}.tar.gz ]]; then | |
| curl -LO https://github.com/tmux/tmux/releases/download/${TMUX_VERSION}/tmux-${TMUX_VERSION}.tar.gz | |
| fi | |
| tar zxf tmux-${TMUX_VERSION}.tar.gz --skip-old-files | |
| pushd . | |
| cd tmux-${TMUX_VERSION} | |
| _cflags=( "${_CFLAGS[@]}" -flto ) | |
| CC="${CC[*]}" CFLAGS="${_cflags[*]}" LDFLAGS="${_LDFLAGS[*]}" PKG_CONFIG_PATH="${TARGETDIR}/lib/pkgconfig" ./configure --enable-static --prefix="${TARGETDIR}" | |
| make -j $TASKS | |
| make install | |
| make clean | |
| popd | |
| cp "${TARGETDIR}/bin/tmux" . | |
| strip --strip-all ./tmux | |
| if command -v upx &> /dev/null; then | |
| upx -k --best ./tmux | |
| fi | |
| } | |
| rm -rf "${TARGETDIR}/out" | |
| if [[ ! -x "${TARGETDIR}/bin/musl-gcc" ]]; then | |
| _musl | |
| fi | |
| _libevent | |
| _ncurses | |
| _tmux |
That's awesome, thanks!
I was building it in an Archlinux container using podman and didn't test any other build environment.
podman run --rm -it --hostname archns --userns=host --tmpfs /tmp:exec,rw -v ./build.sh:/tmp/build/build.sh -v /tmp/build-tmux:/tmp/build --workdir=/tmp/build --security-opt label=disable gitlab.archlinux.org:5050/archlinux/archlinux-docker:base-devel-master /bin/bash /tmp/build/build.sh
For anyone that might be preferring podman or docker.
hello, thanks so much,
i am using a shared linux vm, no root access, spent days trying replace the very old tmux, lacked the skills.
wanted to let you know your script works with tmux 3.2a,
TMUX_VERSION=3.2a
really, thanks!
Fantastic. In order to build on older systems, with a gcc that doesn't support -no-pie, add the following patch:
diff --git a/build.sh b/build.sh
index e7f6c33..720226e 100755
--- a/build.sh
+++ b/build.sh
@@ -15,7 +15,10 @@ mkdir -p "${TARGETDIR}"
TASKS=2
CC=( "${TARGETDIR}/bin/musl-gcc" -static )
-_CFLAGS=( -Os -ffunction-sections -fdata-sections -no-pie)
+_CFLAGS=( -Os -ffunction-sections -fdata-sections )
+if "${REALGCC:-gcc}" -v 2>&1 | grep -q -- --enable-default-pie; then
+ _CFLAGS+=( -no-pie )
+fi
_LDFLAGS=( "-Wl,--gc-sections" -flto )The -no-pie flag is illegal if gcc wasn't compiled with --enable-default-pie; in this case omitting it has the same effect.
With this change, it builds perfectly on CentOS 7. (For example in a centos:7 Dockerfile, use yum install -y gcc make autoconf and run build.sh.)
Adding @meermanr's patch above, it also builds in an ubuntu:20.04 container. In theory, it should build in a standard GitHub Actions runner.
I applied some of the suggested patches and bumped the versions. Also smoke tested with gcc-11 on aarch64 and x86_64.
And for anyone interested, I wrote a Vagrantfile that runs this script in a clean Ubuntu 20.04 LTS install: