1macro(_platform_feature_set FEATURE_NAME FEATURE_SOURCE)
2    if (ENABLE_${FEATURE_NAME}_FEATURE)
3        if (EXISTS ${FEATURE_SOURCE})
4            set(HT_PLATFORM_FEATURE_${FEATURE_NAME}_SOURCE ${FEATURE_SOURCE})
5            set(HT_PLATFORM_FEATURE_${FEATURE_NAME}_ENABLED ON)
6            message(STATUS "Feature ${FEATURE_NAME} enabled. Used file: ${FEATURE_SOURCE}")
7        else()
8            message(WARNING "Feature ${FEATURE_NAME} will be disabled! File ${FEATURE_SOURCE} could not be found!")
9        endif()
10    endif()
11endmacro(_platform_feature_set)
12
13macro(_validate_feature_enabled FEATURE_NAME VARIABLE)
14    if (NOT "${FEATURE_${FEATURE_NAME}_${VARIABLE}}" STREQUAL "" AND NOT ENABLE_${FEATURE_NAME}_FEATURE)
15        message(WARNING "Value FEATURE_${FEATURE_NAME}_${VARIABLE} defined but option ENABLE_${FEATURE_NAME}_FEATURE is not enabled. "
16            "Enable ENABLE_${FEATURE_NAME}_FEATURE option to enable ${FEATURE_NAME} feature.")
17    endif()
18endmacro(_validate_feature_enabled)
19
20macro(define_platform_feature FEATURE_NAME FEATURE_DEFAULT_FILE DEFAULT_ENABLE)
21    if (NOT "${DEFAULT_ENABLE}" STREQUAL "OFF" OR "${ENABLE_${FEATURE_NAME}_FEATURE}" STREQUAL "ON")
22        set(OPTION_VALUE ON)
23    else()
24        set(OPTION_VALUE OFF)
25    endif()
26
27    set(ENABLE_${FEATURE_NAME}_FEATURE ${OPTION_VALUE} CACHE BOOL "${FEATURE_NAME} feature." FORCE)
28
29    _validate_feature_enabled(${FEATURE_NAME} PLATFORM)
30    _validate_feature_enabled(${FEATURE_NAME} SOURCE)
31
32    set(FEATURE_${FEATURE_NAME}_PLATFORM "" CACHE STRING "Platform for ${FEATURE_NAME} feature.
33        Should not be used with FEATURE_${FEATURE_NAME}_SOURCE")
34    set(FEATURE_${FEATURE_NAME}_SOURCE "" CACHE STRING "Absolute source file path for ${FEATURE_NAME} feature.
35        Should not be used with FEATURE_${FEATURE_NAME}_PLATFORM")
36
37    set(FEATURE_PLATFORM "${FEATURE_${FEATURE_NAME}_PLATFORM}")
38    set(FEATURE_SOURCE "${FEATURE_${FEATURE_NAME}_SOURCE}")
39    if (NOT "${FEATURE_SOURCE}" STREQUAL "")
40        _platform_feature_set(${FEATURE_NAME} ${FEATURE_SOURCE})
41    endif()
42
43    string(TOLOWER "${CMAKE_SYSTEM_NAME}" SYSTEM_NAME)
44    if ("${FEATURE_PLATFORM}" STREQUAL "" AND EXISTS "${CMAKE_SOURCE_DIR}/lib/platform/${SYSTEM_NAME}/${FEATURE_DEFAULT_FILE}")
45        set(FEATURE_PLATFORM ${SYSTEM_NAME})
46    endif()
47
48    if (NOT HT_PLATFORM_FEATURE_${FEATURE_NAME}_ENABLED AND NOT ${FEATURE_PLATFORM} STREQUAL "" AND "${FEATURE_SOURCE}" STREQUAL "")
49        set(FEATURE_SOURCE "${CMAKE_SOURCE_DIR}/lib/platform/${FEATURE_PLATFORM}/${FEATURE_DEFAULT_FILE}")
50        _platform_feature_set(${FEATURE_NAME} ${FEATURE_SOURCE})
51    endif()
52
53    if ("${DEFAULT_ENABLE}" STREQUAL "DEFAULT")
54        if (NOT HT_PLATFORM_FEATURE_${FEATURE_NAME}_ENABLED)
55            set(OPTION_VALUE OFF)
56        else()
57            set(OPTION_VALUE ON)
58        endif()
59        set(ENABLE_${FEATURE_NAME}_FEATURE ${OPTION_VALUE} CACHE BOOL "${FEATURE_NAME} feature." FORCE)
60    endif()
61
62    if (ENABLE_${FEATURE_NAME}_FEATURE AND NOT HT_PLATFORM_FEATURE_${FEATURE_NAME}_ENABLED)
63        message(FATAL_ERROR "Feature ${FEATURE_NAME} enabled, but no implementation found. Specify either "
64           "FEATURE_${FEATURE_NAME}_PLATFORM or FEATURE_${FEATURE_NAME}_SOURCE option, or clear both options to use default implementation (if exists).")
65    endif()
66endmacro(define_platform_feature)
67