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/-Wextrafor strict warnings) - Cross-platform compatibility (e.g.,
NOMINMAXto 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 Group | Purpose |
|---|---|
KMCMAKE_GCC_FLAGS | Default flags for GCC (e.g., -Wall, -Wformat-security, -Wwrite-strings) |
KMCMAKE_LLVM_FLAGS | Default flags for Clang/AppleClang (e.g., -Wfloat-overflow-conversion, -Wunreachable-code) |
KMCMAKE_MSVC_FLAGS | Default flags for MSVC (e.g., /W3, /bigobj, /wd4267 for common warning suppression) |
KMCMAKE_XXX_TEST_FLAGS | Relaxed flags for test code (e.g., -Wno-unused-parameter for test-only noise reduction) |
KMCMAKE_ARCH_OPTION | Architecture-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_COPTSis auto-selected based on your compiler (e.g., GCC →KMCMAKE_GCC_FLAGS, Clang →KMCMAKE_LLVM_FLAGS).KMCMAKE_ARCH_OPTIONis no longer a fixed preset. It is built by runtime SIMD policy:- user sets
KMCMAKE_RUNTIME_SIMD_LEVEL(NONE..AVX512, defaultAVX2) simd_detect.cmakeprobes available capabilities (including AVX512 and ARM checks)kmcmake_apply_runtime_simdappends supported flags up to the requested level
- user sets
- 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:
################################
# 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
- Append to
KMCMAKE_CXX_OPTIONS: All custom flags must be added to this variable (kmcmake macros use it by default viaCXXOPTS). - Deduplicate: Retain
list(REMOVE_DUPLICATES KMCMAKE_CXX_OPTIONS)to avoid duplicate flags (e.g., overlapping default and custom flags). - Compiler Compatibility: Use conditional logic for compiler-specific flags (e.g.,
-fltofor GCC/Clang,/LTCGfor 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)
- Productive Presets: kmcmake preconfigures compiler/architecture-specific flags—no boilerplate for common scenarios.
- Centralized Control: All flags live in
cmake/myproject_cxx_config.cmake—no scatteredset(CMAKE_CXX_FLAGS)calls. - Seamless Merging: Custom flags merge with presets and are deduplicated for compatibility.
- Transparent Verification:
kmcmake_print_list_labelprovides 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.