Skip to main content

Customize C++ Compile Flags with kmcmake: Presets + Project-Specific Tweaks

kmcmake streamlines C++ compile flag management through a "preset + customization" design: it predefines production-grade flags for major compilers (GCC/Clang/MSVC) and CPU architectures, while enabling project-specific tweaks in a dedicated file—no scattered flag definitions or raw CMake boilerplate.

All flag configurations are centralized in cmake/myproject_cxx_config.cmake (generated by kmcmake by default), ensuring cross-platform consistency and maintainability.

Core Design: Predefined Flags for Common Scenarios

kmcmake ships with battle-tested default flags tailored to compilers, build types, and use cases—no need to start from scratch. These presets are optimized for:

  • Code quality (e.g., -Wall/-Wextra for strict warnings)
  • Cross-platform compatibility (e.g., NOMINMAX to avoid Windows macro conflicts)
  • Performance (e.g., architecture-specific SIMD flags)
  • Stability (e.g., relaxed warnings for test code to reduce noise)

Key Predefined Flag Groups (in myproject_cxx_config.cmake)

Flag GroupPurpose
KMCMAKE_GCC_FLAGSDefault flags for GCC (e.g., -Wall, -Wformat-security, -Wwrite-strings)
KMCMAKE_LLVM_FLAGSDefault flags for Clang/AppleClang (e.g., -Wfloat-overflow-conversion, -Wunreachable-code)
KMCMAKE_MSVC_FLAGSDefault flags for MSVC (e.g., /W3, /bigobj, /wd4267 for common warning suppression)
KMCMAKE_XXX_TEST_FLAGSRelaxed flags for test code (e.g., -Wno-unused-parameter for test-only noise reduction)
KMCMAKE_ARCH_OPTIONArchitecture-specific flags assembled from KMCMAKE_RUNTIME_SIMD_LEVEL + detected CPU/compiler support

Example: Default GCC Flags (Predefined)

kmcmake preconfigures strict yet practical flags for GCC out of the box:

# From kmcmake-generated myproject_cxx_config.cmake
list(APPEND KMCMAKE_GCC_FLAGS
"-Wall" # Enable basic warnings
"-Wextra" # Enable extended warnings
"-Wno-cast-qual" # Suppress non-critical warning
"-Wformat-security" # Prevent format string vulnerabilities
"-Woverlength-strings" # Warn on overly long strings
"-Wpointer-arith" # Warn on unsafe pointer operations
"-Wwrite-strings" # Treat string literals as const (safer)
"-Wclass-memaccess" # Warn on invalid class member access
"-DNOMINMAX" # Disable Windows-style min/max macros
)

Step 1: Understand Flag Aggregation Logic

kmcmake automatically aggregates flags into KMCMAKE_CXX_OPTIONS (the final flag list used by all kmcmake macros like kmcmake_cc_library/binary via the CXXOPTS parameter):

# From myproject_cxx_config.cmake (generated logic)
set(KMCMAKE_CXX_OPTIONS
${KMCMAKE_DEFAULT_COPTS} # Compiler-specific default flags (e.g., KMCMAKE_GCC_FLAGS)
${KMCMAKE_ARCH_OPTION} # Architecture/SIMD flags (e.g., AVX2)
${KMCMAKE_RANDOM_RANDEN_COPTS} # Crypto-related architecture flags
)
  • KMCMAKE_DEFAULT_COPTS is auto-selected based on your compiler (e.g., GCC → KMCMAKE_GCC_FLAGS, Clang → KMCMAKE_LLVM_FLAGS).
  • KMCMAKE_ARCH_OPTION is no longer a fixed preset. It is built by runtime SIMD policy:
    • user sets KMCMAKE_RUNTIME_SIMD_LEVEL (NONE..AVX512, default AVX2)
    • simd_detect.cmake probes available capabilities (including AVX512 and ARM checks)
    • kmcmake_apply_runtime_simd appends supported flags up to the requested level
  • Flags are deduplicated with list(REMOVE_DUPLICATES KMCMAKE_CXX_OPTIONS) to avoid conflicts.
  • The final flag list is printed during build via kmcmake_print_list_label("CXX_OPTIONS:" KMCMAKE_CXX_OPTIONS) for verification.

Step 2: Add Project-Specific Flags

