Understanding CMP0120 and CMake Policies


What is CMP0120?

CMP0120 is a CMake policy warning. It signifies a potential compatibility issue with older CMake versions when using certain language features or constructs. CMake policies are mechanisms to control the behavior of CMake in different environments.

CMake Policies: A Brief Overview

CMake is a cross-platform, open-source build system generator. It uses a scripting language to define and generate build systems (like Makefiles, Visual Studio projects, etc.).

  • NEW
    The behavior for newer CMake versions, often more consistent or feature-rich.
  • OLD
    The default behavior for older CMake versions.
  • Policy
    A CMake policy defines how CMake behaves in certain situations.

CMake provides a mechanism to set policies explicitly, but often, the default behavior is used. When CMake encounters a situation where the behavior can vary based on the policy, it issues a warning (like CMP0120) to inform the user about the potential compatibility implications.

Understanding CMP0120 Specifically

    • CMP0120 might be triggered when using relatively new language features or constructs in CMake.
    • For example, using newer generator expressions or advanced property definitions could lead to this warning.
  1. Compatibility with Older Generators

    • Some CMake features might work differently or not at all with older build system generators (like Makefiles for older compilers).
    • CMP0120 could indicate that the code might not build correctly with older generators.
  2. Policy-Controlled Behavior

    • Certain CMake behaviors are controlled by policies. Using features related to these policies might trigger CMP0120.
    • For example, if you're using a feature that depends on the CMP0027 policy (related to generator expressions), you might see CMP0120 if your target CMake version is below a certain threshold.

Resolving CMP0120

  1. Understand the Warning
    • Carefully read the warning message to understand the specific issue.
  2. Check Target CMake Versions
    • Determine the minimum CMake version required by your project.
  3. Set Policies Explicitly
    • If you're certain about the behavior you want, you can set the relevant policy explicitly using cmake_policy.
  4. Code Adaptation
    • In some cases, you might need to modify your CMake code to be compatible with older CMake versions or generators.
cmake_minimum_required(VERSION 3.12)
cmake_policy(SET CMP0120 NEW)

# ... rest of your CMake code ...

In this example:

  • We explicitly set the CMP0120 policy to NEW, indicating that we want the newer behavior.
  • We set the minimum required CMake version to 3.12.

Note
Always consider the trade-offs between compatibility and using newer features when dealing with CMake policies.

Need More Help? If you can provide more details about your CMake code, the specific CMP0120 warning message, and the target CMake versions you're supporting, I can offer more tailored advice.



  • The build system generator you're using (e.g., Makefiles, Visual Studio, etc.)
  • The target CMake versions you're supporting
  • The specific CMake version you're using
  • The exact CMake code where the warning is being triggered


Understanding the Issue

Before exploring alternatives, it's essential to understand why you're using WriteCompilerDetectionHeader in the first place. Common reasons include:

  • Conditional compilation based on compiler capabilities
  • Detecting compiler features (e.g., C++11, C++14, specific intrinsics)

Alternative Approaches

Manual Header Generation:

  • Cons
    Increased maintenance overhead, potential for errors.
  • Pros
    Full control over header content, potential performance benefits.
# Generate compiler_detection.h manually
file(WRITE compiler_detection.h ...)

Third-Party Libraries:

  • Other libraries might exist depending on your specific needs.

  • Hedley
    A CC0-licensed header-only library providing feature detection macros.

  • Cons
    Dependency management, potential licensing issues.

  • Pros
    Pre-built solutions, often well-tested.

Compiler-Specific Macros:

  • Cons
    Limited portability, potential for errors.
  • Pros
    Direct access to compiler features.
# Example for GCC/Clang
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
  # Use GCC/Clang specific macros
endif()

CMake's Built-in Features:

  • try_compile
    For testing code compilation.

  • check_include_files
    For header availability.

  • target_compile_features
    For C++ language features.

  • Cons
    Might not cover all required features.

  • Pros
    Portability, often easier to use.

Example Using Hedley

# Find Hedley library
find_package(Hedley REQUIRED)

# Use Hedley macros
if(HEDLEY_HAS_BUILTIN(__builtin_clz))
  # Compiler supports __builtin_clz
endif()
  • Feature Coverage
    Ensure the chosen method covers the required compiler features.
  • Performance
    In performance-critical code, direct compiler intrinsics might be preferable.
  • Maintenance
    Manual header generation requires careful maintenance.
  • Portability
    If targeting multiple compilers, consider using portable methods or third-party libraries.

Remember
The best approach depends on your specific project requirements, target compilers, and desired level of portability.

Would you like to provide more details about your use case for WriteCompilerDetectionHeader? This would help me suggest a more tailored solution.

Additional Tips

  • Keep your CMake code clean and organized.
  • Test your code thoroughly on various compilers to ensure compatibility.
  • Consider using a combination of methods for different features.