Alternatives to MSVC14 for MSVC Compiler Detection in CMake


MSVC14 Variable in CMake

  • Functionality
    CMake automatically sets MSVC14 to TRUE when it detects this specific compiler environment. This variable can be used in your CMakeLists.txt file conditionally to tailor build configurations based on the compiler being used.

  • Purpose
    The MSVC14 variable is an internal variable within CMake that indicates whether you're using Microsoft Visual Studio (MSVC) version 14.0 (also known as Visual Studio 2015) or another compiler that emulates its command-line syntax (like Clang-CL).

Limited Use and Recommendation

  • Deprecation
    While MSVC14 still exists in CMake for backward compatibility, it's recommended to use the more general MSVC_VERSION variable instead. This variable provides a more detailed version number (e.g., 14.0 for MSVC 2015) and is likely to be maintained in future CMake releases.

Example Usage (Conditional Compilation)

if(MSVC14)  # Or, preferably: if(MSVC_VERSION LESS EQUAL 14.0)
  # Code specific to MSVC 2015 or similar compilers
  message(STATUS "Using MSVC 2015 or compatible compiler")
  # Add compiler-specific flags, define preprocessor macros, etc.
else()
  # Code for other compilers
  message(STATUS "Using compiler other than MSVC 2015")
endif()

Key Points

  • Conditional compilation allows you to adjust build settings based on the compiler.
  • MSVC14 only indicates version 14.0 specifically.
  • Use MSVC_VERSION for more reliable and future-proof compiler detection.


Using MSVC_VERSION for Compiler Detection

# Check if the compiler is MSVC and its version is less than or equal to 14.0 (MSVC 2015)
if(MSVC_VERSION LESS EQUAL 14.0)
  message(STATUS "Using MSVC 2015 or compatible compiler (version: ${MSVC_VERSION})")
  # Add compiler-specific flags (e.g., for warnings)
  target_compile_features(my_executable PUBLIC /W4)
else()
  message(STATUS "Using compiler other than MSVC 2015 (version: ${MSVC_VERSION})")
  # Use different compiler flags or preprocessor definitions
endif()

This example not only checks the compiler type but also provides the actual version number for reference. Additionally, it conditionally adds a compiler flag (/W4 for more warnings) specific to MSVC.

Using Generator Expressions for Compiler-Specific Source Files

# Define source files based on the compiler
set(source_files
  source1.cpp
  source2.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/msvc_specific_source.cpp IF MSVC)
)

add_executable(my_executable ${source_files})

This example uses a generator expression (IF MSVC) to conditionally include msvc_specific_source.cpp only when building with MSVC. This allows you to have source files specific to the compiler environment.

Using a Custom Variable for MSVC Version Range Detection

# Define a custom variable for MSVC version range (replace 15.0 with your desired version)
option(USE_MSVC_15_FEATURES "Enable features specific to MSVC 2017 and above" OFF)

if(MSVC_VERSION AND USE_MSVC_15_FEATURES)
  if(MSVC_VERSION GREATER EQUAL 15.0)
    message(STATUS "Using MSVC 2017 or compatible compiler (version: ${MSVC_VERSION})")
    # Add compiler-specific flags and preprocessor definitions
    target_compile_features(my_library PUBLIC /experimental:new_cpp_feature)
  else()
    message(STATUS "MSVC version is less than 15.0, disabling new features")
  endif()
else()
  message(STATUS "Using compiler other than MSVC 2017")
endif()

This example defines a custom boolean option (USE_MSVC_15_FEATURES) that allows users to explicitly enable features specific to MSVC versions greater than or equal to 15.0 (MSVC 2017). It then checks both MSVC_VERSION and the custom option to conditionally add compiler flags and features.



Use MSVC_VERSION

  • You can use comparison operators (LESS EQUAL, GREATER EQUAL) to target specific version ranges.
  • It provides a more detailed version number (e.g., 14.0 for MSVC 2015, 19.29 for MSVC 2019).
  • This is the preferred and future-proof method.

Example

if(MSVC_VERSION LESS EQUAL 14.0)
  # Code specific to MSVC 2015 or similar compilers
  message(STATUS "Using MSVC 2015 or compatible compiler (version: ${MSVC_VERSION})")
else()
  # Code for other compilers
  message(STATUS "Using compiler other than MSVC 2015 (version: ${MSVC_VERSION})")
endif()

Use Generator Expressions with CMAKE_GENERATOR_PLATFORM

  • CMAKE_GENERATOR_PLATFORM indicates the platform for which you're generating the build system files.
  • This approach is useful when compiler behavior is tied to the target platform (e.g., Windows vs. Linux).

Example

set(source_files
  source1.cpp
  source2.cpp
  ${CMAKE_CURRENT_SOURCE_DIR}/windows_specific_source.cpp IF WIN32)
)

add_executable(my_executable ${source_files})
  • In this case, WIN32 within the generator expression conditionally includes windows_specific_source.cpp only when building for Windows platforms, which typically use MSVC.

Use a Custom Variable for Specific Version Ranges

  • This option provides more control for targeting specific MSVC version ranges.

Example

option(USE_MSVC_17_FEATURES "Enable features specific to MSVC 2017 and above" OFF)

if(MSVC_VERSION AND USE_MSVC_17_FEATURES)
  if(MSVC_VERSION GREATER EQUAL 17.0)
    message(STATUS "Using MSVC 2017 or compatible compiler (version: ${MSVC_VERSION})")
    # Add compiler-specific flags and preprocessor definitions
  else()
    message(STATUS "MSVC version is less than 17.0, disabling new features")
  endif()
else()
  message(STATUS "Using compiler other than MSVC 2017")
endif()
  • Combine it with MSVC_VERSION for conditional compilation based on version range.
  • Define a custom boolean option (e.g., USE_MSVC_17_FEATURES) to enable features specific to MSVC versions 17.0 and above (MSVC 2017).

Remember to replace 17.0 with the specific MSVC version you're targeting.