diff --git a/.gitignore b/.gitignore index 11e3702..35654c6 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,7 @@ *.swp *.swo *.DS_Store + +# Local build directories for examples +02-cmake/examples/**/build*/ .idea diff --git a/02-cmake/02-cmake.tex b/02-cmake/02-cmake.tex index 3e5a096..adc7f8b 100644 --- a/02-cmake/02-cmake.tex +++ b/02-cmake/02-cmake.tex @@ -556,8 +556,25 @@ \section{CMake} \end{lstlisting} \end{frame} -\begin{frame}{CMake demo} - Demo +\begin{frame}[fragile]{Examples and demo} + Example projects are included with this lecture under: + \begin{itemize} + \item \texttt{02-cmake/examples/steps} — step-by-step progression + \item \texttt{02-cmake/examples/hello} — minimal project + \item \texttt{02-cmake/examples/modern} — target-based project with tests and presets + \end{itemize} + Quick start (Unix, Ninja): + \begin{lstlisting}[language=bash] +cd 02-cmake/examples/steps/02-hello-cmake +cmake -S . -B build -G Ninja -D CMAKE_BUILD_TYPE=Debug +cmake --build build + \end{lstlisting} + Quick start (Windows, Visual Studio): + \begin{lstlisting}[language=bash] +cd 02-cmake\examples\steps\02-hello-cmake +cmake -S . -B build -G "Visual Studio 17 2022" -A x64 +cmake --build build --config Debug + \end{lstlisting} \end{frame} \begin{frame} diff --git a/02-cmake/examples/README.md b/02-cmake/examples/README.md new file mode 100644 index 0000000..69d9f52 --- /dev/null +++ b/02-cmake/examples/README.md @@ -0,0 +1,10 @@ +# CMake Examples + +This folder contains cross‑platform examples aligned with the CMake lecture. + +- `steps/` — incremental, step‑by‑step walkthrough (recommended start). +- `hello/` — minimal single‑target example. +- `modern/` — target‑based layout with library, tests, presets, and packaging. + +See each subfolder’s README for OS/generator specific commands. + diff --git a/02-cmake/examples/hello/CMakeLists.txt b/02-cmake/examples/hello/CMakeLists.txt new file mode 100644 index 0000000..bb45f3d --- /dev/null +++ b/02-cmake/examples/hello/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.16) +project(HelloCMake LANGUAGES CXX) + +add_executable(hello src/main.cpp) +target_compile_features(hello PRIVATE cxx_std_20) + diff --git a/02-cmake/examples/hello/CMakePresets.json b/02-cmake/examples/hello/CMakePresets.json new file mode 100644 index 0000000..8151c4c --- /dev/null +++ b/02-cmake/examples/hello/CMakePresets.json @@ -0,0 +1,22 @@ +{ + "version": 3, + "cmakeMinimumRequired": { "major": 3, "minor": 22 }, + "configurePresets": [ + { "name": "ninja-debug", "generator": "Ninja", "binaryDir": "build/ninja-debug", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } }, + { "name": "ninja-release", "generator": "Ninja", "binaryDir": "build/ninja-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } }, + { "name": "unix-make-debug", "generator": "Unix Makefiles", "binaryDir": "build/unix-debug", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } }, + { "name": "xcode-debug", "generator": "Xcode", "binaryDir": "build/xcode-debug" }, + { "name": "vs2022-x64-debug", "generator": "Visual Studio 17 2022", "binaryDir": "build/vs2022/x64", "architecture": { "value": "x64", "strategy": "external" } }, + { "name": "mingw-release", "generator": "MinGW Makefiles", "binaryDir": "build/mingw-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } } + ], + "buildPresets": [ + { "name": "build-ninja-debug", "configurePreset": "ninja-debug" }, + { "name": "build-ninja-release", "configurePreset": "ninja-release" }, + { "name": "build-unix-debug", "configurePreset": "unix-make-debug" }, + { "name": "build-xcode-debug", "configurePreset": "xcode-debug" }, + { "name": "build-vs-debug", "configurePreset": "vs2022-x64-debug", "configuration": "Debug" }, + { "name": "build-vs-release", "configurePreset": "vs2022-x64-debug", "configuration": "Release" }, + { "name": "build-mingw-release", "configurePreset": "mingw-release" } + ] +} + diff --git a/02-cmake/examples/hello/README.md b/02-cmake/examples/hello/README.md new file mode 100644 index 0000000..60938f8 --- /dev/null +++ b/02-cmake/examples/hello/README.md @@ -0,0 +1,28 @@ +# Hello Example (Cross‑platform) + +Build with your preferred generator: + +- Generic (works everywhere): + - `cmake -S . -B build` + - `cmake --build build` + - Run: `./build/hello` (Linux/macOS) or `build\hello.exe` (Windows) + +- Ninja: + - `cmake -S . -B build-ninja -G Ninja -D CMAKE_BUILD_TYPE=Release` + - `cmake --build build-ninja` + +- Unix Makefiles (Linux/macOS): + - `cmake -S . -B build-make -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug` + - `cmake --build build-make` + +- Visual Studio (Windows, x64): + - `cmake -S . -B build-vs -G "Visual Studio 17 2022" -A x64` + - `cmake --build build-vs --config Release` + - Or open `build-vs/HelloCMake.sln` in Visual Studio. + +- MinGW (Windows): + - `cmake -S . -B build-mingw -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Release` + - `cmake --build build-mingw` + +Presets are provided in `CMakePresets.json` for common setups. + diff --git a/02-cmake/examples/hello/src/main.cpp b/02-cmake/examples/hello/src/main.cpp new file mode 100644 index 0000000..90274a2 --- /dev/null +++ b/02-cmake/examples/hello/src/main.cpp @@ -0,0 +1,7 @@ +#include + +int main() { + std::cout << "Hello, CMake!" << std::endl; + return 0; +} + diff --git a/02-cmake/examples/modern/CMakeLists.txt b/02-cmake/examples/modern/CMakeLists.txt new file mode 100644 index 0000000..66e65eb --- /dev/null +++ b/02-cmake/examples/modern/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.16) +project(ModernCMakeExamples LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +option(BUILD_TESTS "Build unit tests" ON) + +add_subdirectory(lib) +add_subdirectory(src) + +if(BUILD_TESTS) + enable_testing() + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip + ) + FetchContent_MakeAvailable(googletest) + add_subdirectory(tests) +endif() + +install(TARGETS app add EXPORT modernTargets + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + INCLUDES DESTINATION include +) +install(DIRECTORY lib/include/ DESTINATION include) +install(EXPORT modernTargets NAMESPACE modern:: DESTINATION lib/cmake/modern) + +include(CPack) + diff --git a/02-cmake/examples/modern/CMakePresets.json b/02-cmake/examples/modern/CMakePresets.json new file mode 100644 index 0000000..2bceea8 --- /dev/null +++ b/02-cmake/examples/modern/CMakePresets.json @@ -0,0 +1,27 @@ +{ + "version": 3, + "cmakeMinimumRequired": { "major": 3, "minor": 22 }, + "configurePresets": [ + { "name": "ninja-debug", "generator": "Ninja", "binaryDir": "build/ninja-debug", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } }, + { "name": "ninja-release", "generator": "Ninja", "binaryDir": "build/ninja-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } }, + { "name": "unix-make-debug","generator": "Unix Makefiles", "binaryDir": "build/unix-debug", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } }, + { "name": "xcode-debug", "generator": "Xcode", "binaryDir": "build/xcode-debug" }, + { "name": "vs2022-x64", "generator": "Visual Studio 17 2022", "binaryDir": "build/vs2022/x64", + "architecture": { "value": "x64", "strategy": "external" } }, + { "name": "mingw-release", "generator": "MinGW Makefiles", "binaryDir": "build/mingw-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } } + ], + "buildPresets": [ + { "name": "build-ninja-debug", "configurePreset": "ninja-debug" }, + { "name": "build-ninja-release", "configurePreset": "ninja-release" }, + { "name": "build-unix-debug", "configurePreset": "unix-make-debug" }, + { "name": "build-xcode-debug", "configurePreset": "xcode-debug" }, + { "name": "build-vs-debug", "configurePreset": "vs2022-x64", "configuration": "Debug" }, + { "name": "build-vs-release", "configurePreset": "vs2022-x64", "configuration": "Release" }, + { "name": "build-mingw-release", "configurePreset": "mingw-release" } + ], + "testPresets": [ + { "name": "test-ninja-debug", "configurePreset": "ninja-debug" }, + { "name": "test-vs-debug", "configurePreset": "vs2022-x64", "configuration": "Debug" } + ] +} + diff --git a/02-cmake/examples/modern/README.md b/02-cmake/examples/modern/README.md new file mode 100644 index 0000000..79579fa --- /dev/null +++ b/02-cmake/examples/modern/README.md @@ -0,0 +1,46 @@ +# Modern CMake Example (Cross‑platform) + +Build options: + +- Ninja (fast, single‑config): + - `cmake --preset ninja-debug` + - `cmake --build --preset build-ninja-debug` + - Run: `./build/ninja-debug/app` or `build\ninja-debug\app.exe` + +- Unix Makefiles (Linux/macOS): + - `cmake --preset unix-make-debug` + - `cmake --build --preset build-unix-debug` + +- Visual Studio 2022 (Windows, x64): + - `cmake --preset vs2022-x64` + - `cmake --build --preset build-vs-debug` + - Or open `build/vs2022/x64/ModernCMakeExamples.sln` and build. + +- MinGW (Windows): + - `cmake --preset mingw-release` + - `cmake --build --preset build-mingw-release` + +- Xcode (macOS): + - `cmake --preset xcode-debug` + - `cmake --build --preset build-xcode-debug` + +Tests: + +- After configuring with any preset that enables tests (all of the above), run: + - `ctest --preset test-ninja-debug` (Ninja) + - `ctest --preset test-vs-debug` (Visual Studio) + - Or from a build dir: `ctest --output-on-failure -j` + +Cross‑compiling (ARM, example): + +``` +cmake -S . -B build-arm \ + -DCMAKE_TOOLCHAIN_FILE=toolchains/arm-none-eabi.cmake \ + -D CMAKE_BUILD_TYPE=Release +cmake --build build-arm +``` + +Packaging: + +- `cpack -G ZIP` from the configured build directory to create an archive. + diff --git a/02-cmake/examples/modern/lib/CMakeLists.txt b/02-cmake/examples/modern/lib/CMakeLists.txt new file mode 100644 index 0000000..a739db9 --- /dev/null +++ b/02-cmake/examples/modern/lib/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(add src/add.cpp) +target_include_directories(add PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_compile_features(add PUBLIC cxx_std_20) + diff --git a/02-cmake/examples/modern/lib/include/add/add.h b/02-cmake/examples/modern/lib/include/add/add.h new file mode 100644 index 0000000..0337ea3 --- /dev/null +++ b/02-cmake/examples/modern/lib/include/add/add.h @@ -0,0 +1,8 @@ +#pragma once + +namespace addlib { + +int add(int x, int y); + +} // namespace addlib + diff --git a/02-cmake/examples/modern/lib/src/add.cpp b/02-cmake/examples/modern/lib/src/add.cpp new file mode 100644 index 0000000..b528525 --- /dev/null +++ b/02-cmake/examples/modern/lib/src/add.cpp @@ -0,0 +1,8 @@ +#include "add/add.h" + +namespace addlib { + +int add(int x, int y) { return x + y; } + +} // namespace addlib + diff --git a/02-cmake/examples/modern/src/CMakeLists.txt b/02-cmake/examples/modern/src/CMakeLists.txt new file mode 100644 index 0000000..d04b4d3 --- /dev/null +++ b/02-cmake/examples/modern/src/CMakeLists.txt @@ -0,0 +1,6 @@ +add_executable(app src/main.cpp) +target_link_libraries(app PRIVATE add) +target_compile_features(app PRIVATE cxx_std_20) + +set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT app) + diff --git a/02-cmake/examples/modern/src/main.cpp b/02-cmake/examples/modern/src/main.cpp new file mode 100644 index 0000000..bf0020d --- /dev/null +++ b/02-cmake/examples/modern/src/main.cpp @@ -0,0 +1,10 @@ +#include +#include "add/add.h" + +int main() { + const int a = 5; + const int b = 3; + std::cout << a << " + " << b << " = " << addlib::add(a, b) << std::endl; + return 0; +} + diff --git a/02-cmake/examples/modern/tests/CMakeLists.txt b/02-cmake/examples/modern/tests/CMakeLists.txt new file mode 100644 index 0000000..88eef08 --- /dev/null +++ b/02-cmake/examples/modern/tests/CMakeLists.txt @@ -0,0 +1,6 @@ +add_executable(app_tests tests.cpp) +target_link_libraries(app_tests PRIVATE add gtest_main) + +include(GoogleTest) +gtest_discover_tests(app_tests) + diff --git a/02-cmake/examples/modern/tests/tests.cpp b/02-cmake/examples/modern/tests/tests.cpp new file mode 100644 index 0000000..3e92f59 --- /dev/null +++ b/02-cmake/examples/modern/tests/tests.cpp @@ -0,0 +1,12 @@ +#include +#include "add/add.h" + +TEST(AddLib, SumsPositive) { + EXPECT_EQ(addlib::add(2, 2), 4); + EXPECT_EQ(addlib::add(5, 3), 8); +} + +TEST(AddLib, SumsNegative) { + EXPECT_EQ(addlib::add(-2, -3), -5); +} + diff --git a/02-cmake/examples/modern/toolchains/arm-none-eabi.cmake b/02-cmake/examples/modern/toolchains/arm-none-eabi.cmake new file mode 100644 index 0000000..b268199 --- /dev/null +++ b/02-cmake/examples/modern/toolchains/arm-none-eabi.cmake @@ -0,0 +1,6 @@ +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_C_COMPILER arm-none-eabi-gcc) +set(CMAKE_CXX_COMPILER arm-none-eabi-g++) + diff --git a/02-cmake/examples/steps/01-hello-plain/README.md b/02-cmake/examples/steps/01-hello-plain/README.md new file mode 100644 index 0000000..55091c9 --- /dev/null +++ b/02-cmake/examples/steps/01-hello-plain/README.md @@ -0,0 +1,23 @@ +# 01 — Hello (no CMake) + +Linux/macOS (g++): + +``` +g++ -std=c++20 -O2 -o hello main.cpp +./hello +``` + +Windows (Visual Studio Developer Command Prompt): + +``` +cl /EHsc /std:c++20 main.cpp +main.exe +``` + +Windows (MinGW): + +``` +g++ -std=c++20 -O2 -o hello.exe main.cpp +hello.exe +``` + diff --git a/02-cmake/examples/steps/01-hello-plain/main.cpp b/02-cmake/examples/steps/01-hello-plain/main.cpp new file mode 100644 index 0000000..e041e11 --- /dev/null +++ b/02-cmake/examples/steps/01-hello-plain/main.cpp @@ -0,0 +1,7 @@ +#include + +int main() { + std::cout << "Hello, World!" << std::endl; + return 0; +} + diff --git a/02-cmake/examples/steps/02-hello-cmake/CMakeLists.txt b/02-cmake/examples/steps/02-hello-cmake/CMakeLists.txt new file mode 100644 index 0000000..75f4011 --- /dev/null +++ b/02-cmake/examples/steps/02-hello-cmake/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) +project(HelloCMake LANGUAGES CXX) +add_executable(hello src/main.cpp) +target_compile_features(hello PRIVATE cxx_std_20) + diff --git a/02-cmake/examples/steps/02-hello-cmake/README.md b/02-cmake/examples/steps/02-hello-cmake/README.md new file mode 100644 index 0000000..ae01ab6 --- /dev/null +++ b/02-cmake/examples/steps/02-hello-cmake/README.md @@ -0,0 +1,32 @@ +# 02 — Hello (CMake minimal) + +Generic: + +``` +cmake -S . -B build +cmake --build build +./build/hello # Linux/macOS +build\\hello.exe # Windows +``` + +Ninja: + +``` +cmake -S . -B build-ninja -G Ninja -D CMAKE_BUILD_TYPE=Release +cmake --build build-ninja +``` + +Visual Studio (Windows x64): + +``` +cmake -S . -B build-vs -G "Visual Studio 17 2022" -A x64 +cmake --build build-vs --config Debug +``` + +Unix Makefiles (Linux/macOS): + +``` +cmake -S . -B build-make -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug +cmake --build build-make +``` + diff --git a/02-cmake/examples/steps/02-hello-cmake/src/main.cpp b/02-cmake/examples/steps/02-hello-cmake/src/main.cpp new file mode 100644 index 0000000..90274a2 --- /dev/null +++ b/02-cmake/examples/steps/02-hello-cmake/src/main.cpp @@ -0,0 +1,7 @@ +#include + +int main() { + std::cout << "Hello, CMake!" << std::endl; + return 0; +} + diff --git a/02-cmake/examples/steps/03-lib-cmake/CMakeLists.txt b/02-cmake/examples/steps/03-lib-cmake/CMakeLists.txt new file mode 100644 index 0000000..6231bea --- /dev/null +++ b/02-cmake/examples/steps/03-lib-cmake/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.16) +project(LibExample LANGUAGES CXX) + +add_library(add lib/src/add.cpp) +target_include_directories(add PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/lib/include) + +add_executable(app src/main.cpp) +target_link_libraries(app PRIVATE add) +target_compile_features(app PRIVATE cxx_std_20) + diff --git a/02-cmake/examples/steps/03-lib-cmake/README.md b/02-cmake/examples/steps/03-lib-cmake/README.md new file mode 100644 index 0000000..2987efa --- /dev/null +++ b/02-cmake/examples/steps/03-lib-cmake/README.md @@ -0,0 +1,15 @@ +# 03 — Library + app + +Configure and build (generic): + +``` +cmake -S . -B build +cmake --build build +./build/app # Linux/macOS +build\\app.exe # Windows +``` + +Notes: +- `add` is a simple library linked to `app`. +- Headers are exposed via `target_include_directories(add PUBLIC include)`. + diff --git a/02-cmake/examples/steps/03-lib-cmake/lib/include/add/add.h b/02-cmake/examples/steps/03-lib-cmake/lib/include/add/add.h new file mode 100644 index 0000000..6f9a9a5 --- /dev/null +++ b/02-cmake/examples/steps/03-lib-cmake/lib/include/add/add.h @@ -0,0 +1,8 @@ +#pragma once + +namespace addlib { + +int add(int x, int y); + +} + diff --git a/02-cmake/examples/steps/03-lib-cmake/lib/src/add.cpp b/02-cmake/examples/steps/03-lib-cmake/lib/src/add.cpp new file mode 100644 index 0000000..55d3824 --- /dev/null +++ b/02-cmake/examples/steps/03-lib-cmake/lib/src/add.cpp @@ -0,0 +1,8 @@ +#include "add/add.h" + +namespace addlib { + +int add(int x, int y) { return x + y; } + +} + diff --git a/02-cmake/examples/steps/03-lib-cmake/src/main.cpp b/02-cmake/examples/steps/03-lib-cmake/src/main.cpp new file mode 100644 index 0000000..b71caed --- /dev/null +++ b/02-cmake/examples/steps/03-lib-cmake/src/main.cpp @@ -0,0 +1,8 @@ +#include +#include "add/add.h" + +int main() { + std::cout << "5 + 3 = " << addlib::add(5, 3) << std::endl; + return 0; +} + diff --git a/02-cmake/examples/steps/04-targets-modern/CMakeLists.txt b/02-cmake/examples/steps/04-targets-modern/CMakeLists.txt new file mode 100644 index 0000000..4a5ae31 --- /dev/null +++ b/02-cmake/examples/steps/04-targets-modern/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.16) +project(TargetBased LANGUAGES CXX) + +add_library(add src/add.cpp) +target_include_directories(add PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_compile_features(add PUBLIC cxx_std_20) + +add_executable(app src/main.cpp) +target_link_libraries(app PRIVATE add) +target_compile_options(app PRIVATE $<$:/W4 /WX> + $<$>:-Wall -Wextra -Wpedantic -Werror>) + diff --git a/02-cmake/examples/steps/04-targets-modern/README.md b/02-cmake/examples/steps/04-targets-modern/README.md new file mode 100644 index 0000000..aad06de --- /dev/null +++ b/02-cmake/examples/steps/04-targets-modern/README.md @@ -0,0 +1,13 @@ +# 04 — Target-based CMake + +Highlights: +- PUBLIC/PRIVATE usage requirements. +- Compiler warnings as errors (portable generator expressions). + +Build: + +``` +cmake -S . -B build +cmake --build build +``` + diff --git a/02-cmake/examples/steps/04-targets-modern/include/add/add.h b/02-cmake/examples/steps/04-targets-modern/include/add/add.h new file mode 100644 index 0000000..6f9a9a5 --- /dev/null +++ b/02-cmake/examples/steps/04-targets-modern/include/add/add.h @@ -0,0 +1,8 @@ +#pragma once + +namespace addlib { + +int add(int x, int y); + +} + diff --git a/02-cmake/examples/steps/04-targets-modern/src/add.cpp b/02-cmake/examples/steps/04-targets-modern/src/add.cpp new file mode 100644 index 0000000..55d3824 --- /dev/null +++ b/02-cmake/examples/steps/04-targets-modern/src/add.cpp @@ -0,0 +1,8 @@ +#include "add/add.h" + +namespace addlib { + +int add(int x, int y) { return x + y; } + +} + diff --git a/02-cmake/examples/steps/04-targets-modern/src/main.cpp b/02-cmake/examples/steps/04-targets-modern/src/main.cpp new file mode 100644 index 0000000..11309c4 --- /dev/null +++ b/02-cmake/examples/steps/04-targets-modern/src/main.cpp @@ -0,0 +1,8 @@ +#include +#include "add/add.h" + +int main() { + std::cout << "2 + 2 = " << addlib::add(2, 2) << std::endl; + return 0; +} + diff --git a/02-cmake/examples/steps/05-deps-fmt-find_package/CMakeLists.txt b/02-cmake/examples/steps/05-deps-fmt-find_package/CMakeLists.txt new file mode 100644 index 0000000..46f06eb --- /dev/null +++ b/02-cmake/examples/steps/05-deps-fmt-find_package/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.16) +project(DepsFmt LANGUAGES CXX) + +add_library(add src/add.cpp) +target_include_directories(add PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_compile_features(add PUBLIC cxx_std_20) + +find_package(fmt CONFIG REQUIRED) + +add_executable(app src/main.cpp) +target_link_libraries(app PRIVATE add fmt::fmt) + diff --git a/02-cmake/examples/steps/05-deps-fmt-find_package/README.md b/02-cmake/examples/steps/05-deps-fmt-find_package/README.md new file mode 100644 index 0000000..928f9cc --- /dev/null +++ b/02-cmake/examples/steps/05-deps-fmt-find_package/README.md @@ -0,0 +1,20 @@ +# 05 — Dependencies via find_package (fmt) + +Requires fmt to be discoverable by CMake. + +Install fmt: + +- Ubuntu/Debian: `sudo apt install libfmt-dev` +- macOS (Homebrew): `brew install fmt` +- Windows (vcpkg): + - `vcpkg install fmt` + - Configure with: `-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake` + +Build: + +``` +cmake -S . -B build \ + -DCMAKE_TOOLCHAIN_FILE="C:/vcpkg/scripts/buildsystems/vcpkg.cmake" # on Windows/vcpkg +cmake --build build +``` + diff --git a/02-cmake/examples/steps/05-deps-fmt-find_package/include/add/add.h b/02-cmake/examples/steps/05-deps-fmt-find_package/include/add/add.h new file mode 100644 index 0000000..6f9a9a5 --- /dev/null +++ b/02-cmake/examples/steps/05-deps-fmt-find_package/include/add/add.h @@ -0,0 +1,8 @@ +#pragma once + +namespace addlib { + +int add(int x, int y); + +} + diff --git a/02-cmake/examples/steps/05-deps-fmt-find_package/src/add.cpp b/02-cmake/examples/steps/05-deps-fmt-find_package/src/add.cpp new file mode 100644 index 0000000..55d3824 --- /dev/null +++ b/02-cmake/examples/steps/05-deps-fmt-find_package/src/add.cpp @@ -0,0 +1,8 @@ +#include "add/add.h" + +namespace addlib { + +int add(int x, int y) { return x + y; } + +} + diff --git a/02-cmake/examples/steps/05-deps-fmt-find_package/src/main.cpp b/02-cmake/examples/steps/05-deps-fmt-find_package/src/main.cpp new file mode 100644 index 0000000..3ba390d --- /dev/null +++ b/02-cmake/examples/steps/05-deps-fmt-find_package/src/main.cpp @@ -0,0 +1,9 @@ +#include +#include "add/add.h" + +int main() { + int a = 7, b = 5; + fmt::print("{} + {} = {}\n", a, b, addlib::add(a, b)); + return 0; +} + diff --git a/02-cmake/examples/steps/06-testing-ctest-gtest/CMakeLists.txt b/02-cmake/examples/steps/06-testing-ctest-gtest/CMakeLists.txt new file mode 100644 index 0000000..8020904 --- /dev/null +++ b/02-cmake/examples/steps/06-testing-ctest-gtest/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.16) +project(WithTests LANGUAGES CXX) + +add_library(add src/add.cpp) +target_include_directories(add PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_compile_features(add PUBLIC cxx_std_20) + +add_executable(app src/main.cpp) +target_link_libraries(app PRIVATE add) + +option(BUILD_TESTS "Build unit tests" ON) +if(BUILD_TESTS) + enable_testing() + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip) + FetchContent_MakeAvailable(googletest) + add_executable(app_tests tests/tests.cpp) + target_link_libraries(app_tests PRIVATE add gtest_main) + include(GoogleTest) + gtest_discover_tests(app_tests) +endif() + diff --git a/02-cmake/examples/steps/06-testing-ctest-gtest/README.md b/02-cmake/examples/steps/06-testing-ctest-gtest/README.md new file mode 100644 index 0000000..8d19218 --- /dev/null +++ b/02-cmake/examples/steps/06-testing-ctest-gtest/README.md @@ -0,0 +1,14 @@ +# 06 — Testing with CTest and GoogleTest + +Configure, build, and run tests: + +``` +cmake -S . -B build +cmake --build build +ctest --test-dir build --output-on-failure -j +``` + +Notes: +- GoogleTest is fetched at configure time via `FetchContent`. +- Use `-DBUILD_TESTS=OFF` to skip tests. + diff --git a/02-cmake/examples/steps/06-testing-ctest-gtest/include/add/add.h b/02-cmake/examples/steps/06-testing-ctest-gtest/include/add/add.h new file mode 100644 index 0000000..6f9a9a5 --- /dev/null +++ b/02-cmake/examples/steps/06-testing-ctest-gtest/include/add/add.h @@ -0,0 +1,8 @@ +#pragma once + +namespace addlib { + +int add(int x, int y); + +} + diff --git a/02-cmake/examples/steps/06-testing-ctest-gtest/src/add.cpp b/02-cmake/examples/steps/06-testing-ctest-gtest/src/add.cpp new file mode 100644 index 0000000..55d3824 --- /dev/null +++ b/02-cmake/examples/steps/06-testing-ctest-gtest/src/add.cpp @@ -0,0 +1,8 @@ +#include "add/add.h" + +namespace addlib { + +int add(int x, int y) { return x + y; } + +} + diff --git a/02-cmake/examples/steps/06-testing-ctest-gtest/src/main.cpp b/02-cmake/examples/steps/06-testing-ctest-gtest/src/main.cpp new file mode 100644 index 0000000..7ebef15 --- /dev/null +++ b/02-cmake/examples/steps/06-testing-ctest-gtest/src/main.cpp @@ -0,0 +1,8 @@ +#include +#include "add/add.h" + +int main() { + std::cout << addlib::add(1, 2) << "\n"; + return 0; +} + diff --git a/02-cmake/examples/steps/06-testing-ctest-gtest/tests/tests.cpp b/02-cmake/examples/steps/06-testing-ctest-gtest/tests/tests.cpp new file mode 100644 index 0000000..563320b --- /dev/null +++ b/02-cmake/examples/steps/06-testing-ctest-gtest/tests/tests.cpp @@ -0,0 +1,11 @@ +#include +#include "add/add.h" + +TEST(Add, Positive) { + EXPECT_EQ(addlib::add(1, 2), 3); +} + +TEST(Add, Negative) { + EXPECT_EQ(addlib::add(-1, -4), -5); +} + diff --git a/02-cmake/examples/steps/07-presets/CMakeLists.txt b/02-cmake/examples/steps/07-presets/CMakeLists.txt new file mode 100644 index 0000000..9e54021 --- /dev/null +++ b/02-cmake/examples/steps/07-presets/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.16) +project(PresetsDemo LANGUAGES CXX) + +add_executable(app src/main.cpp) +target_compile_features(app PRIVATE cxx_std_20) + diff --git a/02-cmake/examples/steps/07-presets/CMakePresets.json b/02-cmake/examples/steps/07-presets/CMakePresets.json new file mode 100644 index 0000000..87f3ca8 --- /dev/null +++ b/02-cmake/examples/steps/07-presets/CMakePresets.json @@ -0,0 +1,17 @@ +{ + "version": 3, + "cmakeMinimumRequired": { "major": 3, "minor": 22 }, + "configurePresets": [ + { "name": "ninja-debug", "generator": "Ninja", "binaryDir": "build/ninja-debug", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } }, + { "name": "unix-make-debug", "generator": "Unix Makefiles", "binaryDir": "build/unix-debug", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } }, + { "name": "xcode-debug", "generator": "Xcode", "binaryDir": "build/xcode-debug" }, + { "name": "vs2022-x64", "generator": "Visual Studio 17 2022", "binaryDir": "build/vs2022/x64", "architecture": { "value": "x64", "strategy": "external" } } + ], + "buildPresets": [ + { "name": "build-ninja-debug", "configurePreset": "ninja-debug" }, + { "name": "build-unix-debug", "configurePreset": "unix-make-debug" }, + { "name": "build-xcode-debug", "configurePreset": "xcode-debug" }, + { "name": "build-vs-debug", "configurePreset": "vs2022-x64", "configuration": "Debug" } + ] +} + diff --git a/02-cmake/examples/steps/07-presets/README.md b/02-cmake/examples/steps/07-presets/README.md new file mode 100644 index 0000000..ac99ba7 --- /dev/null +++ b/02-cmake/examples/steps/07-presets/README.md @@ -0,0 +1,14 @@ +# 07 — CMake Presets + +Use presets to configure and build consistently across systems. + +Examples: + +``` +cmake --preset ninja-debug +cmake --build --preset build-ninja-debug + +cmake --preset vs2022-x64 +cmake --build --preset build-vs-debug +``` + diff --git a/02-cmake/examples/steps/07-presets/src/main.cpp b/02-cmake/examples/steps/07-presets/src/main.cpp new file mode 100644 index 0000000..4bc14cc --- /dev/null +++ b/02-cmake/examples/steps/07-presets/src/main.cpp @@ -0,0 +1,4 @@ +#include + +int main() { std::cout << "Presets demo\n"; } + diff --git a/02-cmake/examples/steps/08-toolchain-arm/CMakeLists.txt b/02-cmake/examples/steps/08-toolchain-arm/CMakeLists.txt new file mode 100644 index 0000000..00372f8 --- /dev/null +++ b/02-cmake/examples/steps/08-toolchain-arm/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.16) +project(ArmToolchainDemo C CXX) + +add_executable(app src/main.cpp) +target_compile_features(app PRIVATE cxx_std_20) + diff --git a/02-cmake/examples/steps/08-toolchain-arm/README.md b/02-cmake/examples/steps/08-toolchain-arm/README.md new file mode 100644 index 0000000..99ffa20 --- /dev/null +++ b/02-cmake/examples/steps/08-toolchain-arm/README.md @@ -0,0 +1,13 @@ +# 08 — Cross-compiling with a toolchain (ARM) + +Requires `arm-none-eabi-gcc` toolchain. + +``` +cmake -S . -B build-arm \ + -DCMAKE_TOOLCHAIN_FILE=toolchains/arm-none-eabi.cmake \ + -D CMAKE_BUILD_TYPE=Release +cmake --build build-arm +``` + +This produces binaries for the ARM target (not runnable on host). + diff --git a/02-cmake/examples/steps/08-toolchain-arm/src/main.cpp b/02-cmake/examples/steps/08-toolchain-arm/src/main.cpp new file mode 100644 index 0000000..b54a220 --- /dev/null +++ b/02-cmake/examples/steps/08-toolchain-arm/src/main.cpp @@ -0,0 +1,2 @@ +int main() { return 0; } + diff --git a/02-cmake/examples/steps/08-toolchain-arm/toolchains/arm-none-eabi.cmake b/02-cmake/examples/steps/08-toolchain-arm/toolchains/arm-none-eabi.cmake new file mode 100644 index 0000000..410563f --- /dev/null +++ b/02-cmake/examples/steps/08-toolchain-arm/toolchains/arm-none-eabi.cmake @@ -0,0 +1,5 @@ +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +set(CMAKE_C_COMPILER arm-none-eabi-gcc) +set(CMAKE_CXX_COMPILER arm-none-eabi-g++) + diff --git a/02-cmake/examples/steps/09-install-cpack/CMakeLists.txt b/02-cmake/examples/steps/09-install-cpack/CMakeLists.txt new file mode 100644 index 0000000..cfd1b72 --- /dev/null +++ b/02-cmake/examples/steps/09-install-cpack/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.16) +project(InstallPack LANGUAGES CXX) + +add_library(add src/add.cpp) +target_include_directories(add PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_compile_features(add PUBLIC cxx_std_20) + +add_executable(app src/main.cpp) +target_link_libraries(app PRIVATE add) + +install(TARGETS app add EXPORT packTargets + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + INCLUDES DESTINATION include) +install(DIRECTORY include/ DESTINATION include) +install(EXPORT packTargets NAMESPACE pack:: DESTINATION lib/cmake/pack) + +include(CPack) + diff --git a/02-cmake/examples/steps/09-install-cpack/README.md b/02-cmake/examples/steps/09-install-cpack/README.md new file mode 100644 index 0000000..890f351 --- /dev/null +++ b/02-cmake/examples/steps/09-install-cpack/README.md @@ -0,0 +1,15 @@ +# 09 — Install, export, and CPack + +Build and package: + +``` +cmake -S . -B build -D CMAKE_BUILD_TYPE=Release +cmake --build build --config Release +cmake --install build --prefix build/install +(cd build && cpack -G ZIP) +``` + +Artifacts: +- Installed tree under `build/install`. +- Package archive in `build/`. + diff --git a/02-cmake/examples/steps/09-install-cpack/include/add/add.h b/02-cmake/examples/steps/09-install-cpack/include/add/add.h new file mode 100644 index 0000000..6f9a9a5 --- /dev/null +++ b/02-cmake/examples/steps/09-install-cpack/include/add/add.h @@ -0,0 +1,8 @@ +#pragma once + +namespace addlib { + +int add(int x, int y); + +} + diff --git a/02-cmake/examples/steps/09-install-cpack/src/add.cpp b/02-cmake/examples/steps/09-install-cpack/src/add.cpp new file mode 100644 index 0000000..55d3824 --- /dev/null +++ b/02-cmake/examples/steps/09-install-cpack/src/add.cpp @@ -0,0 +1,8 @@ +#include "add/add.h" + +namespace addlib { + +int add(int x, int y) { return x + y; } + +} + diff --git a/02-cmake/examples/steps/09-install-cpack/src/main.cpp b/02-cmake/examples/steps/09-install-cpack/src/main.cpp new file mode 100644 index 0000000..97c2af1 --- /dev/null +++ b/02-cmake/examples/steps/09-install-cpack/src/main.cpp @@ -0,0 +1,8 @@ +#include +#include "add/add.h" + +int main() { + std::cout << addlib::add(10, 20) << "\n"; + return 0; +} + diff --git a/02-cmake/examples/steps/10-visual-studio/CMakeLists.txt b/02-cmake/examples/steps/10-visual-studio/CMakeLists.txt new file mode 100644 index 0000000..df49351 --- /dev/null +++ b/02-cmake/examples/steps/10-visual-studio/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) +project(VisualStudioTips LANGUAGES CXX) + +add_executable(app src/main.cpp) +target_compile_features(app PRIVATE cxx_std_20) + +set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT app) + diff --git a/02-cmake/examples/steps/10-visual-studio/README.md b/02-cmake/examples/steps/10-visual-studio/README.md new file mode 100644 index 0000000..a5b3ddf --- /dev/null +++ b/02-cmake/examples/steps/10-visual-studio/README.md @@ -0,0 +1,19 @@ +# 10 — Visual Studio (Windows) + +Configure and build with VS 2022 (x64): + +``` +cmake -S . -B build-vs -G "Visual Studio 17 2022" -A x64 +cmake --build build-vs --config Debug +``` + +Open solution: + +- `build-vs/VisualStudioTips.sln` → F7 to Build, Ctrl+F5 to Run. + +Tips: + +- Use clang-cl toolset: `-T clangcl` +- Use vcpkg for deps: `-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake` +- Set startup project via `VS_STARTUP_PROJECT` (already done). + diff --git a/02-cmake/examples/steps/10-visual-studio/src/main.cpp b/02-cmake/examples/steps/10-visual-studio/src/main.cpp new file mode 100644 index 0000000..0dbe3d0 --- /dev/null +++ b/02-cmake/examples/steps/10-visual-studio/src/main.cpp @@ -0,0 +1,7 @@ +#include + +int main() { + std::cout << "Visual Studio generator demo" << std::endl; + return 0; +} + diff --git a/02-cmake/examples/steps/README.md b/02-cmake/examples/steps/README.md new file mode 100644 index 0000000..f577d0c --- /dev/null +++ b/02-cmake/examples/steps/README.md @@ -0,0 +1,17 @@ +# Step-by-step CMake Examples + +Follow these incremental steps to learn/build from simple to advanced: + +1. `01-hello-plain` — compile a single file without CMake. +2. `02-hello-cmake` — minimal CMake project for the same program. +3. `03-lib-cmake` — add a library and link it. +4. `04-targets-modern` — target-based CMake (PUBLIC/PRIVATE, cxx_std_20). +5. `05-deps-fmt-find_package` — use external dependency via `find_package` (fmt). +6. `06-testing-ctest-gtest` — add tests with GoogleTest and run via CTest. +7. `07-presets` — use `CMakePresets.json` for multi-platform builds. +8. `08-toolchain-arm` — cross-compile with a toolchain file (ARM example). +9. `09-install-cpack` — install/export targets and make a ZIP with CPack. +10. `10-visual-studio` — Visual Studio generator and tips for Windows. + +Each folder contains a README with commands for Linux, macOS, and Windows. +