1file(TO_CMAKE_PATH "${HEXAGON_SDK_ROOT}"   HEXAGON_SDK_ROOT)
  2file(TO_CMAKE_PATH "${HEXAGON_TOOLS_ROOT}" HEXAGON_TOOLS_ROOT)
  3
  4if (NOT IS_DIRECTORY "${HEXAGON_SDK_ROOT}")
  5    message(FATAL_ERROR "Make sure HEXAGON_SDK_ROOT point to the correct Hexagon SDK installation.")
  6endif()
  7
  8if (NOT IS_DIRECTORY "${HEXAGON_TOOLS_ROOT}")
  9    message("Try to read HEXAGON_TOOLS_ROOT from hexagon_sdk.json")
 10    file(READ "${HEXAGON_SDK_ROOT}/hexagon_sdk.json" HEXAGON_SDK_CONFIG_PATH)
 11    string(JSON HEXAGON_TOOLS_PATH GET ${HEXAGON_SDK_CONFIG_PATH} "root" "tools" "info" 0 "path")
 12    message("Found HEXAGON_TOOLS_PATH: ${HEXAGON_TOOLS_PATH}")
 13    set(HEXAGON_TOOLS_ROOT "${HEXAGON_SDK_ROOT}/${HEXAGON_TOOLS_PATH}")
 14    file(TO_CMAKE_PATH "${HEXAGON_TOOLS_ROOT}" HEXAGON_TOOLS_ROOT)
 15    if (NOT IS_DIRECTORY "${HEXAGON_TOOLS_ROOT}")
 16        message(FATAL_ERROR "Make sure HEXAGON_TOOLS_ROOT point to the correct Hexagon SDK installation.")
 17    endif()
 18endif()
 19
 20message(STATUS "hexagon: using ${HEXAGON_SDK_ROOT} and ${HEXAGON_TOOLS_ROOT} for building libggml-htp skels")
 21
 22include(${HEXAGON_SDK_ROOT}/build/cmake/hexagon_fun.cmake)
 23include(ExternalProject)
 24
 25option(GGML_HEXAGON_HTP_DEBUG "ggml-hexagon: enable HTP debug output" OFF)
 26set(GGML_HEXAGON_HTP_CERT  "$ENV{HEXAGON_HTP_CERT}" CACHE PATH "ggml-hexagon: enable HTP library signing using certificate")
 27set(GGML_HEXAGON_FP32_QUANTIZE_GROUP_SIZE 128 CACHE STRING "ggml-hexagon: quantize group size (32, 64, or 128)")
 28
 29add_library(htp_iface OBJECT
 30    ${CMAKE_CURRENT_BINARY_DIR}/htp_iface_stub.c)
 31
 32set_target_properties(htp_iface PROPERTIES POSITION_INDEPENDENT_CODE ON)
 33target_include_directories(htp_iface PUBLIC
 34    ${HEXAGON_SDK_ROOT}/incs
 35    ${HEXAGON_SDK_ROOT}/incs/stddef
 36    ${HEXAGON_SDK_ROOT}/utils/examples
 37    ${CMAKE_CURRENT_SOURCE_DIR}/htp
 38    ${CMAKE_CURRENT_BINARY_DIR})
 39
 40build_idl(htp/htp_iface.idl htp_iface)
 41
 42if (CMAKE_SYSTEM_NAME MATCHES Android)
 43    target_link_options(htp_iface PUBLIC -llog -ldl)
 44elseif (CMAKE_SYSTEM_NAME MATCHES Windows)
 45    target_precompile_headers(htp_iface PUBLIC <sal.h>)
 46else()
 47    target_link_options(htp_iface PUBLIC -ldl)
 48endif()
 49
 50set(TARGET_NAME ggml-hexagon)
 51ggml_add_backend_library(${TARGET_NAME}
 52    ggml-hexagon.cpp
 53    htp-drv.cpp
 54    htp-drv.h
 55    libdl.h
 56    ../../include/ggml-hexagon.h)
 57
 58target_link_libraries(${TARGET_NAME} PRIVATE htp_iface)
 59target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/htp ${CMAKE_CURRENT_BINARY_DIR})
 60
 61# Build HTP skels
 62set(HTP_SKELS)
 63function(build_htp_skel V)
 64    ExternalProject_Add(htp-${V}
 65        SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/htp BUILD_ALWAYS ON
 66        BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/libggml-htp-${V}.so
 67        CMAKE_ARGS
 68            -DCMAKE_BUILD_TYPE=Release
 69            -DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/htp/cmake-toolchain.cmake
 70            -DCMAKE_INSTALL_LIBDIR=${CMAKE_CURRENT_BINARY_DIR}
 71            -DHEXAGON_SDK_ROOT=${HEXAGON_SDK_ROOT}
 72            -DHEXAGON_TOOLS_ROOT=${HEXAGON_TOOLS_ROOT}
 73            -DHEXAGON_HTP_DEBUG=${GGML_HEXAGON_HTP_DEBUG}
 74            -DGGML_HEXAGON_FP32_QUANTIZE_GROUP_SIZE=${GGML_HEXAGON_FP32_QUANTIZE_GROUP_SIZE}
 75            -DDSP_VERSION=${V}
 76            -DPREBUILT_LIB_DIR="toolv19_${V}")
 77    list(APPEND HTP_SKELS ${CMAKE_CURRENT_BINARY_DIR}/libggml-htp-${V}.so)
 78    set(HTP_SKELS ${HTP_SKELS} PARENT_SCOPE)
 79endfunction()
 80
 81build_htp_skel(v68)
 82build_htp_skel(v69)
 83build_htp_skel(v73)
 84build_htp_skel(v75)
 85build_htp_skel(v79)
 86build_htp_skel(v81)
 87
 88# Install Hexagon skels required at runtime
 89install(FILES ${HTP_SKELS} TYPE LIB)
 90
 91if (CMAKE_SYSTEM_NAME MATCHES Windows AND GGML_HEXAGON_HTP_CERT)
 92    file(TO_CMAKE_PATH "$ENV{WINDOWS_SDK_BIN}/arm64"      WINSDK_BIN0_ARM64)
 93    file(TO_CMAKE_PATH "$ENV{WINDOWS_SDK_BIN}/x86"        WINSDK_BIN0_X86)
 94    file(TO_CMAKE_PATH "$ENV{WindowsSdkVerBinPath}/arm64" WINSDK_BIN1_ARM64)
 95    file(TO_CMAKE_PATH "$ENV{WindowsSdkVerBinPath}/x86"   WINSDK_BIN1_X86)
 96
 97    set(WINSDK_PATHS ${WINSDK_BIN0_ARM64} ${WINSDK_BIN0_X86} ${WINSDK_BIN1_ARM64} ${WINSDK_BIN1_X86})
 98
 99    find_program(INF2CAT  NAMES inf2cat.exe  PATHS ${WINSDK_PATHS} REQUIRED)
100    find_program(SIGNTOOL NAMES signtool.exe PATHS ${WINSDK_PATHS} REQUIRED)
101
102    message(STATUS "hexagon: using ${GGML_HEXAGON_HTP_CERT} to sign libggml-htp skels")
103
104    set(LIBGGML_HTP_CAT ${CMAKE_CURRENT_BINARY_DIR}/libggml-htp.cat)
105    add_custom_target(libggml-htp-cat
106        BYPRODUCTS ${LIBGGML_HTP_CAT}
107        DEPENDS libggml-htp.inf ${HTP_SKELS}
108        COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/libggml-htp.inf ${CMAKE_CURRENT_BINARY_DIR}
109        COMMAND ${INF2CAT} /driver:${CMAKE_CURRENT_BINARY_DIR} /os:10_25H2_ARM64
110        COMMAND ${SIGNTOOL} sign /fd sha256 /f ${GGML_HEXAGON_HTP_CERT} ${LIBGGML_HTP_CAT}
111        COMMENT "generating and signing libggml-htp.cat file"
112        VERBATIM
113    )
114
115    add_dependencies(${TARGET_NAME} libggml-htp-cat)
116    install(FILES ${LIBGGML_HTP_CAT} TYPE LIB)
117endif()