# Installs lit, clones the git submodules, builds LDC and the test
# runners and runs the tests.
# Requires env variables EXTRA_CMAKE_FLAGS and PARALLELISM.
common_steps_template: &COMMON_STEPS_TEMPLATE
  install_lit_script: |
    # Install lit
    python3 -m pip install --user setuptools wheel
    # lit v0.11.1 is the latest version to work with Python v3.5 (from Ubuntu 16.04)
    python3 -m pip install --user lit==0.11.1
    python3 -c "import lit.main; lit.main.main();" --version . | head -n 1
  clone_submodules_script: |
    cd $CIRRUS_WORKING_DIR
    git submodule update --init --depth $CIRRUS_CLONE_DEPTH
  build_script: |
    # Build LDC & LDC D unittests & defaultlib unittest runners
    cmake --version
    ninja --version
    cd $CIRRUS_WORKING_DIR/..
    installDir=$PWD/install
    mkdir build
    cd build
    IFS=$'\n' extraFlags=( $(xargs -n1 <<<"$EXTRA_CMAKE_FLAGS") )
    cmake -G Ninja $CIRRUS_WORKING_DIR \
      -DCMAKE_BUILD_TYPE=Release \
      -DD_COMPILER=$PWD/../host-ldc/bin/ldmd2 \
      -DCMAKE_INSTALL_PREFIX=$installDir \
      -DINCLUDE_INSTALL_DIR=$installDir/import \
      -DLDC_LINK_MANUALLY=OFF \
      "${extraFlags[@]}"
    ninja -j$PARALLELISM all ldc2-unittest all-test-runners
    bin/ldc2 -version
  always:
    run_compiler_unittests_script: |
      cd $CIRRUS_WORKING_DIR/../build
      ctest --output-on-failure -R ldc2-unittest
    run_lit_testsuite_script: |
      cd $CIRRUS_WORKING_DIR/../build/tests
      python3 runlit.py -v -j $PARALLELISM .
    run_dmd_testsuite_script: |
      cd $CIRRUS_WORKING_DIR/../build
      DMD_TESTSUITE_MAKE_ARGS=-j$PARALLELISM ctest -V -R dmd-testsuite
    run_defaultlib_tests_script: |
      # Run defaultlib unittests & druntime integration tests
      cd $CIRRUS_WORKING_DIR/../build
      excludes="dmd-testsuite|ldc2-unittest|lit-tests"
      # FIXME: unittest failure for unclear reason
      if [ "$CI_OS" == "freebsd" ]; then
        excludes+='|^std.experimental.allocator-shared$'
      fi
      ctest -j$PARALLELISM --output-on-failure -E "$excludes"

# Installs Ubuntu 18.04+ prerequisites.
# Requires env variables HOST_LDC_VERSION and EXTRA_APT_PACKAGES.
install_ubuntu_prerequisites_template: &INSTALL_UBUNTU_PREREQUISITES_TEMPLATE
  install_prerequisites_script: |
    cd $CIRRUS_WORKING_DIR/..
    nproc
    export DEBIAN_FRONTEND=noninteractive
    if [[ "$EXTRA_CMAKE_FLAGS" = *-DMULTILIB?ON* ]]; then
      dpkg --add-architecture i386
      gcc_pkg="g++-multilib"
      libcurl_pkg="libcurl4 libcurl4:i386"
    else
      gcc_pkg="g++"
      libcurl_pkg="libcurl4"
    fi
    apt-get -q update
    apt-get -yq install \
      git-core cmake ninja-build $gcc_pkg \
      zlib1g-dev $libcurl_pkg curl gdb python3 python3-pip tzdata unzip zip \
      $EXTRA_APT_PACKAGES
    python3 --version
    # Download & extract host LDC
    curl -fL --retry 3 --max-time 300 -o ldc2.tar.xz https://github.com/ldc-developers/ldc/releases/download/v$HOST_LDC_VERSION/ldc2-$HOST_LDC_VERSION-linux-x86_64.tar.xz
    mkdir host-ldc
    tar -xf ldc2.tar.xz --strip 1 -C host-ldc
    rm ldc2.tar.xz

