<commit_before># Set project name
project(tundra)

# CMake version requirement, >= 2.5.5 to ensure that ProtoBuf is found ok.
cmake_minimum_required(VERSION 2.5.5)

# TUNDRA_NO_BOOST defines whether we want to replace usage of Boost with the C++ (TR1) standard equivalents.
# Setting TUNDRA_NO_BOOST to TRUE, i.e. disabling usage of Boost in the Tundra codebase, requires compiler
# with up-to-date C++ TR1 and preferably the C99 standard cstdint header. Also if the used compiler has C++11 
# make_shared function available, it is used.
# If TUNDRA_NO_BOOST is set to TRUE, kNet must also be built without Boost dependecy. In order to make the
# Tundra build fully free of Boost, you must also build Ogre and AssImp, which depend on Boost by default,
# with Boost disabled. See the dependencies scripts for instructions how to control this.
option(TUNDRA_NO_BOOST "Specifies whether Tundra is build without Boost." TRUE)

macro(PrintUsedEnvVariables)
    # Print out the resolved variables. Note that this does not print the env variables
    # in most cases as they should be resolved to our cmake variables and get cached.
    # This way this printed list wont lie if ran without env variables and we are still
    # succesfully finding all the deps from our cacher (or in bad cases assumed) dirs.
    message("\n=========== Used Environment Variables ===========\n")
    message(STATUS "TUNDRA_DEP_PATH  = " ${ENV_TUNDRA_DEP_PATH})
    message(STATUS "QTDIR            = " ${ENV_QT_DIR})
    if (NOT TUNDRA_NO_BOOST)
        message (STATUS "BOOST_ROOT       = " ${BOOST_ROOT})
    endif()
    message(STATUS "OGRE_HOME        = " ${OGRE_DIR}) # OGRE_DIR is our internal OGRE_HOME
    message(STATUS "SKYX_HOME        = " ${SKYX_HOME})
    message(STATUS "HYDRAX_HOME      = " ${HYDRAX_HOME})
    message(STATUS "KNET_DIR         = " ${KNET_DIR})
    message(STATUS "BULLET_DIR       = " ${BULLET_DIR})
endmacro()

macro (PrintUsedBuildConfig)
    message ("\n=========== Used Build Configuration =============\n")
    message (STATUS "TUNDRA_NO_BOOST            = " ${TUNDRA_NO_BOOST})
    message (STATUS "TUNDRACORE_SHARED          = " ${TUNDRACORE_SHARED})
    message (STATUS "BUILD_SDK_ONLY             = " ${BUILD_SDK_ONLY})
    message (STATUS "BUILDING_INSTALLER         = " ${BUILDING_INSTALLER})
    message (STATUS "ENABLE_BUILD_OPTIMIZATIONS = " ${ENABLE_BUILD_OPTIMIZATIONS})
    message (STATUS "ENABLE_HYDRAX              = " ${ENABLE_HYDRAX})
    message (STATUS "ENABLE_SKYX                = " ${ENABLE_SKYX})
    message (STATUS "ENABLE_OPEN_ASSET_IMPORT   = " ${ENABLE_OPEN_ASSET_IMPORT})
    message (STATUS "ENABLE_PROFILING           = " ${ENABLE_PROFILING})
    message (STATUS "ENABLE_JS_PROFILING        = " ${ENABLE_JS_PROFILING})
    message (STATUS "ENABLE_MEMORY_LEAK_CHECKS  = " ${ENABLE_MEMORY_LEAK_CHECKS})
    message ("")
    message (STATUS "Install prefix = " ${CMAKE_INSTALL_PREFIX})
    message ("")
endmacro ()

macro(GetLastElementFromPath dirPath outputParam)
    string (FIND ${dirPath} "/" lastPathSepIndex REVERSE)
    # This path does not have any subdirs in it
    if (${lastPathSepIndex} STREQUAL "-1")
        set (${outputParam} ${dirPath})
    # Path has subdirs, pick the last
    else ()
        math(EXPR lastPathSepIndex "${lastPathSepIndex} + 1")
        string(SUBSTRING ${dirPath} ${lastPathSepIndex} -1 ${outputParam})
    endif ()
endmacro ()

