Last active
February 10, 2021 11:53
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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