To customize flags, edit cmake/myproject_cxx_config.cmake—kmcmake reserves a dedicated section (marked by #define your options here) for project-specific tweaks, no modifications to kmcmake core are needed.

Example: Add Custom Warnings & Optimizations

To disable redundant warnings, enable OpenMP, and enable Link-Time Optimization (LTO), modify the reserved section:

cmake/myproject_cxx_config.cmake
################################
# Follow CC flags provided by kmcmake:
# ${KMCMAKE_DEFAULT_COPTS}
# ${KMCMAKE_TEST_COPTS}
# ${KMCMAKE_ARCH_OPTION} (computed from runtime SIMD level + detection)
# ${KMCMAKE_RANDOM_RANDEN_COPTS}
##############################################################################
set(KMCMAKE_CXX_OPTIONS ${KMCMAKE_DEFAULT_COPTS} ${KMCMAKE_ARCH_OPTION} ${KMCMAKE_RANDOM_RANDEN_COPTS})
###############################
#
# Define your options here <-- kmcmake-reserved customization section
# e.g., list(APPEND KMCMAKE_CXX_OPTIONS "-fopenmp") # kmcmake example comment
# 1. Disable redundant warnings
list(APPEND KMCMAKE_CXX_OPTIONS
"-Wno-redundant-move"
"-Wno-deprecated-declarations"
"-Wno-strict-aliasing"
)
# 2. Enable OpenMP (parallel computing)
list(APPEND KMCMAKE_CXX_OPTIONS "-fopenmp")
# 3. Enable LTO (Link-Time Optimization for performance)
list(APPEND KMCMAKE_CXX_OPTIONS "-flto")

# Remove duplicates (avoid conflicts with default flags)
list(REMOVE_DUPLICATES KMCMAKE_CXX_OPTIONS)
kmcmake_print_list_label("CXX_OPTIONS:" KMCMAKE_CXX_OPTIONS) # Print final flags

Critical Customization Rules

  1. Append to KMCMAKE_CXX_OPTIONS: All custom flags must be added to this variable (kmcmake macros use it by default via CXXOPTS).
  2. Deduplicate: Retain list(REMOVE_DUPLICATES KMCMAKE_CXX_OPTIONS) to avoid duplicate flags (e.g., overlapping default and custom flags).
  3. Compiler Compatibility: Use conditional logic for compiler-specific flags (e.g., -flto for GCC/Clang, /LTCG for MSVC):
    # Cross-compiler LTO configuration
    if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
    list(APPEND KMCMAKE_CXX_OPTIONS "-flto")
    elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
    list(APPEND KMCMAKE_CXX_OPTIONS "/LTCG")
    endif ()

Step 3: Verify Final Flags

Build the project as usual—kmcmake prints the final CXX_OPTIONS during the configure phase (visible in build output):

cd myproject  # Project root directory
cmake --build build

Example Output (GCC, runtime SIMD level = AVX2)

-- KMCMAKE ARCH FLAGS -mavx2 -mfma
-- CXX_OPTIONS:
- -Wall
- -Wextra
- -Wno-cast-qual
- -Wformat-security
- ... (other default flags)
- -Wno-redundant-move
- -fopenmp
- -flto
- -mavx2
- -mfma

This confirms custom flags are merged with kmcmake’s presets correctly.

Step 4: Advanced Customization (Optional)

Override Default Flags

To replace a default flag (instead of appending), modify KMCMAKE_DEFAULT_COPTS before it’s added to KMCMAKE_CXX_OPTIONS:

# Replace "-O2" with "-O3" for Release builds
if (CMAKE_BUILD_TYPE STREQUAL "Release")
string(REPLACE "-O2" "-O3" KMCMAKE_DEFAULT_COPTS "${KMCMAKE_DEFAULT_COPTS}")
endif ()

Test-Specific Flag Customization

kmcmake predefines KMCMAKE_TEST_COPTS (relaxed flags for test code). To extend it:

# Add extra relaxed warnings for test code
list(APPEND KMCMAKE_TEST_COPTS "-Wno-unused-variable" "-Wno-missing-prototypes")

Key Takeaways (kmcmake Flag Design Core)

  1. Productive Presets: kmcmake preconfigures compiler/architecture-specific flags—no boilerplate for common scenarios.
  2. Centralized Control: All flags live in cmake/myproject_cxx_config.cmake—no scattered set(CMAKE_CXX_FLAGS) calls.
  3. Seamless Merging: Custom flags merge with presets and are deduplicated for compatibility.
  4. Transparent Verification: kmcmake_print_list_label provides clear visibility into final flags—no guesswork.

This design balances "batteries included" convenience (predefined production-grade flags) with flexibility (project-specific tweaks), aligning with kmcmake’s "convention over configuration" philosophy.