# The AddEntityComponent macro adds the static EC lib from the given sourceFolder directory to the build.
# The componentName == A subfolder in src/EntityComponents/ or a relative path to the EC directory where the CMakeLists.txt is located.
# Use this macro when adding ECs to the build, since this macro tracks the set of ECs that are added, so that the individual
# modules get #defines in C++ code for each EC that is present. This allows conditionally excluding ECs from the build.
# Note that for eg. AddEntityComponent(3rdparty/myecs/EC_Thingie) the define will be EC_Thingie_ENABLED and you would expect.
# Examples:     AddEntityComponent(EC_Sound)
#               AddEntityComponent(3rdparty/myecs/EC_Thingie)
macro(AddEntityComponent componentName)
    # Chekc if the component is in our default entity components location
    # note: from cmake docs: IS_DIRECTORY Behavior is well-defined only for full paths.
    if (IS_DIRECTORY ${PROJECT_BINARY_DIR}/src/EntityComponents/${componentName})
        add_subdirectory (src/EntityComponents/${componentName})
        set (${componentName}_ENABLED 1)
        set (USED_ENTITYCOMPONENTS ${USED_ENTITYCOMPONENTS} ${componentName})
    elseif (IS_DIRECTORY ${PROJECT_BINARY_DIR}/${componentName})
        add_subdirectory (${componentName})
        GetLastElementFromPath(${componentName} compNameFromRelPath)
        set(${compNameFromRelPath}_ENABLED 1)
        set(USED_ENTITYCOMPONENTS ${USED_ENTITYCOMPONENTS} ${compNameFromRelPath})
    else ()
        message(FATAL_ERROR "Could not resolve AddEntityComponent() call with path " ${componentName} ". Are you sure the component is there?")
    endif ()
endmacro()

# AddProject takes in one or two parameters: 
# - One param  : argv0 == the relative directory (to the root CMakeLists.txt) where you project is and that contains the CMakeLists.txt for this project.
# - Two params : argv0 == 'Core'|'Application'. argv1 folder name of the project in the src/argv0/
# More useful for building the Tundra project when including platform provided projects.
# Note: One param projects or two param "Application" type plugins will always be omitted if BUILD_SDK_ONLY is true!
# Note: Due to the cmake add_subdirectory restrictions, the directory cannot be outside the Tundra source tree, hopefully we can go around this one day.
# Examples:     AddProject(Core Input)
#               AddProject(Application JavascriptModule)
#               AddProject(mysubdir/MyPlugin)
function(AddProject)
    if (NOT ARGV1)
        if (BUILD_SDK_ONLY)
            message (STATUS "** Omitting Application level project " ${ARGV0} " because BUILD_SDK_ONLY is set to TRUE")
        else ()
            add_subdirectory(${ARGV0})
        endif ()
    else ()
        if (NOT ${ARGV0} STREQUAL "Core" AND NOT ${ARGV0} STREQUAL "Application")
            message (FATAL_ERROR "You are trying to use AddProject macro with invalid project type parameter: " ${ARGV0} " with project name " ${ARGV1})
        endif()
        if (BUILD_SDK_ONLY AND ${ARGV0} STREQUAL "Application")
            message (STATUS "** Omitting Application level project " ${ARGV1} " because BUILD_SDK_ONLY is set to TRUE")
        else ()
            add_subdirectory(src/${ARGV0}/${ARGV1})
        endif ()
    endif ()
endfunction()

# Generates in the current project a #define for each EC that has been added to the build. Use this macro in your module CMakeLists.txt
# to receive information in C++ about which ECs have been added to the project. This allows supporting conditional compilation of the ECs in your module.
macro(GetEntityComponents)
   foreach(componentName ${USED_ENTITYCOMPONENTS})
      add_definitions(-D${componentName}_ENABLED)
   endforeach()
endmacro()

