#! /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 environment. # # Note that this script runs git-update-index commands specified in the # README-GIT files of cloned repositories. # # This script assumes the following steps have been performed: # # 1. The latest staged toolchain has been temporarily installed somewhere # other than /usr/local (e.g., /tmp/build2) and is in PATH. Hint: use # --local to speed things up seeing that this is a throw-away installation. # # 2. The CLI and ODB compilers have been built and are either installed (if # you don't plan to contribute to them) or symlinked in /usr/local/bin/. # For the latter case they would typically go to ~/work/{cli,odb/}, for # example, for CLI: # # NOTE: clone using the git.codesynthesis.com:/var/scm/... SSH URL for rw # access. # # mkdir -p ~/work/cli # cd ~/work/cli # git clone --recursive https://git.codesynthesis.com/cli/cli.git # cd cli # bdep init -C ../builds/gccN-asan @gccN-asan cc \ # config.cxx=g++-N \ # config.cc.coptions="-Wall -Wextra -Werror -g3 -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer" # b # sudo ln -s "$(pwd)/cli/cli" /usr/local/bin/cli # which cli # cli --version # # For ODB (no sanitizer use is currently possible due to the way GCC is # built): # # mkdir -p ~/work/odb # cd ~/work/odb # git clone --recursive https://git.codesynthesis.com/odb/odb.git # cd odb # bdep init -C ../builds/gccN-asan @gccN-asan cc \ # config.cxx=g++-N \ # config.cc.coptions="-Wall -Wextra -Werror -g3" # b # sudo ln -s "$(pwd)/odb/odb" /usr/local/bin/odb # sudo ln -s "$(pwd)/odb/odb.so" /usr/local/bin/odb.so # which odb # odb --version # # Once this is done, you should be able to: # # NOTE: clone using the git.build2.org:/var/scm/... SSH URL and pass the # --ssh bootstrap option for rw access. # # mkdir -p ~/work/build2 # cd ~/work/build2 # git clone --recursive https://git.build2.org/etc.git # PATH="/tmp/build2/bin:$PATH" etc/bootstrap # # After a successful bootstrap you can remove the staged toolchain. # # Also a few notes and tips on the development process: Because the toolchain # is used for its own development you will sometimes find yourself in a # situation where one or more tools in the toolchain are no longer runnable or # functioning correctly but to fix this you need to be able to run those # tools. This can happen, for example, because of the linking errors or # because the version (and therefore the name) of one of the shared libraries # has changed as a result of updating another part of a toolchain (for # instance, updating bpkg can trigger an update of libbpkg and this could make # bdep, which also depends on libbpkg, no longer runnable). # # There are several mechanisms for recovering from such situations. If the # build system is functional, it itself and the rest of the toolchain can # always be update by first disabling the auto-synchronization hooks (which # invoke bdep and bpkg). For example, the following commands should get the # toolchain back into the fully-functional state: # # BDEP_SYNC=0 b build2/build2/ bpkg/bpkg/ bdep/bdep/ # b build2/build2/ bpkg/bpkg/ bdep/bdep/ # # If the build system itself is not functional, it can always be rebuilt using # the bootstrapped build system (b-boot). For example: # # BDEP_SYNC=0 b-boot build2/build2/ # BDEP_SYNC=0 b build2/build2/ # # Note that the bootstrap build system can only be used to update build2. It # also makes sense to rebuild it from time to time to keep it reasonably up to # date with master. Normally this is done when master is assumed to be in a # reasonably good shape. See build2/INSTALL for details on the bootstrap build # system. # # Options: # # --ssh # Use SSH URL for cloning (rw access). # # --no-symlink # Do not create executable symlinks in /usr/local/bin/. # # --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). # # --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. # 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" sym=true clone=true cxx=g++ cfg=gcc while [ $# -gt 0 ]; do case $1 in --ssh) url="git.build2.org:/var/scm" shift ;; --no-symlink) sym= shift ;; --no-clone) clone= shift ;; --cxx) shift cxx="$1" shift ;; --cfg) shift cfg="$1" shift ;; *) error "unexpected $1" ;; esac done function git_clone () # { local u d l u="$1" d="$(basename -s .git "$u")" run git clone --recursive "$u" # 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" ]; 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" # 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 # @@ TODO: make build system configuration ASAN/TSAN configurable. # # ASAN: -g3 -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer # TSAN: -g3 -fsanitize=thread run mkdir -p builds # 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 "builds/$cfg-asan-bs" cc ?cli \ config.cxx="$cxx" \ config.cc.coptions="-Wall -Wextra -Werror -g3 -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer" \ config.cc.loptions="-fuse-ld=gold -Wl,--threads,--thread-count,4" \ config.bin.lib=shared \ config.install.root=/tmp/install config.dist.root=/tmp/dist run bdep init -d libbutl -A "builds/$cfg-asan-bs" "@$cfg-asan-bs" --no-default run bdep init -d build2 -A "builds/$cfg-asan-bs" "@$cfg-asan-bs" run b build2/build2/ run build2/build2/b --version # Package manager (and the rest of the toolchain) configuration. # run bpkg create -d "builds/$cfg-asan-pm" cc cli \ config.cxx="$cxx" \ config.cc.coptions="-Wall -Wextra -Werror -g3 -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer" \ config.cc.loptions="-fuse-ld=gold -Wl,--threads,--thread-count,4" \ config.bin.lib=shared \ config.install.root=/tmp/install config.dist.root=/tmp/dist run bdep init -d libbutl -A "builds/$cfg-asan-pm" "@$cfg-asan-pm" --default run bdep init -d libbpkg -A "builds/$cfg-asan-pm" "@$cfg-asan-pm" run bdep init -d bpkg -A "builds/$cfg-asan-pm" "@$cfg-asan-pm" run bdep init -d bdep -A "builds/$cfg-asan-pm" "@$cfg-asan-pm" # 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. # run bpkg update -d builds/$cfg-asan-pm libodb run b "builds/$cfg-asan-pm/libbutl/libbutl/hxx{version}" run b "builds/$cfg-asan-pm/libbpkg/libbpkg/hxx{version}" run b "builds/$cfg-asan-pm/bpkg/bpkg/hxx{version common-options}" run b "builds/$cfg-asan-pm/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 - run b bpkg/bpkg/ bdep/bdep/ run bpkg/bpkg/bpkg --version run bdep/bdep/bdep --version # Add symlinks. # if [ "$sym" ]; then run sudo ln -s "$owd/build2/build2/b" /usr/local/bin/b run sudo ln -s "$owd/build2/build2/b-boot" /usr/local/bin/b-boot run sudo ln -s "$owd/bpkg/bpkg/bpkg" /usr/local/bin/bpkg run sudo ln -s "$owd/bdep/bdep/bdep" /usr/local/bin/bdep run export PATH="/usr/local/bin:$PATH" run which b bpkg bdep # Re-run update using the bootstrapped toolchain (normally should be a # noop). # run b build2/build2/ bpkg/bpkg/ bdep/bdep/ fi