20 Commandments for Building Qt Projects with Modern CMake

1. Basic Principles

Commandment 1: Minimum Version Declaration

cmake_minimum_required(VERSION 3.21) # Requires support for Qt6's AUX_SOURCE_DIRECTORY improvementproject(MyApp     VERSION 1.2.3     LANGUAGES CXX)

Commandment 2: Strict Policy Configuration

# Enforce interface compatibility checks
cmake_policy(SET CMP0063 NEW)  # Target link library order
cmake_policy(SET CMP0079 NEW)  # Target import file generation

2. Qt Integration Standards

Commandment 3: Modular Qt Lookup

find_package(Qt6 COMPONENTS     Core Gui Widgets Concurrent Sql    REQUIRED)
# Automatically obtain meta-object processing target
set(QT6_FEATURE_qt_aux_source_dir ON)

Commandment 4: Meta-Object Automation

# Automatically handle moc/uic/rcc
qt_standard_project_setup()
# Explicitly declare files to be processed
qt_add_executable(my_app     MANUAL_FINALIZATION    SOURCES main.cpp MainWindow.cpp    HEADERS MainWindow.h    RESOURCES resources.qrc    UI ui/mainwindow.ui)

3. Target Definition Essentials

Commandment 5: Target Property Interface

add_library(app_core STATIC)
target_compile_features(app_core PUBLIC cxx_std_17)
# Interface-level property configuration
set_target_properties(app_core PROPERTIES    C_VISIBILITY_PRESET hidden    CXX_VISIBILITY_PRESET hidden)

Commandment 6: Qt Module Linking Standards

# Prohibit ALL linking

target_link_libraries(app_core     PRIVATE         Qt6::Core         Qt6::Concurrent)
# Plugin-level dependencies
if(ANDROID)    target_link_libraries(app_core PRIVATE Qt6::GuiAndroidExtras)endif()

4. Advanced Dependency Management

Commandment 7: Sandwich Dependency Model

# 1. Official packages take priority
find_package(ZLIB REQUIRED)
# 2. FetchContent secondary
include(FetchContent)
FetchContent_Declare(json URL https://github.com/nlohmann/json...)
FetchContent_MakeAvailable(json)
# 3. CPM fallback
include(cmake/CPM.cmake)
CPMAddPackage("gh:fmtlib/fmt#8.1.1")

5. Cross-Platform Key Strategies

Commandment 8: Conditional Compilation Standards

# Error example: global
add_definitions(-DMACRO)
target_compile_definitions(app_core    PRIVATE        $<platform_id:windows:win32_lean_and_mean>        $<platform_id:linux:_xopen_source=600>)
# Resource path redirection
if(APPLE)    set(MACOS_BUNDLE_RESOURCES_DIR "${CMAKE_BINARY_DIR}/Resources")    file(COPY images DESTINATION ${MACOS_BUNDLE_RESOURCES_DIR})endif()</platform_id:linux:_xopen_source=600></platform_id:windows:win32_lean_and_mean>

Commandment 9: Android/iOS Special Configurations

# Android APK build template
qt_add_executable(my_app MANUAL_FINALIZATION)
qt_finalize_executable(my_app)
# iOS bundle settings
set_target_properties(my_app PROPERTIES    MACOSX_BUNDLE TRUE    MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)

6. Advanced Build Techniques

Commandment 10: Automatic Qt Wrapper Generation

# Custom command to replace qt_wrap_cpp
add_custom_command(    OUTPUT moc_core.cpp    COMMAND Qt::moc ${CMAKE_CURRENT_SOURCE_DIR}/core.h             -o ${CMAKE_CURRENT_BINARY_DIR}/moc_core.cpp    DEPENDS core.h)
target_sources(app_core PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/moc_core.cpp)

7. Architectural Design Standards

Commandment 11: Component-Based Design

# Logical components
add_subdirectory(core)
add_subdirectory(gui)
add_subdirectory(plugins)
# Explicit component dependencies
target_link_libraries(gui     PUBLIC         app_core        Qt6::Widgets)

8. Installation and Deployment Rules

Commandment 12: Cross-Platform Installation Rules

# Windows installer generation
include(InstallRequiredSystemLibraries)
set(CPACK_NSIS_EXECUTABLES_DIRECTORY .)
include(CPack)
# Linux desktop integration
install(TARGETS my_app RUNTIME DESTINATION bin)
install(FILES my_app.desktop DESTINATION share/applications)

9. Toolchain Integration

Commandment 13: Multi-Compiler Backend Support

# Detect Ninja acceleration
find_program(NINJA_EXE ninja)
if(NINJA_EXE)    set(CMAKE_GENERATOR Ninja CACHE INTERNAL "")endif()
# Multi-configuration build
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo" CACHE STRING "")

10. Quality Assurance System

Commandment 14: Unit Test Integration

# GoogleTest integration
include(GoogleTest)
add_executable(test_core tests/test_core.cpp)
target_link_libraries(test_core     PRIVATE         app_core         GTest::gtest_main)
gtest_discover_tests(test_core)

11. Advanced Debugging Techniques

Commandment 15: Symbol File Management

if(MSVC)    # Control PDB generation location
    set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/pdb)
    set(CMAKE_PDB_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/pdb)endif()
# Separate debug information on Linux
add_custom_command(TARGET app_core POST_BUILD    COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $<target_file:app_core> app_core.sym    COMMAND ${CMAKE_OBJCOPY} --strip-debug $<target_file:app_core>)</target_file:app_core></target_file:app_core>

12. Performance Optimization Techniques

Commandment 16: Precompiled Header Files

# Cross-platform PCH support
target_precompile_headers(app_core     PRIVATE         <memory>        <vector>        <qtcore>        <qtgui>)</qtgui></qtcore></vector></memory>

Commandment 17: Link-Time Optimization

# LTO configuration (Clang/GCC)
check_ipo_supported(RESULT ipo_supported)
if(ipo_supported)    set_target_properties(app_core PROPERTIES         INTERPROCEDURAL_OPTIMIZATION TRUE    )endif()

13. Security Hardening Solutions

Commandment 18: Compilation Hardening Options

# Secure compilation flags
if(UNIX AND NOT APPLE)    target_compile_options(app_core         PRIVATE             -fstack-protector-strong            -D_FORTIFY_SOURCE=2    )    target_link_options(app_core        PRIVATE            -Wl,-z,now,-z,relro,-z,defs    )endif()

14. Continuous Integration Integration

Commandment 19: CI Environment Adaptation

# General CI detection
if(DEFINED ENV{CI})    add_compile_options(-Werror)    set(CMAKE_EXPORT_COMPILE_COMMANDS ON)endif()

Commandment 20: Documentation Integration

# Doxygen integration
find_package(Doxygen)
if(DOXYGEN_FOUND)    set(DOXYGEN_EXCLUDE_PATTERNS */tests/*)    doxygen_add_docs(docs         ${PROJECT_SOURCE_DIR}/core        COMMENT "Generate API documentation"    )endif()

Leave a Comment