diff options
Diffstat (limited to 'bootstrap')
-rwxr-xr-x | bootstrap | 484 |
1 files changed, 484 insertions, 0 deletions
diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..16aa666 --- /dev/null +++ b/bootstrap @@ -0,0 +1,484 @@ +#! /usr/bin/env bash + +# @@ Do we really want to require PDF doc generation? This will unlikely +# work anywhere except Linux. Maybe we should only distribute .xhtml +# and only generate PDFs for web publishing? Maybe decide when moving +# to ad hoc rules? + +# Boostrap the build2 development setup. +# +# See HOWTO/setup-build2-for-development.md for step by step instructions. +# +# Typical command lines for "full" development setup: +# +# --ssh --clean --extra --module rust --cxx g++-7 --cfg gcc7 --loptions "-fuse-ld=gold -Wl,--threads,--thread-count,4" +# +# Additional configuration: +# +# --no-clone --no-symlink --no-libs --no-modules --cxx g++-7 --cfg gcc7-tsan --coptions "-Wall -Wextra -Werror -g -fsanitize=thread" --loptions "-fuse-ld=gold -Wl,--threads,--thread-count,4" +# +# To initialize any additional projects: +# +# bdep init -d <proj> -A builds/gcc7 @gcc7 +# +# Note that this script runs git-update-index commands specified in the +# README-GIT files of cloned repositories. It also expected the staged +# toolchain, CLI, and ODB to be runnable (i.e., already in PATH). +# +# Options: +# +# --ssh +# Use SSH URL for cloning (rw access). +# +# --extra +# Initialize additional packages (bbot, brep, etc) that are not part of +# the toolchain core (build2, bpkg, and bdep). Note that they are +# configured but not updated. Also note that for brep we assume libapr1, +# libapreq2, and libpq are available from the system (see brep/INSTALL +# for details). +# +# --module <name> +# Additional (to standard pre-installed) build system module to initialize. +# Repeat this option to specify multiple modules. Note: <name> should be +# without the libbuild2- prefix. +# +# --no-modules +# Do not initialize standard pre-installed build system modules. +# +# --no-clone +# Do not clone the repositories or build the bootstrap build system +# (b-boot) assuming this has already been done. This option is primarily +# useful for initializing additional configurations (e.g., Clang in +# addition to GCC). +# +# --clean +# Clean (or clone if does not exist) the source directories (remove .bdep/, +# forwarded configurations) and the configuration directories. This is +# primarily useful to re-initialized an already initialized (or failed) +# setup. +# +# --no-libs +# Do not create an extra configuration for libraries. Having such a +# configuration allows you to test changes in libraries without rendering +# the rest of the toolchain no longer runnable/functional. +# +# --no-symlink +# Do not create executable symlinks in /usr/local/bin/. +# +# --cxx +# --cfg +# C++ compiler to use and the corresponding build configuration name, for +# example, g++-9/gcc9 or clang++-8/clang8; g++/gcc by default. +# +# --coptions +# --loptions +# Compiler and linker options to use. By default a debug build with +# ASAN/UBSAN is configured: +# +# -Wall -Wextra -Werror -g -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer +# +# To configure TSAN, use the following coptions instead: +# +# -Wall -Wextra -Werror -g -fsanitize=thread +# +# To enable parallel linking with gold, use the following loptions: +# +# -fuse-ld=gold -Wl,--threads,--thread-count,4 +# +owd="$(pwd)" +trap "{ cd '$owd'; exit 1; }" ERR +set -o errtrace # Trap in functions. + +function info () { echo "$*" 1>&2; } +function error () { info "$*"; exit 1; } + +# Run a command with tracing (similar to set -x). +# +# Note that this function will execute a command with arguments that contain +# spaces but it will not print them as quoted (and neither does set -x). +# +function run () +{ + echo "+ $@" 1>&2 + "$@" +} + +# Make sure the necessary tools are runnable. +# +cli --version >/dev/null +odb --version >/dev/null +b --version >/dev/null +bpkg --version >/dev/null +bdep --version >/dev/null + +url="https://git.build2.org" +mod_url="https://github.com/build2" +extra= +mod=(hello autoconf kconfig) +sym=true +clone=true +clean= +libs=true +cxx=g++ +cfg=gcc +copt="-Wall -Wextra -Werror -g -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer" +lopt= +popt= + +while [ $# -gt 0 ]; do + case $1 in + --ssh) + url="git.build2.org:/var/scm" + mod_url="git@github.com:build2" + shift + ;; + --extra) + extra=true + shift + ;; + --module) + shift + mod+=("$1") + shift + ;; + --no-modules) + mod=() + shift + ;; + --no-symlink) + sym= + shift + ;; + --no-clone) + clone= + shift + ;; + --clean) + clean=true + shift + ;; + --no-libs) + libs= + shift + ;; + --cxx) + shift + cxx="$1" + shift + ;; + --cfg) + shift + cfg="$1" + shift + ;; + --coptions) + shift + copt="$1" + shift + ;; + --loptions) + shift + lopt="$1" + shift + ;; + *) + error "unexpected $1" + ;; + esac +done + +if [ "$clean" ]; then + + if [ "$sym" ]; then + run sudo rm -f /usr/local/bin/b-boot + run sudo rm -f /usr/local/bin/b + run sudo rm -f /usr/local/bin/bpkg + run sudo rm -f /usr/local/bin/bdep + fi + + run rm -rf builds/ + + for m in "${mod[@]}"; do + run rm -rf "libbuild2-$m-build/" + done + + run cd build2 + run make -f bootstrap.gmake CXX="$cxx" CXXFLAGS=-O3 clean + run cd - + + def=true + +else + # Determine if this is the first/default configuration. + # + if test -d build2/.bdep; then + def= + else + def=true + fi +fi + +if [ ! "$def" ]; then + + if [ "$libs" ]; then + error "non-default configuration requires --no-libs" + fi + + if [ "${#mod[@]}" -ne 0 ]; then + error "non-default configuration requires --no-modules" + fi +fi + +if [ "$extra" ]; then + popt="$popt -I$(apxs -q includedir)" +fi + +# Clone or clean the repository. +# +function git_clone () # <url> +{ + local u d l + + u="$1" + d="$(basename -s .git "$u")" + + # Clone it if doesn't exist. + # + if [ "$clean" -a -d "$d" ]; then + + run rm -rf "$d/.bdep/" + + for l in $(find "$d" -name out-root.build); do + run rm -f "$l" + done + + else + run git clone --recursive "$u" + fi + + # Run git-update-index commands from README-GIT. + # + if [ -f "$d/README-GIT" ]; then + run cd "$d" + l= + while read l || [ -n "$l" ]; do + info "+ $l" + eval $l + done < <(sed -rn -e 's/^(git update-index .+)/\1/p' README-GIT) + run cd - + fi + + # Generate documentation (currently and temporarily handled with a script). + # + if [ -f "$d/doc/cli.sh" ]; then + run cd "$d/doc" + run ./cli.sh + run cd - + fi +} + +if [ "$clone" -o "$clean" ]; then + git_clone "$url/libbutl.git" + git_clone "$url/build2.git" + git_clone "$url/libbpkg.git" + git_clone "$url/bpkg.git" + git_clone "$url/bdep.git" + + if [ "$extra" ]; then + git_clone "$url/libbutl.bash.git" + git_clone "$url/bpkg-util.git" + git_clone "$url/bdep-util.git" + git_clone "$url/libbbot.git" + git_clone "$url/bbot.git" + git_clone "$url/brep.git" + fi + + for m in "${mod[@]}"; do + git_clone "$mod_url/libbuild2-$m.git" + done + + # Build the bootstrap build system (b-boot). + # + run cd build2 + run make -f bootstrap.gmake CXX="$cxx" CXXFLAGS=-O3 -j 8 + run make -f bootstrap.gmake CXX="$cxx" CXXFLAGS=-O3 cleano # Cleanup objs. + run build2/b-boot --version + run cd - +fi + +run mkdir -p builds + +# The -libs configuration. +# +# Note that by doing this first we automatically make sure this will be their +# default/forwarded configuration. +# +if [ "$libs" ]; then + + run bpkg create -d "builds/$cfg-libs" cc cli \ + config.cli=cli \ + config.cxx="$cxx" \ + config.cc.coptions="$copt" \ + config.cc.loptions="$lopt" \ + config.bin.lib=shared \ + config.install.root=/tmp/install config.dist.root=/tmp/dist + + run bdep init -d libbutl -A "builds/$cfg-libs" "@$cfg-libs" + run bdep init -d libbpkg -A "builds/$cfg-libs" "@$cfg-libs" + + if [ "$extra" ]; then + run bdep init -d libbutl.bash -A "builds/$cfg-libs" "@$cfg-libs" + run bdep init -d libbbot -A "builds/$cfg-libs" "@$cfg-libs" + fi +fi + +# Relative and absolute configuration directories. +# +rd="builds/$cfg" +ad="$owd/$rd" + +# Build system configuration. +# +# Notes: +# +# 1. Using ?cli since this should be buildable by b-boot. +# +# 2. Only building shared libraries for speed of development. +# +run bpkg create -d "$rd" cc ?cli \ + config.cli=cli \ + config.cxx="$cxx" \ + config.cc.poptions="$popt" \ + config.cc.coptions="$copt" \ + config.cc.loptions="$lopt" \ + config.bin.lib=shared \ + config.install.root=/tmp/install config.dist.root=/tmp/dist + +run bdep init -d libbutl -A "$rd" "@$cfg" +run bdep init -d build2 -A "$rd" "@$cfg" +run bdep init -d libbpkg -A "$rd" "@$cfg" +run bdep init -d bpkg -A "$rd" "@$cfg" +run bdep init -d bdep -A "$rd" "@$cfg" + +if [ "$extra" ]; then + run bdep init -d libbutl.bash -A "$rd" "@$cfg" + run bdep init -d bpkg-util -A "$rd" "@$cfg" + run bdep init -d bdep-util -A "$rd" "@$cfg" + run bdep init -d libbbot -A "$rd" "@$cfg" + run bdep init -d bbot -A "$rd" "@$cfg" + run bdep init -d brep -A "$rd" "@$cfg" \ + ?sys:libapr1 ?sys:libapreq2 ?sys:libpq +fi + +# Generate database support (currently and temporarily handled with a script). +# +# Note: this has to be done after bdep-init since we need the libodb headers. +# We also have to pre-update version headers. +# +if [ $def ]; then + run bpkg update -d "$rd" libodb + run b "$rd/libbutl/libbutl/hxx{version}" + run b "$rd/libbpkg/libbpkg/hxx{version}" + run b "$rd/bpkg/bpkg/hxx{version common-options}" + run b "$rd/bdep/bdep/hxx{version common-options project-options}" + + run cd bpkg/bpkg + run ./odb.sh + run cd - + + run cd bdep/bdep + run ./odb.sh + run cd - + + if [ "$extra" ]; then + run b "$rd/brep/web/xhtml/hxx{version}" + run b "$rd/brep/libbrep/hxx{version}" + + run cd brep/libbrep + run ./odb.sh + run cd - + fi +fi + +if [ $def ]; then + run b build2/build2/ bpkg/bpkg/ bdep/bdep/ + run build2/build2/b --version + run bpkg/bpkg/bpkg --version + run bdep/bdep/bdep --version +else + run b "$rd/build2/build2/" "$rd/bpkg/bpkg/" "$rd/bdep/bdep/" + run "$rd/build2/build2/b" --version + run "$rd/bpkg/bpkg/bpkg" --version + run "$rd/bdep/bdep/bdep" --version +fi + +# Add symlinks. +# +if [ "$sym" ]; then + # Note that we symlink the actual executable in the build configuration + # rather than the backlink in the forwarded source to make the old binary + # runnable in the face of compilation errors (which trigger the removal of + # backlinks). + # + run sudo mkdir -p /usr/local/bin + run sudo ln -s "$owd/build2/build2/b-boot" /usr/local/bin/b-boot + run sudo ln -s "$ad/build2/build2/b" /usr/local/bin/b + run sudo ln -s "$ad/bpkg/bpkg/bpkg" /usr/local/bin/bpkg + run sudo ln -s "$ad/bdep/bdep/bdep" /usr/local/bin/bdep + + run export PATH="/usr/local/bin:$PATH" +else + run export PATH="$ad/build2/build2:$PATH" + run export PATH="$ad/bpkg/bpkg:$PATH" + run export PATH="$ad/bdep/bdep:$PATH" +fi + +run which b bpkg bdep + +# Re-run update using the bootstrapped toolchain (normally should be a +# noop). +# +if [ $def ]; then + run b build2/build2/ bpkg/bpkg/ bdep/bdep/ +else + run b "$rd/build2/build2/" "$rd/bpkg/bpkg/" "$rd/bdep/bdep/" +fi + +# Configure the modules. +# +for m in "${mod[@]}"; do + d="libbuild2-$m" + + run cd "$d" + + run bdep init --empty + run bdep config create @module "../$d-build/module/" --type build2 cc config.config.load=~build2 + run bdep config create @target "../$d-build/target/" cc config.cxx="$cxx" + + run bdep init @module -d "$d/" + + # See if this module requires bootstrap. + # + b=$(sed -rn -e 's/^\s*requires\s*:\s*bootstrap\s*$/true/p' "$d/manifest") + + if [ "$b" ]; then + info "module $d requires bootstrapping" + info "make sure ~/.build2/b.option contains the following line and press Enter" + info "!config.import.libbuild2_$m=$owd/$d-build/module/" + read + fi + + # Assume every package other than the module is a test. + # + # Note: sed regex is from the glue buildfile. + # + for t in $(sed -rn -e 's/^\s*location\s*:\s*(\S+)\s*$/\1/p' packages.manifest); do + if [ "$d/" = "$t" ]; then + continue + fi + + run bdep init @target -d "$t" + done + + run cd - +done |