# Adds the given folder_name into the source files of the current project. Use this macro when your module contains .cpp and .h files in several subdirectories.
macro(AddSourceFolder folder_name)
    file(GLOB H_FILES_IN_FOLDER_${folder_name} ${folder_name}/*.h ${folder_name}/*.inl)
    file(GLOB CPP_FILES_IN_FOLDER_${folder_name} ${folder_name}/*.cpp)
    source_group("Header Files\\${folder_name}" FILES ${H_FILES_IN_FOLDER_${folder_name}})
    source_group("Source Files\\${folder_name}" FILES ${CPP_FILES_IN_FOLDER_${folder_name}})
    set(H_FILES ${H_FILES} ${H_FILES_IN_FOLDER_${folder_name}})
    set(CPP_FILES ${CPP_FILES} ${CPP_FILES_IN_FOLDER_${folder_name}})
endmacro()

# Moves all Qt moc-compiler generated files into their own folder in the Visual Studio project. Call this once after having added all source files in the build in your module,
# but before the call to 'set (SOURCE_FILES ...)' directive.
# This macro is optional and for "conveniency" only. If you omit this call, you will have all the generated moc files in the Visual Studio project root.
# TODO: Add support for more deep folder structures. Current
#       implementation only support folders directly under project folder
macro(MocFolder)
    file(GLOB MOCS_TO_SOURCE_GROUP *.cxx */*.cxx)
    source_group("CMake Moc" FILES ${MOCS_TO_SOURCE_GROUP})
endmacro()

# Moves all Qt ui copmiler-generated .h files into their own folder in the Visual Studio project. Call this once after having added all source files in the build in your module.
# This macro is optional and for "conveniency" only. If you omit this call, you will have all the generated moc files in the Visual Studio project root.
macro(UiFolder)
    file(GLOB GENERATED_UI_H ui_*.h)
    source_group("Generated UI" FILES ${GENERATED_UI_H})
endmacro()

# Enables the use of Precompiled Headers in the project this macro is invoked in. Also adds the DEBUG_CPP_NAME to each .cpp file that specifies the name of that compilation unit. MSVC only.
macro(SetupCompileFlagsWithPCH)
    if (MSVC)
        # Label StableHeaders.cpp to create the PCH file and mark all other .cpp files to use that PCH file.
        # Add a #define DEBUG_CPP_NAME "this compilation unit name" to each compilation unit to aid in memory leak checking.
        foreach(src_file ${CPP_FILES})
            if (${src_file} MATCHES "StableHeaders.cpp$")
                set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "/YcStableHeaders.h")        
            else()
                get_filename_component(basename ${src_file} NAME)
                set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "/YuStableHeaders.h -DDEBUG_CPP_NAME=\"\\\"${basename}\"\\\"")
            endif()
        endforeach()
    endif()
endmacro()

# Sets up the compilation flags without PCH. For now just set the DEBUG_CPP_NAME to each compilation unit.
# TODO: The SetupCompileFlags and SetupCompileFlagsWithPCH macros should be merged, and the option to use PCH be passed in as a param. However,
# CMake string ops in PROPERTIES COMPILE_FLAGS gave some problems with this, so these are separate for now.
macro(SetupCompileFlags)
    if (MSVC)
        # Add a #define DEBUG_CPP_NAME "this compilation unit name" to each compilation unit to aid in memory leak checking.
        foreach(src_file ${CPP_FILES})
            if (${src_file} MATCHES "StableHeaders.cpp$")
            else()
                get_filename_component(basename ${src_file} NAME)
                set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "-DDEBUG_CPP_NAME=\"\\\"${basename}\"\\\"")
            endif()
        endforeach()
    endif()
endmacro()

# Set CMake library search policy
if (COMMAND cmake_policy)
    cmake_policy(SET CMP0003 NEW)
    cmake_policy(SET CMP0005 NEW)
endif()

# Detect what compiler we are using on Windows
# TODO Remove these as redundant.
set(VC90 FALSE)
set(VC100 FALSE)
if (MSVC)
    if (MSVC90)
        set(VC90 TRUE)
    elseif(MSVC10)
        set(VC100 TRUE)
    else()
        message(STATUS "-- Warning: Unsupported Visual Studio version detected. Currently Visual Studio 2008 and 2010 are supported".)
    endif()
endif()

# Set compiler warning levels.
# On MSVC, use warning level 4 but disable the following warnings:
# C4127 conditional expression is constant<commit_msg>Make llvm.clang.1_0 default compiler in case of Snow Leopard (although still Xcode will use llvm.g++42)<commit_after># Set project name
project(tundra)

# CMake version requirement, >= 2.5.5 to ensure that ProtoBuf is found ok.
cmake_minimum_required(VERSION 2.5.5)

