Skip to main content

programming-cmake-best-practices

Create, refactor, link, and build CMake projects following modern CMake guidelines from official documentation

설치로 이동

소스 정보

저장소
ROCm/rocprofiler-systems-skills
최근 소스 활동
2026년 2월 9일 09:12
감지된 SKILL.md 언어
영어
스타
4
포크
0

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
programming-cmake-best-practices
description
Create, refactor, link, and build CMake projects following modern CMake guidelines from official documentation
# CMake Best Practices You are an expert in modern CMake (3.15+) following official guidelines. Your task is to help create, refactor, and maintain CMake build systems using target-based, declarative patterns. ## Core Principles 1. **Think in terms of targets, not variables** - Use `target_*()` commands instead of global variables 2. **Be declarative, not imperative** - Describe what you want, not how to build it 3. **Avoid global scope pollution** - Keep settings attached to specific targets 4. **Use generator expressions** for conditional logic that depends on build configuration 5. **Prefer `PUBLIC`, `PRIVATE`, `INTERFACE`** keywords to control transitive dependencies ## Creating New CMake Projects ### Minimum CMakeLists.txt Structure ```cmake cmake_minimum_required(VERSION 3.15...3.28) project(ProjectName VERSION 1.0.0 DESCRIPTION "Brief description" LANGUAGES CXX) # Set C++ standard as a project-wide default set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # Create executable or library target add_executable(myapp src/main.cpp) # OR add_library(mylib src/mylib.cpp) # Link dependencies (modern way) target_link_libraries(myapp PRIVATE mylib) ``` ### Directory Structure Best Practices ``` project/ ├── CMakeLists.txt # Root CMake file ├── cmake/ # Custom CMake modules ├── src/ # Source files │ └── CMakeLists.txt # Add with add_subdirectory() ├── include/ # Public headers │ └── project/ ├── tests/ # Test files │ └── CMakeLists.txt └── external/ # Third-party dependencies ``` ## Refactoring to Modern CMake ### Replace Global Variables with Target Properties **OLD (avoid):** ```cmake include_directories(${PROJECT_SOURCE_DIR}/include) add_definitions(-DMY_DEFINE) link_directories(${SOME_LIB_DIR}) ``` **NEW (use this):** ```cmake target_include_directories(mylib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $) target_compile_definitions(mylib PRIVATE MY_DEFINE) target_link_libraries(mylib PUBLIC somelib) ``` ### Visibility Keywords (PUBLIC/PRIVATE/INTERFACE) - **PRIVATE**: Only this target needs it - **INTERFACE**: Consumers of this target need it, but this target doesn't - **PUBLIC**: Both this target and its consumers need it ```cmake target_include_directories(mylib PUBLIC include/ # Headers consumers will use PRIVATE src/ # Internal implementation headers ) target_link_libraries(mylib PUBLIC fmt::fmt # Appears in public API PRIVATE sqlite3 # Internal implementation detail ) ``` ## Modern Linking Patterns ### Using find_package() with Imported Targets ```cmake find_package(Boost 1.70 REQUIRED COMPONENTS system filesystem) target_link_libraries(myapp PRIVATE Boost::system Boost::filesystem) ``` ### Using FetchContent for Dependencies (CMake 3.14+) ```cmake include(FetchContent) FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG v1.14.0 ) FetchContent_MakeAvailable(googletest) target_link_libraries(mytests PRIVATE GTest::gtest_main) ``` ### Creating Interface Libraries (Header-Only) ```cmake add_library(myheaderlib INTERFACE) target_include_directories(myheaderlib INTERFACE include/) target_compile_features(myheaderlib INTERFACE cxx_std_17) ``` ## Building and Configuration ### Proper Out-of-Source Build Commands ```bash # Configure cmake -S . -B build -DCMAKE_BUILD_TYPE=Release # Build cmake --build build --config Release # Install cmake --install build --prefix /usr/local # Test ctest --test-dir build ``` ### Setting Compiler Flags (Modern Way) ```cmake target_compile_options(myapp PRIVATE $<$:-Wall -Wextra -pedantic> $<$:/W4> ) ``` ### Export and Install Targets ```cmake install(TARGETS mylib EXPORT mylibTargets LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin INCLUDES DESTINATION include ) install(EXPORT mylibTargets FILE mylibTargets.cmake NAMESPACE mylib:: DESTINATION lib/cmake/mylib ) ``` ## Common Refactoring Tasks ### Converting to Modern target-based CMake 1. **Identify all executables and libraries** - List all `add_executable()` and `add_library()` calls 2. **Replace global commands** - Convert `include_directories()`, `link_libraries()`, etc. to `target_*()` equivalents 3. **Add visibility keywords** - Determine what should be PUBLIC vs PRIVATE 4. **Use generator expressions** - Replace if/else with `$<...>` for config-dependent settings 5. **Modularize with subdirectories** - Use `add_subdirectory()` for organized structure ### Testing the Refactoring ```bash # Clean build to ensure no leftover state rm -rf build && cmake -S . -B build cmake --build build ctest --test-dir build --output-on-failure ``` ## Guidelines Summary - Always use `cmake_minimum_required()` at the top - Never use `file(GLOB)` for source files in production - list them explicitly - Use `target_sources()` to add sources after target creation - Prefer `option()` for user-configurable settings - Use `CMAKE_PROJECT_NAME` instead of hardcoded project names - Set properties with `set_target_properties()` when needed - Use `cmake_path()` (CMake 3.20+) for path manipulation - Enable testing with `enable_testing()` and use `add_test()` ## Resources - **Official CMake Documentation**: https://cmake.org/cmake/help/latest/ - Modern CMake guide: Search for "cmake-buildsystem(7)" - Command reference: https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html - **CMake Discourse**: https://discourse.cmake.org/ (for specific questions) - **"An Introduction to Modern CMake"**: https://cliutils.gitlab.io/modern-cmake/ - **CMake Generator Expressions**: https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html - For package finding: Search official docs for "Find<PackageName>.cmake" modules - For debugging: Use `cmake --trace` or `message(STATUS "...")` statements
GitHub에서 보기