Skip to content
代码片段 群组 项目
build.sh 12.9 KB
更新 更旧
  • 了解如何忽略特定修订
  • #!/usr/bin/env bash
    
    
    #
    # variables
    #
    
    RESET="\033[0m"
    RED="\033[0;31m"
    YELLOW="\033[0;33m"
    
    DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    
    ci=false
    
    verbosity='minimal'
    
    run_build=true
    run_pack=false
    run_tests=false
    build_all=false
    
    build_repo_tasks=true
    
    build_managed=''
    build_native=''
    build_nodejs=''
    build_java=''
    
    build_installers=''
    
    build_projects=''
    
    configuration=''
    
    dotnet_runtime_source_feed=''
    dotnet_runtime_source_feed_key=''
    
    
    if [ "$(uname)" = "Darwin" ]; then
        target_os_name='osx'
    else
        target_os_name='linux'
    fi
    
    
    msbuild_args=()
    
    #
    # Functions
    #
    __usage() {
        echo "Usage: $(basename "${BASH_SOURCE[0]}") [options] [[--] <Arguments>...]
    
    Arguments:
    
        <Arguments>...                    Arguments passed to the command. Variable number of arguments allowed.
    
        --configuration|-c                The build configuration (Debug, Release). Default=Debug
        --arch                            The CPU architecture to build for (x64, arm, arm64). Default=$target_arch
        --os-name                         The base runtime identifier to build for (linux, osx, linux-musl). Default=$target_os_name
    
        --[no-]restore                    Run restore.
        --[no-]build                      Compile projects. (Implies --no-restore)
        --[no-]pack                       Produce packages.
        --[no-]test                       Run tests.
    
        --projects                        A list of projects to build. (Must be an absolute path.)
                                          Globbing patterns are supported, such as \"$(pwd)/**/*.csproj\".
        --no-build-deps                   Do not build project-to-project references and only build the specified project.
        --no-build-repo-tasks             Suppress building RepoTasks.
    
        --all                             Build all project types.
    
        --[no-]build-native               Build native projects (C, C++). Ignored in most cases i.e. with `dotnet msbuild`.
    
        --[no-]build-managed              Build managed projects (C#, F#, VB).
        --[no-]build-nodejs               Build NodeJS projects (TypeScript, JS).
        --[no-]build-java                 Build Java projects.
        --[no-]build-installers           Build Java projects.
    
        --ci                              Apply CI specific settings and environment variables.
        --binarylog|-bl                   Use a binary logger
    
        --excludeCIBinarylog              Don't output binary log by default in CI builds (short: -nobl).
    
        --verbosity|-v                    MSBuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]
    
        --dotnet-runtime-source-feed      Additional feed that can be used when downloading .NET runtimes
        --dotnet-runtime-source-feed-key  Key for feed that can be used when downloading .NET runtimes
    
    
    Description:
        This build script installs required tools and runs an MSBuild command on this repository
        This script can be used to invoke various targets, such as targets to produce packages
        build projects, run tests, and generate code.
    "
    
        if [[ "${1:-}" != '--no-exit' ]]; then
            exit 2
        fi
    }
    
    __error() {
        echo -e "${RED}error: $*${RESET}" 1>&2
    }
    
    __warn() {
        echo -e "${YELLOW}warning: $*${RESET}"
    }
    
    #
    # main
    #
    
    while [[ $# -gt 0 ]]; do
    
        opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')"
        case "$opt" in
            -\?|-h|-help)
    
                __usage --no-exit
                exit 0
                ;;
    
            -configuration|-c)
                shift
                configuration="${1:-}"
                [ -z "$configuration" ] && __error "Missing value for parameter --configuration" && __usage
                ;;
            -arch)
    
                shift
                target_arch="${1:-}"
                [ -z "$target_arch" ] && __error "Missing value for parameter --arch" && __usage
                ;;
    
            -os-name|-osname)
    
                shift
                target_os_name="${1:-}"
                [ -z "$target_os_name" ] && __error "Missing value for parameter --os-name" && __usage
                ;;
    
                run_restore=true
                ;;
    
            -no-restore|-norestore)
    
                run_restore=false
                ;;
    
                run_build=true
                ;;
    
            -no-build|-nobuild)
    
                run_build=false
    
                [ -z "$run_restore" ] && run_restore=false
    
            -no-build-deps|-nobuilddeps)
    
                run_pack=true
                ;;
    
            -no-pack|-nopack)
    
                run_pack=false
                ;;
    
                run_tests=true
                ;;
    
            -no-test|-notest)
    
                run_tests=false
                ;;
    
                shift
                build_projects="${1:-}"
                [ -z "$build_projects" ] && __error "Missing value for parameter --projects" && __usage
                ;;
    
                build_all=true
                ;;
    
            -build-managed|-buildmanaged)
    
                build_managed=true
                ;;
    
            -no-build-managed|-nobuildmanaged)
    
            -build-nodejs|-buildnodejs)
    
                build_nodejs=true
                ;;
    
            -no-build-nodejs|-nobuildnodejs)
    
            -build-java|-buildjava)
    
            -no-build-java|-nobuildjava)
    
            -build-native|-buildnative)
    
            -no-build-native|-nobuildnative)
    
            -build-installers|-buildinstallers)
                build_installers=true
                ;;
            -no-build-installers|-nobuildinstallers)
                build_installers=false
                ;;
            -no-build-repo-tasks|-nobuildrepotasks)
                build_repo_tasks=false
                ;;
    
            -arch)
                shift
                target_arch="${1:-}"
                [ -z "$target_arch" ] && __error "Missing value for parameter --arch" && __usage
                ;;
    
            -binarylog|-bl)
    
                binary_log=true
                ;;
            -excludeCIBinarylog|-nobl)
                exclude_ci_binary_log=true
    
            -dotnet-runtime-source-feed|-dotnetruntimesourcefeed)
    
                [ -z "${1:-}" ] && __error "Missing value for parameter --dotnet-runtime-source-feed" && __usage
                dotnet_runtime_source_feed="${1:-}"
                ;;
            -dotnet-runtime-source-feed-key|-dotnetruntimesourcefeedkey)
                shift
                [ -z "${1:-}" ] && __error "Missing value for parameter --dotnet-runtime-source-feed-key" && __usage
                dotnet_runtime_source_feed_key="${1:-}"
    
                ;;
            *)
                msbuild_args[${#msbuild_args[*]}]="$1"
                ;;
        esac
        shift
    done
    
    if [ "$build_all" = true ]; then
        msbuild_args[${#msbuild_args[*]}]="-p:BuildAllProjects=true"
    
    fi
    
    if [ ! -z "$build_projects" ]; then
    
        msbuild_args[${#msbuild_args[*]}]="-p:ProjectToBuild=$build_projects"
    
    elif [ "$build_all" != true ] && [ -z "$build_managed$build_nodejs$build_java$build_native$build_installers" ]; then
    
        # This goal of this is to pick a sensible default for `build.sh` with zero arguments.
        # We believe the most common thing our contributors will work on is C#, so if no other build group was picked, build the C# projects.
    
        __warn "No default group of projects was specified, so building the 'managed' and its dependent subset of projects. Run ``build.sh --help`` for more details."
    
    if [ "$build_deps" = false ]; then
        msbuild_args[${#msbuild_args[*]}]="-p:BuildProjectReferences=false"
    fi
    
    
    if [ "$build_managed" = true ] || ([ "$build_all" = true ] && [ "$build_managed" != false ]); then
    
        if [ -z "$build_nodejs" ]; then
            if [ -x "$(command -v node)" ]; then
                __warn "Building of C# project is enabled and has dependencies on NodeJS projects. Building of NodeJS projects is enabled since node is detected on PATH."
            else
                __warn "Building of NodeJS projects is disabled since node is not detected on Path and no BuildNodeJs or NoBuildNodeJs setting is set explicitly."
                build_nodejs=false
            fi
        fi
    
        if [ "$build_nodejs" = false ]; then
            __warn "Some managed projects depend on NodeJS projects. Building NodeJS is disabled so the managed projects will fallback to using the output from previous builds. The output may not be correct or up to date."
        fi
    fi
    
    
    # Only set these MSBuild properties if they were explicitly set by build parameters.
    [ ! -z "$build_java" ] && msbuild_args[${#msbuild_args[*]}]="-p:BuildJava=$build_java"
    [ ! -z "$build_native" ] && msbuild_args[${#msbuild_args[*]}]="-p:BuildNative=$build_native"
    [ ! -z "$build_nodejs" ] && msbuild_args[${#msbuild_args[*]}]="-p:BuildNodeJS=$build_nodejs"
    [ ! -z "$build_managed" ] && msbuild_args[${#msbuild_args[*]}]="-p:BuildManaged=$build_managed"
    
    [ ! -z "$build_installers" ] && msbuild_args[${#msbuild_args[*]}]="-p:BuildInstallers=$build_installers"
    
    # Run restore by default unless --no-restore or --no-build was specified.
    [ -z "$run_restore" ] && run_restore=true
    
    
    msbuild_args[${#msbuild_args[*]}]="-p:Restore=$run_restore"
    msbuild_args[${#msbuild_args[*]}]="-p:Build=$run_build"
    if [ "$run_build" = false ]; then
        msbuild_args[${#msbuild_args[*]}]="-p:NoBuild=true"
    fi
    msbuild_args[${#msbuild_args[*]}]="-p:Pack=$run_pack"
    msbuild_args[${#msbuild_args[*]}]="-p:Test=$run_tests"
    
    msbuild_args[${#msbuild_args[*]}]="-p:TargetArchitecture=$target_arch"
    msbuild_args[${#msbuild_args[*]}]="-p:TargetOsName=$target_os_name"
    
    
    if [ -z "$configuration" ]; then
        if [ "$ci" = true ]; then
            configuration='Release'
        else
            configuration='Debug'
        fi
    fi
    msbuild_args[${#msbuild_args[*]}]="-p:Configuration=$configuration"
    
    
    # Set up additional runtime args
    toolset_build_args=()
    
    if [ ! -z "$dotnet_runtime_source_feed$dotnet_runtime_source_feed_key" ]; then
    
        runtimeFeedArg="/p:DotNetRuntimeSourceFeed=$dotnet_runtime_source_feed"
        runtimeFeedKeyArg="/p:DotNetRuntimeSourceFeedKey=$dotnet_runtime_source_feed_key"
        msbuild_args[${#msbuild_args[*]}]=$runtimeFeedArg
        msbuild_args[${#msbuild_args[*]}]=$runtimeFeedKeyArg
        toolset_build_args[${#toolset_build_args[*]}]=$runtimeFeedArg
        toolset_build_args[${#toolset_build_args[*]}]=$runtimeFeedKeyArg
    fi
    
    
    # Initialize global variables need to be set before the import of Arcade is imported
    restore=$run_restore
    
    # Disable node reuse - Workaround perpetual issues in node reuse and custom task assemblies
    nodeReuse=false
    export MSBUILDDISABLENODEREUSE=1
    
    # Our build often has warnings that we can't fix
    
    # Fixing this is tracked by https://github.com/dotnet/aspnetcore-internal/issues/601
    
    warn_as_error=false
    
    
    # Ensure passing neither --bl nor --nobl on CI avoids errors in tools.sh. This is needed because we set both variables
    # to false by default i.e. they always exist. (We currently avoid binary logs but that is made visible in the YAML.)
    if [[ "$ci" == true && "$exclude_ci_binary_log" == false ]]; then
        binary_log=true
    
    fi
    
    # increase file descriptor limit on macOS
    if [ "$(uname)" = "Darwin" ]; then
        ulimit -n 10000
    fi
    
    # Import Arcade
    . "$DIR/eng/common/tools.sh"
    
    
    Doug Bunting's avatar
    Doug Bunting 已提交
    # Add default .binlog location if not already on the command line. tools.sh does not handle this; it just checks
    # $binary_log, $ci and $exclude_ci_binary_log values for an error case.
    if [[ "$binary_log" == true ]]; then
        found=false
        for arg in "${msbuild_args[@]}"; do
            opt="$(echo "${arg/#--/-}" | awk '{print tolower($0)}')"
            if [[ "$opt" == [-/]bl:* || "$opt" == [-/]binarylogger:* ]]; then
                found=true
                break
            fi
        done
        if [[ "$found" == false ]]; then
            msbuild_args[${#msbuild_args[*]}]="/bl:$log_dir/Build.binlog"
        fi
    fi
    
    
    # Capture MSBuild crash logs
    export MSBUILDDEBUGPATH="$log_dir"
    
    # Set this global property so Arcade will always initialize the toolset. The error message you get when you build on a clean machine
    # with -norestore is not obvious about what to do to fix it. As initialization takes very little time, we think always initializing
    # the toolset is a better default behavior.
    _tmp_restore=$restore
    restore=true
    
    InitializeToolset
    
    restore=$_tmp_restore=
    
    if [ "$build_repo_tasks" = true ]; then
        MSBuild $_InitializeToolset \
            -p:RepoRoot="$repo_root" \
            -p:Projects="$DIR/eng/tools/RepoTasks/RepoTasks.csproj" \
            -p:Configuration=Release \
            -p:Restore=$run_restore \
            -p:Build=true \
    
            -clp:NoSummary \
            ${toolset_build_args[@]+"${toolset_build_args[@]}"}
    
    # This incantation avoids unbound variable issues if msbuild_args is empty
    # https://stackoverflow.com/questions/7577052/bash-empty-array-expansion-with-set-u
    
    MSBuild $_InitializeToolset -p:RepoRoot="$repo_root" ${msbuild_args[@]+"${msbuild_args[@]}"}
    
    ExitWithExitCode 0