# TUNDRA_NO_BOOST defines whether we want to replace usage of Boost with the C++ (TR1) standard equivalents.
# Setting TUNDRA_NO_BOOST to TRUE, i.e. disabling usage of Boost in the Tundra codebase, requires compiler
# with up-to-date C++ TR1 and preferably the C99 standard cstdint header. Also if the used compiler has C++11 
# make_shared function available, it is used.
# If TUNDRA_NO_BOOST is set to TRUE, kNet must also be built without Boost dependecy. In order to make the
# Tundra build fully free of Boost, you must also build Ogre and AssImp, which depend on Boost by default,
# with Boost disabled. See the dependencies scripts for instructions how to control this.
option(TUNDRA_NO_BOOST "Specifies whether Tundra is build without Boost." TRUE)

macro(PrintUsedEnvVariables)
    # Print out the resolved variables. Note that this does not print the env variables
    # in most cases as they should be resolved to our cmake variables and get cached.
    # This way this printed list wont lie if ran without env variables and we are still
    # succesfully finding all the deps from our cacher (or in bad cases assumed) dirs.
    message("\n=========== Used Environment Variables ===========\n")
    message(STATUS "TUNDRA_DEP_PATH  = " ${ENV_TUNDRA_DEP_PATH})
    message(STATUS "QTDIR            = " ${ENV_QT_DIR})
    if (NOT TUNDRA_NO_BOOST)
        message (STATUS "BOOST_ROOT       = " ${BOOST_ROOT})
    endif()
    message(STATUS "OGRE_HOME        = " ${OGRE_DIR}) # OGRE_DIR is our internal OGRE_HOME
    message(STATUS "SKYX_HOME        = " ${SKYX_HOME})
    message(STATUS "HYDRAX_HOME      = " ${HYDRAX_HOME})
    message(STATUS "KNET_DIR         = " ${KNET_DIR})
    message(STATUS "BULLET_DIR       = " ${BULLET_DIR})
endmacro()

macro (PrintUsedBuildConfig)
    message ("\n=========== Used Build Configuration =============\n")
    message (STATUS "TUNDRA_NO_BOOST            = " ${TUNDRA_NO_BOOST})
    message (STATUS "TUNDRACORE_SHARED          = " ${TUNDRACORE_SHARED})
    message (STATUS "BUILD_SDK_ONLY             = " ${BUILD_SDK_ONLY})
    message (STATUS "BUILDING_INSTALLER         = " ${BUILDING_INSTALLER})
    message (STATUS "ENABLE_BUILD_OPTIMIZATIONS = " ${ENABLE_BUILD_OPTIMIZATIONS})
    message (STATUS "ENABLE_HYDRAX              = " ${ENABLE_HYDRAX})
    message (STATUS "ENABLE_SKYX                = " ${ENABLE_SKYX})
    message (STATUS "ENABLE_OPEN_ASSET_IMPORT   = " ${ENABLE_OPEN_ASSET_IMPORT})
    message (STATUS "ENABLE_PROFILING           = " ${ENABLE_PROFILING})
    message (STATUS "ENABLE_JS_PROFILING        = " ${ENABLE_JS_PROFILING})
    message (STATUS "ENABLE_MEMORY_LEAK_CHECKS  = " ${ENABLE_MEMORY_LEAK_CHECKS})
    message ("")
    message (STATUS "Install prefix = " ${CMAKE_INSTALL_PREFIX})
    message ("")
endmacro ()

macro(GetLastElementFromPath dirPath outputParam)
    string (FIND ${dirPath} "/" lastPathSepIndex REVERSE)
    # This path does not have any subdirs in it
    if (${lastPathSepIndex} STREQUAL "-1")
        set (${outputParam} ${dirPath})
    # Path has subdirs, pick the last
    else ()
        math(EXPR lastPathSepIndex "${lastPathSepIndex} + 1")
        string(SUBSTRING ${dirPath} ${lastPathSepIndex} -1 ${outputParam})
    endif ()
endmacro ()

# The AddEntityComponent macro adds the static EC lib from the given sourceFolder directory to the build.
# The componentName == A subfolder in src/EntityComponents/ or a relative path to the EC directory where the CMakeLists.txt is located.
# Use this macro when adding ECs to the build, since this macro tracks the set of ECs that are added, so that the individual
# modules get #defines in C++ code for each EC that is present. This allows conditionally excluding ECs from the build.
# Note that for eg. AddEntityComponent(3rdparty/myecs/EC_Thingie) the define will be EC_Thingie_ENABLED and you would expect.
# Examples:     AddEntityComponent(EC_Sound)
#               AddEntityComponent(3rdparty/myecs/EC_Thingie)
macro(AddEntityComponent componentName)
    # Chekc if the component is in our default entity components location
    # note: from cmake docs: IS_DIRECTORY Behavior is well-defined only for full paths.
    if (IS_DIRECTORY ${PROJECT_BINARY_DIR}/src/EntityComponents/${componentName})
        add_subdirectory (src/EntityComponents/${componentName})
        set (${componentName}_ENABLED 1)
        set (USED_ENTITYCOMPONENTS ${USED_ENTITYCOMPONENTS} ${componentName})
    elseif (IS_DIRECTORY ${PROJECT_BINARY_DIR}/${componentName})
        add_subdirectory (${componentName})
        GetLastElementFromPath(${componentName} compNameFromRelPath)
        set(${compNameFromRelPath}_ENABLED 1)
        set(USED_ENTITYCOMPONENTS ${USED_ENTITYCOMPONENTS} ${compNameFromRelPath})
    else ()
        message(FATAL_ERROR "Could not resolve AddEntityComponent() call with path " ${componentName} ". Are you sure the component is there?")
    endif ()
endmacro()

# AddProject takes in one or two parameters: 
# - One param  : argv0 == the relative directory (to the root CMakeLists.txt) where you project is and that contains the CMakeLists.txt for this project.
# - Two params : argv0 == 'Core'|'Application'. argv1 folder name of the project in the src/argv0/
# More useful for building the Tundra project when including platform provided projects.
# Note: One param projects or two param "Application" type plugins will always be omitted if BUILD_SDK_ONLY is true!
# Note: Due to the cmake add_subdirectory restrictions, the directory cannot be outside the Tundra source tree, hopefully we can go around this one day.
# Examples:     AddProject(Core Input)
#               AddProject(Application JavascriptModule)
#               AddProject(mysubdir/MyPlugin)
function(AddProject)
    if (NOT ARGV1)
        if (BUILD_SDK_ONLY)
            message (STATUS "** Omitting Application level project " ${ARGV0} " because BUILD_SDK_ONLY is set to TRUE")
        else ()
            add_subdirectory(${ARGV0})
        endif ()
    else ()
        if (NOT ${ARGV0} STREQUAL "Core" AND NOT ${ARGV0} STREQUAL "Application")
            message (FATAL_ERROR "You are trying to use AddProject macro with invalid project type parameter: " ${ARGV0} " with project name " ${ARGV1})
        endif()
        if (BUILD_SDK_ONLY AND ${ARGV0} STREQUAL "Application")
            message (STATUS "** Omitting Application level project " ${ARGV1} " because BUILD_SDK_ONLY is set to TRUE")
        else ()
            add_subdirectory(src/${ARGV0}/${ARGV1})
        endif ()
    endif ()
endfunction()

# Generates in the current project a #define for each EC that has been added to the build. Use this macro in your module CMakeLists.txt
# to receive information in C++ about which ECs have been added to the project. This allows supporting conditional compilation of the ECs in your module.
macro(GetEntityComponents)
   foreach(componentName ${USED_ENTITYCOMPONENTS})
      add_definitions(-D${componentName}_ENABLED)
   endforeach()
endmacro()

# Adds the given folder_name into the source files of the current project. Use this macro when your module contains .cpp and .h files in several subdirectories.
macro(AddSourceFolder folder_name)
    file(GLOB H_FILES_IN_FOLDER_${folder_name} ${folder_name}/*.h ${folder_name}/*.inl)
    file(GLOB CPP_FILES_IN_FOLDER_${folder_name} ${folder_name}/*.cpp)
    source_group("Header Files\\${folder_name}" FILES ${H_FILES_IN_FOLDER_${folder_name}})
    source_group("Source Files\\${folder_name}" FILES ${CPP_FILES_IN_FOLDER_${folder_name}})
    set(H_FILES ${H_FILES} ${H_FILES_IN_FOLDER_${folder_name}})
    set(CPP_FILES ${CPP_FILES} ${CPP_FILES_IN_FOLDER_${folder_name}})
endmacro()

# Moves all Qt moc-compiler generated files into their own folder in the Visual Studio project. Call this once after having added all source files in the build in your module,
# but before the call to 'set (SOURCE_FILES ...)' directive.
# This macro is optional and for "conveniency" only. If you omit this call, you will have all the generated moc files in the Visual Studio project root.
# TODO: Add support for more deep folder structures. Current
#       implementation only support folders directly under project folder
macro(MocFolder)
    file(GLOB MOCS_TO_SOURCE_GROUP *.cxx */*.cxx)
    source_group("CMake Moc" FILES ${MOCS_TO_SOURCE_GROUP})
