#! /bin/sh # shellcheck disable=all # Serene Programming Language # # Copyright (c) 2019-2024 Sameer Rahmani # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, version 2. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # ----------------------------------------------------------------------------- # Commentary # ----------------------------------------------------------------------------- # This is the builder script for the Serene project. It makes it easier to # interact with the CMake build scripts. # # In order to define a subcommand all you need to do is to define a function # with the following syntax: # # function subcommand-name() { ## DESCRIPTION # .. subcommand body .. # } # # Make sure to provid one line of DESCRIPTION for the subcommand and use two "#" # characters to start the description following by a space. Otherwise, your # subcommand won't be registered # # shellcheck source=./utils.sh source "$ME/scripts/utils.sh" # ----------------------------------------------------------------------------- # CONFIG VARS # ----------------------------------------------------------------------------- # By default Clang is the compiler that we use and support. But you may use # whatever you want. But just be aware of the fact that we might not be able # to help you in case of any issue. if [[ "$CC" = "" ]]; then CC=$(which clang || echo "Clang_not_found") export CC fi if [[ "$CXX" = "" ]]; then CXX=$(which clang++ || echo "Clang++_not_found") export CXX fi # Serene subprojects. We use this array to run common tasks on all the projects # like running the test cases PROJECTS=(libserene serenec serene-repl serene-tblgen) # TODO: Add sloppiness to the cmake list file as well CCACHE_SLOPPINESS="pch_defines,time_macros" export CCACHE_SLOPPINESS ASAN_OPTIONS=check_initialization_order=1 export ASAN_OPTIONS LSAN_OPTIONS=suppressions="$ME/.ignore_sanitize" export LSAN_OPTIONS # ----------------------------------------------------------------------------- # Helper functions # ----------------------------------------------------------------------------- function gen_precompile_header_index() { { echo "// DO NOT EDIT THIS FILE: It is aute generated by './builder gen_precompile_index'" echo "#ifndef SERENE_PRECOMPIL_H" echo "#define SERENE_PRECOMPIL_H" grep -oP "#include .llvm/.*" . -R|cut -d':' -f2|tail +2 grep -oP "#include .mlir/.*" . -R|cut -d':' -f2|tail +2 echo "#endif" } > ./include/serene_precompiles.h } function pushed_build() { mkdir -p "$BUILD_DIR" pushd "$BUILD_DIR" > /dev/null || return } function popd_build() { popd > /dev/null || return } function build-gen() { local args args=( ) pushed_build info "Running: " info "cmake -G Ninja" "${args[@]}" "$ME" "${@:2}" cmake -G Ninja "${args[@]}" \ "$ME" \ "${@:2}" popd_build } # ----------------------------------------------------------------------------- # Subcomaands # ----------------------------------------------------------------------------- function compile() { ## Compiles the project using the generated build scripts pushed_build cmake --build . --parallel popd_build } function build() { ## Builds the project by regenerating the build scripts local cpus rm -rf "$BUILD_DIR" build-gen "debug" "$@" pushed_build cpus=$(nproc) cmake --build . -j "$cpus" popd_build } function build-20() { ## Builds the project using C++20 (will regenerate the build) rm -rf "$BUILD_DIR" pushed_build build-gen "debug" -DCPP_20_SUPPORT=ON "$@" cmake --build . popd_build } function build-tidy() { ## Builds the project using clang-tidy (It takes longer than usual) build "-DSERENE_ENABLE_TIDY=ON" "${@:2}" } function build-release() { ## Builds the project in "Release" mode rm -rf "$BUILD_DIR" pushed_build build-gen "release" "$@" cmake --build . --config Release popd_build } function build-docs() { ## Builds the documentation of Serene rm -rf "$BUILD_DIR" pip install -r "$ME/docs/requirements.txt" pushed_build build-gen "debug" -DSERENE_ENABLE_DOCS=ON "$@" cmake --build . --parallel popd_build } function serve-docs() { ## Serve the docs directory from build dir python -m http.server --directory "$BUILD_DIR/docs/sphinx/" } function clean() { ## Cleans up the source dir and removes the build git clean -dxf } function run() { ## Runs `serene` and passes all the given aruguments to it "$BUILD_DIR"/serene/serene "$@" } function lldb-run() { ## Runs `serenec` under lldb lldb -- "$BUILD_DIR"/serenec/serenec "$@" } function repl() { ## Runs `serene-repl` and passes all the given aruguments to it "$BUILD_DIR"/serene-repl/serene-repl "$@" } function memcheck-serene() { ## Runs `valgrind` to check `serenec` birany export ASAN_FLAG="" build pushed_build valgrind --tool=memcheck --leak-check=yes --trace-children=yes "$BUILD_DIR"/bin/serenec "$@" popd_build } function tests() { ## Runs all the test cases if [[ "$1" == "all" || "$1" == "" ]]; then info "Run the entire test suit" for proj in "${PROJECTS[@]}"; do local test_file="$BUILD_DIR/$proj/tests/${proj}Tests" if [[ -f "$test_file" ]]; then eval "$test_file ${*:2}" fi done else eval "$BUILD_DIR/$1/tests/$1Tests ${*:2}" fi } function build-tests() { ## Generates and build the project including the test cases rm -rf "$BUILD_DIR" pushed_build build-gen "debug" -DSERENE_BUILD_TESTING=ON "$@" cmake --build . --parallel popd_build } function setup() { ## Setup the working directory and make it ready for development local args if [[ "$SERENE_CI" == "true" ]]; then args=--break-system-packages fi if command -v python3 >/dev/null 2>&1; then pip install "$args" pre-commit pre-commit install else error "Python is required to setup pre-commit" fi } function scan-build() { ## Runs the `scan-build` utility to analyze the build process rm -rf "$BUILD_DIR" build-gen pushed_build # The scan-build utility scans the build for bugs checkout the man page scan-build --force-analyze-debug-code --use-analyzer="$CC" cmake --build . popd_build } function help() { ## Print out this help message echo "Commands:" grep -E '^function [a-zA-Z0-9_-]+\(\) \{ ## .*$$' "$ME/scripts/functions.sh" | \ sort | \ sed 's/^function \([a-zA-Z0-9_-]*\)() { ## \(.*\)/\1:\2/' | \ awk 'BEGIN {FS=":"}; {printf "\033[36m%-30s\033[0m %s\n", $1, $2}' }