# Installs macOS prerequisites.
# Requires env variables HOST_LDC_VERSION and LLVM_VERSION.
install_macos_prerequisites_template: &INSTALL_MACOS_PREREQUISITES_TEMPLATE
  install_prerequisites_script: |
    cd $CIRRUS_WORKING_DIR/..
    sysctl -n hw.logicalcpu
    # Download & extract CMake
    curl -fL --retry 3 --max-time 300 -o cmake.tar.gz https://github.com/Kitware/CMake/releases/download/v3.20.3/cmake-3.20.3-macos-universal.tar.gz
    mkdir cmake
    tar -xf cmake.tar.gz --strip 3 -C cmake
    rm cmake.tar.gz
    # Download & extract Ninja
    curl -fL --retry 3 --max-time 60 -O https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-mac.zip
    mkdir ninja
    tar -xf ninja-mac.zip -C ninja
    rm ninja-mac.zip
    # Download & extract LDC-flavoured LLVM with enabled assertions
    curl -fL --retry 3 --max-time 300 -o llvm.tar.xz https://github.com/ldc-developers/llvm-project/releases/download/ldc-v$LLVM_VERSION/llvm-$LLVM_VERSION-osx-x86_64-withAsserts.tar.xz
    mkdir llvm
    tar -xf llvm.tar.xz --strip 1 -C llvm
    rm llvm.tar.xz
    # Download & extract host LDC
    curl -fL --retry 3 --max-time 300 -o ldc2.tar.xz https://github.com/ldc-developers/ldc/releases/download/v$HOST_LDC_VERSION/ldc2-$HOST_LDC_VERSION-osx-x86_64.tar.xz
    mkdir host-ldc
    tar -xf ldc2.tar.xz --strip 1 -C host-ldc
    rm ldc2.tar.xz
    # Install Python3
    brew install python
    python3 --version

environment:
  CIRRUS_CLONE_DEPTH: 50
  HOST_LDC_VERSION: 1.24.0

task:
  name: Ubuntu 18.04 x64 multilib rtSanitizers
  container:
    image: ubuntu:18.04
    cpu: 8
    memory: 16G
  timeout_in: 60m
  environment:
    CI_OS: linux
    EXTRA_APT_PACKAGES: "llvm-9-dev libclang-common-9-dev"
    EXTRA_CMAKE_FLAGS: "-DMULTILIB=ON -DRT_SUPPORT_SANITIZERS=ON -DBUILD_LTO_LIBS=ON"
    PARALLELISM: 8
  << : *INSTALL_UBUNTU_PREREQUISITES_TEMPLATE
  << : *COMMON_STEPS_TEMPLATE

task:
  name: Ubuntu rolling x64 shared-libs-only gdmd
  # allow failures - gdb v10 came with regressions
  allow_failures: true
  container:
    image: ubuntu:rolling
    cpu: 8
    memory: 16G
  timeout_in: 60m
  environment:
    CI_OS: linux
    EXTRA_APT_PACKAGES: "gdmd llvm-dev libclang-common-12-dev"
    EXTRA_CMAKE_FLAGS: "-DBUILD_SHARED_LIBS=ON -DBUILD_LTO_LIBS=ON -DD_COMPILER=gdmd -DLDC_LINK_MANUALLY=ON"
    PARALLELISM: 8
    # for gdmd:
    LANG: C.UTF-8
  << : *INSTALL_UBUNTU_PREREQUISITES_TEMPLATE
  << : *COMMON_STEPS_TEMPLATE

task:
  name: Ubuntu 18.04 x64 bootstrap
  container:
    image: ubuntu:18.04
    cpu: 8
    memory: 16G
  timeout_in: 60m
  environment:
    CI_OS: linux
    HOST_LDC_VERSION: 1.9.0
    EXTRA_APT_PACKAGES: "llvm-9-dev libclang-common-9-dev"
    EXTRA_CMAKE_FLAGS: "-DBUILD_LTO_LIBS=ON"
    PARALLELISM: 8
  << : *INSTALL_UBUNTU_PREREQUISITES_TEMPLATE
  << : *COMMON_STEPS_TEMPLATE

task:
  name: macOS 11 $TASK_NAME_SUFFIX
  osx_instance:
    image: big-sur-xcode
  timeout_in: 60m
  environment:
    CI_OS: osx
    LLVM_VERSION: 14.0.3
    # OS is preset to `darwin`
    OS: osx
    PATH: ${CIRRUS_WORKING_DIR}/../cmake/bin:${CIRRUS_WORKING_DIR}/../ninja:${CIRRUS_WORKING_DIR}/../llvm/bin:${PATH}
    PARALLELISM: 12
    matrix:
      - TASK_NAME_SUFFIX: x64
        EXTRA_CMAKE_FLAGS: "-DD_COMPILER_FLAGS=-gcc=/usr/bin/c++ -DBUILD_LTO_LIBS=ON"
      - TASK_NAME_SUFFIX: x64 shared-libs-only
        EXTRA_CMAKE_FLAGS: "-DD_COMPILER_FLAGS=-gcc=/usr/bin/c++ -DBUILD_LTO_LIBS=ON -DBUILD_SHARED_LIBS=ON"
  brew_cache:
    folder: "$HOME/Library/Caches/Homebrew"
  << : *INSTALL_MACOS_PREREQUISITES_TEMPLATE
  << : *COMMON_STEPS_TEMPLATE

task:
  name: FreeBSD 12.2 x64
  freebsd_instance:
    image_family: freebsd-12-2
    cpu: 4
    memory: 8G
  timeout_in: 60m
  environment:
    CI_OS: freebsd
    EXTRA_CMAKE_FLAGS: -DBUILD_LTO_LIBS=ON -DD_COMPILER_FLAGS="-O -flto=full -defaultlib=phobos2-ldc-lto,druntime-ldc-lto" -DEXTRA_CXXFLAGS=-flto=full
    PARALLELISM: 4
    GITHUB_TOKEN: ENCRYPTED[0955bd48c8d4e5391446fc0149d0719ad0b63df27ec9e6c180a5730a5b10dc7f28f09d1383423db158d21380ee2b022a]
    # use clang from the `llvm` ports package to be installed, incl. lld support for .deplibs (`pragma(lib, "execinfo")`)
    CC: clang90
  install_prerequisites_script: |
    cd $CIRRUS_WORKING_DIR/..
    sysctl -n hw.ncpu
    pkg install -y git cmake ninja gmake llvm bash gtar 7-zip
    python3 --version
    python3 -m ensurepip
    # Download & extract host LDC
    curl -fL --retry 3 --max-time 300 -o ldc2.tar.xz https://github.com/ldc-developers/ldc/releases/download/v$HOST_LDC_VERSION/ldc2-$HOST_LDC_VERSION-freebsd-x86_64.tar.xz
    mkdir pre-ldc
    gtar -xf ldc2.tar.xz --strip 1 -C pre-ldc
  clone_submodules_early_script: |
    cd $CIRRUS_WORKING_DIR
    git submodule update --init --depth $CIRRUS_CLONE_DEPTH
  # Build a first LDC as host compiler for the actual build
  build_bootstrap_ldc_script: |
    cd $CIRRUS_WORKING_DIR/..
    mkdir host-ldc
    cd host-ldc
    cmake -G Ninja $CIRRUS_WORKING_DIR \
      -DCMAKE_BUILD_TYPE=Release \
      -DD_COMPILER=$PWD/../pre-ldc/bin/ldmd2 \
      -DBUILD_SHARED_LIBS=OFF \
      -DBUILD_LTO_LIBS=ON
    ninja -j$PARALLELISM
    bin/ldc2 -version
  << : *COMMON_STEPS_TEMPLATE
  # Install LDC & make portable
  install_script: |
    cd $CIRRUS_WORKING_DIR/..
    cd build
    ninja install > /dev/null
    cd ..
    perl -pi -e s?$PWD/install/?%%ldcbinarypath%%/../?g install/etc/ldc2.conf
    perl -pi -e "s?,druntime-ldc\",?,druntime-ldc\", \"-gcc=$CC\",?" install/etc/ldc2.conf
    cp $CIRRUS_WORKING_DIR/{LICENSE,packaging/README} install
    cat install/etc/ldc2.conf
    # Now rename the installation dir to test portability
    mv install installed
  # Run hello-world integration test with shared libs
  run_shared_libs_integration_test_script: |
    cd $CIRRUS_WORKING_DIR/..
    echo 'void main() { import std.stdio; writefln("Hello world, %d bits", size_t.sizeof * 8); }' > hello.d
    installed/bin/ldc2 hello.d -m64 -of=hello64 -link-defaultlib-shared
    ./hello64
  # Run hello-world integration test with LTO
  run_lto_integration_test_script: |
    cd $CIRRUS_WORKING_DIR/..
    installed/bin/ldc2 hello.d -of=hello_thin -flto=thin -defaultlib=phobos2-ldc-lto,druntime-ldc-lto
    ./hello_thin
    installed/bin/ldc2 hello.d -of=hello_full -flto=full -defaultlib=phobos2-ldc-lto,druntime-ldc-lto
    ./hello_full
  # Run dynamic-compile integration test
  run_dynamic_compile_integration_test_script: |
    cd $CIRRUS_WORKING_DIR/..
    installed/bin/ldc2 -enable-dynamic-compile -run $CIRRUS_WORKING_DIR/tests/dynamiccompile/array.d
  # Run ImportC integration test
  run_importC_integration_test_script: |
    cd $CIRRUS_WORKING_DIR/..
    installed/bin/ldc2 -run $CIRRUS_WORKING_DIR/tests/d2/dmd-testsuite/runnable/test22597.c
  # Build & copy dub
  build_dub_script: |
    cd $CIRRUS_WORKING_DIR/..
    export DMD=$PWD/installed/bin/ldmd2
    git clone --recursive https://github.com/dlang/dub.git
    cd dub
    git checkout "$(cat $CIRRUS_WORKING_DIR/packaging/dub_version)"
    $DMD -run build.d -O -w -linkonce-templates
    cp bin/dub ../installed/bin
    ../installed/bin/dub --version
  # Build & copy dlang tools
  build_dlang_tools_script: |
    cd $CIRRUS_WORKING_DIR/..
    DMD=$PWD/installed/bin/ldmd2
    git clone --recursive https://github.com/dlang/tools.git dlang-tools
    cd dlang-tools
    git checkout "$(cat $CIRRUS_WORKING_DIR/packaging/dlang-tools_version)"
    mkdir bin
    $DMD -w -de -dip1000 rdmd.d -of=bin/rdmd
    $DMD -w -de -dip1000 ddemangle.d -of=bin/ddemangle
    $DMD -w -de -dip1000 DustMite/dustmite.d DustMite/splitter.d DustMite/polyhash.d -of=bin/dustmite
    cp bin/{rdmd,ddemangle,dustmite} ../installed/bin
  # Build & copy reggae
  build_reggae_script: |
    cd $CIRRUS_WORKING_DIR/..
    git clone --recursive https://github.com/atilaneves/reggae.git
    cd reggae
    git checkout "$(cat $CIRRUS_WORKING_DIR/packaging/reggae_version)"
    DFLAGS="-O -linkonce-templates" ../dub/bin/dub build -v --combined --compiler="$PWD/../installed/bin/ldc2"
    cp bin/reggae ../installed/bin
    ../installed/bin/reggae --version -b ninja
  # Pack artifact
  pack_artifact_script: |
    cd $CIRRUS_WORKING_DIR/..
    mkdir artifacts
    if [ -n "$CIRRUS_TAG" ]; then
      artifactID=${CIRRUS_TAG:1}
    else
      artifactID=${CIRRUS_CHANGE_IN_REPO:0:8}
    fi
    artifactName=ldc2-$artifactID-$CI_OS-x86_64
    mv installed $artifactName
    chmod -R go=rX $artifactName
    gtar -cf - --owner=0 --group=0 $artifactName | 7z a artifacts/$artifactName.tar.xz -si -txz -mx9
  # Upload to GitHub release (only for commits on the master branch and tags)
  upload_to_github_script: |
    cd $CIRRUS_WORKING_DIR
    if [ -n "$CIRRUS_TAG" ]; then
      tools/upload-to-github.sh $CIRRUS_TAG ../artifacts/ldc2-*.tar.xz
    elif [[ "$CIRRUS_PR" = "" && "$CIRRUS_BRANCH" = "master" ]]; then
      tools/upload-to-github.sh CI ../artifacts/ldc2-*.tar.xz
    fi