endmacro()

# Moves all Qt ui copmiler-generated .h files into their own folder in the Visual Studio project. Call this once after having added all source files in the build in your module.
# This macro is optional and for "conveniency" only. If you omit this call, you will have all the generated moc files in the Visual Studio project root.
macro(UiFolder)
    file(GLOB GENERATED_UI_H ui_*.h)
    source_group("Generated UI" FILES ${GENERATED_UI_H})
endmacro()

# Enables the use of Precompiled Headers in the project this macro is invoked in. Also adds the DEBUG_CPP_NAME to each .cpp file that specifies the name of that compilation unit. MSVC only.
macro(SetupCompileFlagsWithPCH)
    if (MSVC)
        # Label StableHeaders.cpp to create the PCH file and mark all other .cpp files to use that PCH file.
        # Add a #define DEBUG_CPP_NAME "this compilation unit name" to each compilation unit to aid in memory leak checking.
        foreach(src_file ${CPP_FILES})
            if (${src_file} MATCHES "StableHeaders.cpp$")
                set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "/YcStableHeaders.h")        
            else()
                get_filename_component(basename ${src_file} NAME)
                set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "/YuStableHeaders.h -DDEBUG_CPP_NAME=\"\\\"${basename}\"\\\"")
            endif()
        endforeach()
    endif()
endmacro()

# Sets up the compilation flags without PCH. For now just set the DEBUG_CPP_NAME to each compilation unit.
# TODO: The SetupCompileFlags and SetupCompileFlagsWithPCH macros should be merged, and the option to use PCH be passed in as a param. However,
# CMake string ops in PROPERTIES COMPILE_FLAGS gave some problems with this, so these are separate for now.
macro(SetupCompileFlags)
    if (MSVC)
        # Add a #define DEBUG_CPP_NAME "this compilation unit name" to each compilation unit to aid in memory leak checking.
        foreach(src_file ${CPP_FILES})
            if (${src_file} MATCHES "StableHeaders.cpp$")
            else()
                get_filename_component(basename ${src_file} NAME)
                set_source_files_properties(${src_file} PROPERTIES COMPILE_FLAGS "-DDEBUG_CPP_NAME=\"\\\"${basename}\"\\\"")
            endif()
        endforeach()
    endif()
endmacro()

# Set CMake library search policy
if (COMMAND cmake_policy)
    cmake_policy(SET CMP0003 NEW)
    cmake_policy(SET CMP0005 NEW)
endif()

EXEC_PROGRAM(/usr/bin/sw_vers ARGS -productVersion OUTPUT_VARIABLE OSX_MINOR_VERSION_RAW)
STRING(REGEX REPLACE "10\\.([0-9]).*" "\\1" MACOSX_VERSION "${OSX_MINOR_VERSION_RAW}")
if(${MACOSX_VERSION} LESS 6)
    message(FATAL_ERROR "Unsupported version of OS X: ${OSX_MINOR_VERSION_RAW}")
    return()
elseif (${MACOSX_VERSION} LESS 7)
    set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0")
endif()

# Detect what compiler we are using on Windows
# TODO Remove these as redundant.
set(VC90 FALSE)
set(VC100 FALSE)
if (MSVC)
    if (MSVC90)
        set(VC90 TRUE)
    elseif(MSVC10)
        set(VC100 TRUE)
    else()
        message(STATUS "-- Warning: Unsupported Visual Studio version detected. Currently Visual Studio 2008 and 2010 are supported".)
    endif()
endif()

# Set compiler warning levels.
# On MSVC, use warning level 4 but disable the following warnings:
# C4127 conditional expression is constant
{'fraction_non_alphanumeric': 0.08847710330138445, 'fraction_numerical': 0.0064323748668796595, 'mean_word_length': 3.7637987012987013, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4066484', 'n_tokens_mistral': 7127, 'n_tokens_neox': 6809, 'n_words': 2464}