yolo #24
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: C++ CI | |
on: | |
push: | |
branches: ['*'] # NOTE: replace/update with appropriate branch name(s) | |
tags: ['*'] | |
pull_request: | |
branches: ['*'] # NOTE: replace/update with appropriate branch name(s) | |
workflow_dispatch: | |
inputs: | |
build_type: | |
description: Build type | |
required: false | |
default: 'Debug' | |
type: choice | |
options: | |
- Debug | |
- Release | |
- RelWithDebInfo | |
- MinSizeRel | |
env: | |
BUILD_TYPE: ${{ inputs.build_type || 'Debug' }} | |
# NOTE: update executable name if it is changed in CMakeLists.txt | |
EXECUTABLE_NAME: "oop" | |
INPUT_FILENAME: "tastatura.txt" | |
BUILD_DIR: "build" | |
EXT_DIR: "ext" | |
BIN_DIR: "bin" | |
GEN_DIR: "generated" | |
defaults: | |
run: | |
# Use a bash shell, so we can use the same syntax for environment variable | |
# access regardless of the host operating system | |
# https://github.com/saxbophone/CPP20-Cross-Platform-Template | |
shell: bash | |
jobs: | |
cppcheck: | |
name: "Cppcheck" | |
runs-on: ubuntu-22.04 | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@v4 | |
- name: Install cppcheck | |
run: | | |
sudo apt-get update | |
sudo apt-get install --no-install-recommends cppcheck | |
- name: Install protobuf | |
run: | | |
sudo apt-get update | |
sudo apt-get install -y --no-install-recommends \ | |
libprotobuf-dev libprotoc-dev protobuf-compiler | |
# The flag CMAKE_EXPORT_COMPILE_COMMANDS generates compile_commands.json | |
# which is used by cppcheck and clang-tidy | |
- name: Configure CMake | |
uses: ./.github/actions/configure-cmake | |
with: | |
custom_flags: '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON' | |
- name: Cppcheck | |
run: | | |
cppcheck --enable=all \ | |
--inline-suppr \ | |
--project="${BUILD_DIR}"/compile_commands.json \ | |
-i"${BUILD_DIR}" --suppress='*:"${BUILD_DIR}"/*' \ | |
-i"${EXT_DIR}" --suppress='*:"${EXT_DIR}"/*' \ | |
-i"${GEN_DIR}" --suppress='*:"${GEN_DIR}"/*' \ | |
--suppress=missingIncludeSystem \ | |
--suppress=unmatchedSuppression \ | |
--suppress=useStlAlgorithm \ | |
--error-exitcode=1 | |
clang-tidy: | |
name: "Clang-Tidy" | |
runs-on: ubuntu-22.04 | |
env: | |
CC: clang-17 | |
CXX: clang++-17 | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@v4 | |
# Also see https://github.com/actions/runner-images/discussions/9446#discussioncomment-8668538 | |
- name: Install Clang 17 | |
run: | | |
wget https://apt.llvm.org/llvm.sh | |
chmod +x ./llvm.sh | |
sudo ./llvm.sh 17 | |
- name: Install clang-tidy | |
run: | | |
sudo apt-get update | |
sudo apt-get install --no-install-recommends clang-tidy-17 libc++-17-dev libc++abi-17-dev | |
- name: Install protobuf | |
run: | | |
sudo apt-get update | |
sudo apt-get install -y --no-install-recommends \ | |
libprotobuf-dev libprotoc-dev protobuf-compiler=3.15.0 | |
- name: Configure CMake | |
uses: ./.github/actions/configure-cmake | |
with: | |
custom_flags: '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON' | |
- name: Clang-Tidy | |
continue-on-error: true | |
# clang-tidy is not able to follow symbolic links: https://bugs.llvm.org/show_bug.cgi?id=47460 | |
# need to use | as sed separator because / is used in paths | |
run: | | |
sed -i "s|$(which ${CXX})|$(realpath $(which ${CXX}))|g" "${BUILD_DIR}"/compile_commands.json | |
cat "${BUILD_DIR}"/compile_commands.json | | |
jq -r '.[] | .file' | # select source file paths from CMake project; -r to strip quotes | |
grep -v "/${BUILD_DIR}/_deps/" | # ignore external dependencies | |
xargs clang-tidy-17 -p "${BUILD_DIR}" | |
build: | |
name: ${{ matrix.name }} | |
runs-on: ${{ matrix.os }} | |
timeout-minutes: 10 | |
permissions: | |
contents: write | |
env: | |
CC: ${{ matrix.c }} | |
CXX: ${{ matrix.cxx }} | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- os: ubuntu-22.04 | |
c: clang-17 | |
cxx: clang++-17 | |
name: "MSan: Ubuntu 22.04 Clang 17" | |
# cmake_flags: | |
cmake_generator: Ninja | |
# This env runs memory sanitizers | |
runs_msan: true | |
- os: ubuntu-22.04 | |
c: gcc-12 | |
cxx: g++-12 | |
name: "ASan: Ubuntu 22.04 GCC 12" | |
# cmake_flags: | |
cmake_generator: Ninja | |
# This env runs address sanitizers | |
runs_asan: true | |
- os: ubuntu-22.04 | |
c: gcc-11 | |
cxx: g++-11 | |
name: "Valgrind: Ubuntu 22.04 GCC 11" | |
# cmake_flags: | |
cmake_generator: Ninja | |
# This env runs valgrind | |
runs_valgrind: true | |
- os: macos-12 | |
c: clang | |
cxx: clang++ | |
name: "ASan: macOS 12 Apple Clang 14" | |
# cmake_flags: | |
# cmake_generator: | |
# This env runs address sanitizers | |
runs_asan: true | |
- os: macos-12 | |
c: gcc-12 | |
cxx: g++-12 | |
name: "macOS 12 GCC 12" | |
# cmake_flags: | |
# cmake_generator: Ninja | |
- os: windows-2022 | |
c: cl | |
cxx: cl | |
name: "ASan: Windows 2022 MSVC 19.38" | |
# cmake_flags: | |
# cmake_generator: Ninja | |
# This env runs address sanitizers | |
runs_asan: true | |
- os: windows-2022 | |
c: gcc | |
cxx: g++ | |
name: "Windows 2022 MinGW GCC 12" | |
# cmake_flags: | |
cmake_generator: Ninja | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@v4 | |
- name: Prepare env | |
run: | | |
echo ${GITHUB_WORKSPACE} | |
mkdir ${GITHUB_WORKSPACE}/artifacts | |
- name: Set timestamp and zip name | |
run: | | |
echo "TIMESTAMP=$(date +%Y-%m-%d-%H-%M-%S)" >> ${GITHUB_ENV} | |
# use the full name as prefix: {user_name}_{repo_name} (replace / with _) | |
echo "ZIP_NAME=$(echo "${GITHUB_REPOSITORY}_${{ env.BUILD_TYPE }}_${{ matrix.os }}_${{ matrix.cxx }}" | sed 's|/|_|')" >> ${GITHUB_ENV} | |
# or use only the repo name (github does not have a predefined environment variable for this) | |
# the regex splits by / and keeps everything after / without the / character | |
# echo "ZIP_NAME=$(echo "${GITHUB_REPOSITORY}_${{ env.BUILD_TYPE }}_${{ matrix.os }}_${{ matrix.cxx }}" | sed -E 's|.+/(.+)|\1|')" >> ${GITHUB_ENV} | |
# Common Linux dependencies | |
- name: Install Linux Dependencies | |
if: runner.os == 'Linux' | |
run: | | |
sudo apt-get update | |
sudo apt-get install ninja-build | |
# Also see https://github.com/actions/runner-images/discussions/9446#discussioncomment-8668538 | |
- name: Install Clang 17 | |
if: runner.os == 'Linux' && matrix.runs_msan == true | |
run: | | |
wget https://apt.llvm.org/llvm.sh | |
chmod +x ./llvm.sh | |
sudo ./llvm.sh 17 | |
- name: Install libc++ (Linux Clang 17) | |
if: runner.os == 'Linux' && matrix.runs_msan == true | |
run: | | |
# sudo apt-get update | |
sudo apt-get install --no-install-recommends libc++-17-dev libc++abi-17-dev | |
- name: Install ninja (Windows) | |
if: runner.os == 'Windows' | |
run: | | |
choco install ninja | |
- name: Install valgrind | |
if: runner.os == 'Linux' && matrix.runs_valgrind == true | |
run: | | |
# sudo apt-get update | |
sudo apt-get install --no-install-recommends valgrind | |
- name: Cache tools | |
uses: actions/cache@v4 | |
if: runner.os == 'Linux' && matrix.runs_msan == true | |
id: cache-tools | |
with: | |
path: tools | |
key: tools-clang-stdlib-msan | |
- name: Configure CMake | |
uses: ./.github/actions/configure-cmake | |
with: | |
custom_flags: ${{ matrix.cmake_flags }} | |
warnings_as_errors: 'ON' | |
- name: Build | |
# Execute the build using N jobs (-jN) | |
run: cmake --build "${BUILD_DIR}" --config ${BUILD_TYPE} -j6 | |
- name: Install | |
# Use CMake to "install" build artifacts (only interested in CMake registered targets) to our custom artifacts directory | |
run: cmake --install "${BUILD_DIR}" --config ${BUILD_TYPE} --prefix artifacts | |
- name: Move artifacts | |
run: | | |
mkdir ${{ env.ZIP_NAME }} | |
mv artifacts/${{ env.BIN_DIR }}/* ${{ env.ZIP_NAME }} | |
ls -la ${{ env.ZIP_NAME }} | |
cp "${INPUT_FILENAME}" ${{ env.ZIP_NAME }} | |
- name: Patch macOS launcher | |
if: runner.os == 'macOS' | |
run: | | |
sed -i '' -e "s/oop/${EXECUTABLE_NAME}/" "${{ env.ZIP_NAME }}/launcher.command" | |
chmod +x "${{ env.ZIP_NAME }}/launcher.command" | |
- name: Copy missing dylibs | |
if: runner.os == 'macOS' && matrix.cxx == 'clang++' | |
run: | | |
mkdir lib | |
cp /Library/Developer/CommandLineTools/usr/lib/clang/14.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib lib | |
install_name_tool -change @rpath/libclang_rt.asan_osx_dynamic.dylib @executable_path/lib/libclang_rt.asan_osx_dynamic.dylib ${{ env.ZIP_NAME }}/${{ env.EXECUTABLE_NAME }} | |
mv lib ${{ env.ZIP_NAME }}/ | |
- name: Copy missing dylibs (g++) | |
if: runner.os == 'macOS' && startsWith(matrix.cxx, 'g++') | |
run: | | |
mkdir lib | |
cp /usr/local/opt/gcc@12/lib/gcc/12/libstdc++.6.dylib /usr/local/opt/gcc@12/lib/gcc/12/libgcc_s.1.1.dylib lib | |
install_name_tool -change /usr/local/opt/gcc@12/lib/gcc/12/libstdc++.6.dylib @executable_path/lib/libstdc++.6.dylib ${{ env.ZIP_NAME }}/${{ env.EXECUTABLE_NAME }} | |
install_name_tool -change /usr/local/opt/gcc@12/lib/gcc/12/libgcc_s.1.1.dylib @executable_path/lib/libgcc_s.1.1.dylib ${{ env.ZIP_NAME }}/${{ env.EXECUTABLE_NAME }} | |
mv lib ${{ env.ZIP_NAME }}/ | |
- name: Copy missing dlls | |
if: runner.os == 'Windows' && matrix.cxx == 'cl' | |
run: | | |
if [[ "${BUILD_TYPE}" =~ "Deb" ]]; then | |
# runtime debug DLLs | |
cp "$(which ucrtbased.dll)" \ | |
"$(which VCRUNTIME140_1D.dll)" \ | |
"$(which MSVCP140D.dll)" \ | |
"$(which VCRUNTIME140D.dll)" \ | |
${GITHUB_WORKSPACE}/${{ env.ZIP_NAME }} | |
# sanitizers DLLs | |
vcver=$(cat "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt") | |
vcbindir="C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/MSVC/${vcver}/bin/Hostx64/x64/" | |
cp "${vcbindir}/clang_rt.asan_dynamic-x86_64.dll" \ | |
"${vcbindir}/clang_rt.asan_dbg_dynamic-x86_64.dll" \ | |
${GITHUB_WORKSPACE}/${{ env.ZIP_NAME }} | |
fi | |
# runtime release DLLs | |
if [[ "${BUILD_TYPE}" =~ "Rel" ]]; then | |
cp "$(which ucrtbase.dll)" \ | |
"$(which VCRUNTIME140_1.dll)" \ | |
"$(which MSVCP140.dll)" \ | |
"$(which VCRUNTIME140.dll)" \ | |
${GITHUB_WORKSPACE}/${{ env.ZIP_NAME }} | |
fi | |
- name: Copy stdlib (MinGW) | |
if: runner.os == 'Windows' && matrix.cxx == 'g++' | |
# static linking might not work with MinGW, might be easier this way | |
run: | | |
cp $(which libstdc++-6.dll) \ | |
$(which libgcc_s_seh-1.dll) \ | |
$(which libwinpthread-1.dll) \ | |
${GITHUB_WORKSPACE}/${{ env.ZIP_NAME }} | |
- name: Upload Artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ env.ZIP_NAME }}_${{ env.TIMESTAMP }} | |
path: ${{ env.ZIP_NAME }} | |
retention-days: 30 | |
- name: Setup memory sanitizer | |
if: runner.os == 'Linux' && matrix.runs_msan == true && steps.cache-tools.outputs.cache-hit != 'true' | |
run: | | |
mkdir -p tools | |
cd tools | |
git clone --depth=1 --branch=llvmorg-17.0.6 https://github.com/llvm/llvm-project | |
cd llvm-project | |
# mkdir build; cd build | |
sudo ln -s -f /usr/bin/$CC /usr/bin/clang | |
sudo ln -s -f /usr/bin/$CXX /usr/bin/clang++ | |
cmake -G Ninja -S runtimes -B build \ | |
-DCMAKE_BUILD_TYPE=Release \ | |
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ | |
-DCMAKE_C_COMPILER=clang \ | |
-DCMAKE_CXX_COMPILER=clang++ \ | |
-DLLVM_USE_SANITIZER=MemoryWithOrigins \ | |
-DCMAKE_BUILD_WITH_INSTALL_RPATH=true | |
cmake --build build -j6 -- cxx cxxabi | |
- name: Sanitizers | |
# run one sanitizer for each env to avoid building extra binaries on one env | |
if: (matrix.runs_asan == true || matrix.runs_msan == true) && runner.os != 'Windows' | |
# detect_leaks is not supported on macOS | |
# env: | |
# ASAN_OPTIONS: detect_leaks=1 | |
run: | | |
cat "${INPUT_FILENAME}" | tr -d '\r' | ./${{ env.ZIP_NAME }}/"${EXECUTABLE_NAME}" | |
- name: Sanitizers (Windows MSVC) | |
# run one sanitizer for each OS to avoid building extra binaries | |
if: matrix.cxx == 'cl' && matrix.runs_asan == true | |
continue-on-error: true | |
run: | | |
cat "${INPUT_FILENAME}" | ./${{ env.ZIP_NAME }}/"${EXECUTABLE_NAME}".exe | |
- name: Valgrind | |
if: runner.os == 'Linux' && matrix.runs_valgrind == true | |
run: | | |
# remove --show-leak-kinds=all (and --track-origins=yes) if there are many leaks in external libs | |
cat "${INPUT_FILENAME}" | tr -d '\r' | valgrind \ | |
--leak-check=full --show-leak-kinds=all --track-origins=yes \ | |
--error-exitcode=1 \ | |
./${{ env.ZIP_NAME }}/"${EXECUTABLE_NAME}" | |
- name: Set Tag Name | |
if: startsWith(github.ref, 'refs/tags/') | |
# trim prefix from ref to get tag name | |
run: echo "TAG_NAME=${GITHUB_REF#'refs/tags/'}" >> ${GITHUB_ENV} | |
- name: Add tag to folder name | |
if: startsWith(github.ref, 'refs/tags/') | |
run: | | |
mv ${{ env.ZIP_NAME }} ${{ env.ZIP_NAME }}_${{ env.TAG_NAME }} | |
- name: Archive Release | |
uses: thedoctor0/zip-release@master | |
if: startsWith(github.ref, 'refs/tags/') | |
with: | |
type: 'zip' | |
path: ${{ env.ZIP_NAME }}_${{ env.TAG_NAME }} | |
filename: ${{ env.ZIP_NAME }}_${{ env.TAG_NAME }}.zip | |
- name: Release | |
uses: softprops/action-gh-release@master | |
if: startsWith(github.ref, 'refs/tags/') | |
with: | |
files: | | |
${{ env.ZIP_NAME }}_${{ env.TAG_NAME }}.zip |