Skip to content

Instantly share code, notes, and snippets.

@andrew-d
Last active February 10, 2021 11:53
Show Gist options
  • Save andrew-d/46cae586975221bd625ddce52b460aba to your computer and use it in GitHub Desktop.
Save andrew-d/46cae586975221bd625ddce52b460aba to your computer and use it in GitHub Desktop.
Helpful script to build a copy of Nix 2.0 for ARM (arm-linux-gnueabihf)
#!/bin/bash
# USAGE: docker run -t -i --rm -v $PWD:/out ubuntu:16.04 /out/build.sh
set -eu
# Install
install_packages() {
apt-get update && apt-get upgrade -yy
local packages=(
# Compiler/linker
binutils-arm-linux-gnueabihf
gcc-arm-linux-gnueabihf
g++-arm-linux-gnueabihf
# Required build tools
make
cmake
autoconf
automake
pkg-config
libtool
flex
bison
gettext
# Utilities required
curl
ca-certificates
xz-utils
# For debugging
less
silversearcher-ag
tree
vim
)
apt-get install -yy --no-install-recommends "${packages[@]}"
}
# Download helper function
fetch() {
local url fileopt
if [[ $# -eq 2 ]]; then
fileopt="-o $1"
url="$2"
elif [[ $# -eq 1 ]]; then
fileopt="-O"
url="$1"
else
echo "Bad args"
exit 1
fi
curl -L '-#' $fileopt $url
}
fetch_deps() {
cd $BUILDROOT/srcs
echo "Fetching sources..."
fetch https://zlib.net/zlib-1.2.11.tar.gz
fetch http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz
fetch https://tukaani.org/xz/xz-5.2.3.tar.gz
fetch https://www.openssl.org/source/openssl-1.0.2o.tar.gz
fetch https://curl.haxx.se/download/curl-7.59.0.tar.gz
fetch https://github.com/nghttp2/nghttp2/releases/download/v1.31.0/nghttp2-1.31.0.tar.gz
fetch https://www.sqlite.org/2018/sqlite-autoconf-3230000.tar.gz
fetch https://github.com/seccomp/libseccomp/releases/download/v2.3.3/libseccomp-2.3.3.tar.gz
fetch https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz
# Renamed files. Note that the nix tarball is a version with the fix for '$CPPFLAGS'
fetch aws-sdk-cpp-1.4.31.tar.gz https://github.com/aws/aws-sdk-cpp/archive/1.4.31.tar.gz
fetch nix-2.0.tar.gz https://github.com/NixOS/nix/archive/b828051659cf7cac21577982afd3f9314dc2e68c.tar.gz
}
build_zlib() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/zlib-* && cd zlib-*
CROSS_PREFIX=arm-linux-gnueabihf- \
CFLAGS="-fPIC" \
./configure \
--prefix=$BUILDROOT/sysroot \
--static
make -j4
make install
}
build_bzip2() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/bzip2-* && cd bzip2-*
local flags=(
"CC=arm-linux-gnueabihf-gcc -fPIC"
"AR=arm-linux-gnueabihf-ar"
"RANLIB=arm-linux-gnueabihf-ranlib"
)
make -j4 "${flags[@]}" libbz2.a
make "${flags[@]}" PREFIX=$BUILDROOT/sysroot install
}
build_liblzma() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/xz-* && cd xz-*
./configure \
--host=arm-linux-gnueabihf \
--prefix=$BUILDROOT/sysroot \
--disable-shared \
CFLAGS="-fPIC"
make -j4
make install
}
build_nghttp2() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/nghttp2-* && cd nghttp2-*
PKG_CONFIG_PATH=$BUILDROOT/sysroot/lib/pkgconfig \
./configure \
--host=arm-linux-gnueabihf \
--prefix=$BUILDROOT/sysroot \
--disable-shared \
CFLAGS="-fPIC"
make -j4
make install
}
build_openssl() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/openssl-* && cd openssl-*
./Configure \
--openssldir=$BUILDROOT/sysroot \
no-shared \
os/compiler:arm-linux-gnueabihf-gcc \
-fPIC
make -j4 AR='arm-linux-gnueabihf-ar r ' RANLIB=arm-linux-gnueabihf-ranlib
make install
}
build_curl() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/curl-* && cd curl-*
./configure \
--host=arm-linux-gnueabihf \
--prefix=$BUILDROOT/sysroot \
--disable-shared \
PKG_CONFIG_PATH="$BUILDROOT/sysroot/lib/pkgconfig" \
CFLAGS="-fPIC"
make -j4
make install
}
build_aws_sdk_cpp() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/aws-sdk-cpp-* && cd aws-sdk-cpp-*
mkdir build && cd build
cat <<EOF > aws.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSROOT "$BUILDROOT/sysroot")
set(CMAKE_C_COMPILER "arm-linux-gnueabihf-gcc")
set(CMAKE_CXX_COMPILER "arm-linux-gnueabihf-g++")
set(CMAKE_C_FLAGS "\${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "\${CMAKE_CXX_FLAGS} -fPIC")
# Extra flags require for HTTP/2 support
set(AWS_SDK_ADDITIONAL_LIBRARIES "$BUILDROOT/sysroot/lib/libnghttp2.a")
EOF
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_ONLY="config;core;s3" \
-DCMAKE_TOOLCHAIN_FILE=aws.cmake \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_INSTALL_PREFIX="$BUILDROOT/sysroot" \
..
make -j2
make install
}
build_sqlite() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/sqlite-* && cd sqlite-*
./configure \
--prefix=$BUILDROOT/sysroot \
--host=arm-linux-gnueabihf \
--disable-shared \
CFLAGS="-fPIC" \
CPPFLAGS=-I$BUILDROOT/sysroot/include \
LDFLAGS=-L$BUILDROOT/sysroot/lib
make
make install
}
build_libseccomp() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/libseccomp-* && cd libseccomp-*
./configure \
--prefix=$BUILDROOT/sysroot \
--host=arm-linux-gnueabihf \
--disable-shared \
CFLAGS="-fPIC"
make
make install
}
build_boost() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/boost_* && cd boost_*
./bootstrap.sh \
--prefix=$BUILDROOT/sysroot \
--with-libraries=coroutine,context
# Enable cross-compilation
sed -i \
-e "s|using gcc.*|using gcc : arm : arm-linux-gnueabihf-g++ ;|g" \
project-config.jam
# NOTE: The `-a` means "always rebuild"
./bjam install \
cxxflags='-fPIC -std=c++14' \
cflags=-fPIC \
link=static \
architecture=arm \
variant=release \
abi=aapcs \
binary-format=elf \
threading=multi \
toolset=gcc \
-a
}
build_nix() {
cd $BUILDROOT/build
tar -xf $BUILDROOT/srcs/nix-* && cd nix-*
# Handle both from git and from releases
if [[ ! -f configure ]]; then
./bootstrap.sh
fi
# NOTE: we need to pass `-std=c++11` (or newer) in $CPPFLAGS so that our
# autodetection of aws-sdk-cpp works properly
./configure \
--prefix=/usr \
--host=arm-linux-gnueabihf \
--disable-doc-gen \
PKG_CONFIG_PATH="$BUILDROOT/sysroot/lib/pkgconfig" \
CPPFLAGS="-I$BUILDROOT/sysroot/include -std=c++14" \
CXXFLAGS='-std=c++14' \
LDFLAGS="-L$BUILDROOT/sysroot/lib/"
# Patch various dependency issues
# TODO: should we submit the LIBS ordering issue upstream?
sed -i -e 's|-laws-cpp-sdk-s3 -laws-cpp-sdk-core|-laws-cpp-sdk-s3 -laws-cpp-sdk-core -lssl -lcrypto -lz|g' src/libstore/local.mk
sed -i -e "s|-lbz2|-L$BUILDROOT/sysroot/lib -lbz2|g" src/nix-store/local.mk
for subdir in nix-copy-closure nix-channel build-remote; do
sed -i -e 's|LIBS = libmain libutil libformat libstore|LIBS = libmain libformat libstore libutil|g' src/$subdir/local.mk
done
# Fix install directory
# TODO: remove once https://github.com/NixOS/nix/pull/2059 is merged
sed -i -e 's|install -t $$($(1)_INSTALL_DIR)|install -t $(DESTDIR)$$($(1)_INSTALL_DIR)|g' mk/programs.mk
# These flags are:
# - Build with C++14 (required by Nix)
# - Link libnghttp2 along with curl
# - Link both libcrypto and libssl in OpenSSL
# - Link binaries statically
# - Don't build shared libraries (since everything is static)
#
local makeflags=(
"CXXFLAGS=-std=c++14 -I/root/sysroot/include"
"LIBCURL_LIBS=-L$BUILDROOT/sysroot/lib -lcurl -lnghttp2"
"OPENSSL_LIBS=-L$BUILDROOT/sysroot/lib -lcrypto -lssl"
"LDFLAGS=-static"
"BUILD_SHARED_LIBS=0"
)
make -j4 "${makeflags[@]}"
make "${makeflags[@]}" DESTDIR="$OUTDIR" install
}
main() {
# Prep and variables
export BUILDROOT=$HOME
export OUTDIR=/out/install
mkdir -p $BUILDROOT/srcs $BUILDROOT/build $BUILDROOT/sysroot
mkdir -p $OUTDIR
install_packages
fetch_deps
build_zlib
build_bzip2
build_liblzma
build_nghttp2
build_openssl
build_curl
build_aws_sdk_cpp
build_sqlite
build_libseccomp
build_boost
build_nix
# Finally, strip everything in the bin directory to reduce the size
find "$OUTDIR" -type f -executable -exec arm-linux-gnueabihf-strip {} \;
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment