diff --git a/.github/scripts/conan-profile.sh b/.github/scripts/conan-profile.sh new file mode 100644 index 0000000..8d05348 --- /dev/null +++ b/.github/scripts/conan-profile.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +conan profile detect -f + +std=20 +version=11 + + +profile="$(conan profile path default)" + +mv "$profile" "${profile}.bak" +sed -e 's/^\(compiler\.cppstd=\).\{1,\}$/\1'"$std/" \ + -e 's/^\(compiler\.version=\).\{1,\}$/\1'"$version/" \ + "${profile}.bak" > "$profile" +rm "${profile}.bak" diff --git a/.github/workflows/dry-run.yml b/.github/workflows/dry-run.yml new file mode 100644 index 0000000..7b8322f --- /dev/null +++ b/.github/workflows/dry-run.yml @@ -0,0 +1,36 @@ +name: CI - Dry Run + +on: + push: + branches: + - main + pull_request: + +jobs: + cpp-unit-tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@v5 + with: + version: "latest" + + - name: Install Conan and Ninja + run: | + uv tool install conan + uv tool install ninja + conan profile detect + bash < .github/scripts/conan-profile.sh + + - name: Generate Executable + run: make install && make build + + - name: Run Main + run: ./build/template + + - name: Run Debug Executable + run: ./build/template_debug diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..bffaae2 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,36 @@ +name: CI - Cpp Linting and Format Check + +on: + push: + branches: + - main + pull_request: + +jobs: + cpp-lint-and-format-check: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@v5 + with: + version: "latest" + + - name: Install Conan and Ninja + run: | + uv tool install conan + uv tool install ninja + conan profile detect + bash < .github/scripts/conan-profile.sh + + - name: Install code dependencies + run: make build + + - name: Format Check + run: make format-check + + - name: Lint Check + run: make lint-check diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml new file mode 100644 index 0000000..39b5c52 --- /dev/null +++ b/.github/workflows/unit-test.yml @@ -0,0 +1,30 @@ +name: CI - Unit Tests + +on: + push: + branches: + - main + pull_request: + +jobs: + cpp-unit-tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@v5 + with: + version: "latest" + + - name: Install Conan and Ninja + run: | + uv tool install conan + uv tool install ninja + conan profile detect + bash < .github/scripts/conan-profile.sh + + - name: Run unit tests + run: make test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cb7b974 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +build +CMakeUserPresets.json +.idea +cmake-build-debug +CMakeFiles +.cache diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5afe6a4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.20) + +project(template LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +set(DEBUG_FLAGS -g -O0) +set(RELEASE_FLAGS -O3 -DNDEBUG) + +find_package(GTest REQUIRED) +enable_testing() + +file(GLOB MAIN src/main.cpp) +file(GLOB_RECURSE TESTS tst/*.cpp) +file(GLOB_RECURSE HEADERS src/*.hpp) + +find_package(fmt REQUIRED) + +SET(PACKAGES fmt::fmt) + +add_executable(template ${MAIN} ${HEADERS}) +add_executable(template_tests ${TESTS} ${HEADERS}) +add_executable(template_debug ${MAIN} ${HEADERS}) + +target_compile_options(template PRIVATE ${RELEASE_FLAGS}) +target_compile_options(template_tests PRIVATE ${DEBUG_FLAGS}) +target_compile_options(template_debug PRIVATE ${DEBUG_FLAGS}) + + +SET(TARGETS template template_tests template_debug) + +foreach (target ${TARGETS}) + target_include_directories(${target} PUBLIC src) + target_link_libraries(${target} PRIVATE ${PACKAGES}) +endforeach() + +# Gtest +target_link_libraries(template_tests PRIVATE gtest::gtest) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ee6d50a --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +.PHONY: install +install: + conan install . --build=missing + +.PHONY: build +build: install + cd build && cmake .. -DCMAKE_TOOLCHAIN_FILE=Release/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -G Ninja + cd build && cmake --build . -j + +.PHONY: test +test: build + cd build && ./template_tests + +.PHONY: lint-check +lint-check: + run-clang-tidy -j $(shell nproc) -p build + +.PHONY: format-check +format-check: + find src tst -name '*.cpp' -o -name '*.hpp' | xargs clang-format --style=file --Werror --dry-run + +.PHONY: format +format: + find src tst -name '*.cpp' -o -name '*.hpp' | xargs clang-format --style=file -i + run-clang-tidy -fix -j $(shell nproc) -p build + +.PHONY: clean +clean: + rm -rf build + diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 0000000..e8c4cc9 --- /dev/null +++ b/conanfile.py @@ -0,0 +1,14 @@ +from conan import ConanFile +from conan.tools.cmake import cmake_layout + + +class TemplateRecipe(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeDeps", "CMakeToolchain" + + def requirements(self): + self.requires("gtest/1.15.0") + self.requires("fmt/11.1.1") + + def layout(self): + cmake_layout(self) diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..1f0308c --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,5 @@ +#include +int main() { + std::cout << "Hello World" << std::endl; + return 0; +} diff --git a/tst/test_basic.cpp b/tst/test_basic.cpp new file mode 100644 index 0000000..ec65a5c --- /dev/null +++ b/tst/test_basic.cpp @@ -0,0 +1,3 @@ +#include + +TEST(TestBasic, TestAdd) { EXPECT_EQ(4 + 4, 4 * 2); }