# Copyright (c) Facebook, Inc. and its affiliates.
# All rights reserved.
#
# Copyright 2019 Google LLC
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

CMAKE_MINIMUM_REQUIRED(VERSION 3.15 FATAL_ERROR)

# Allow specifying -D<PackageName>_ROOT.
CMAKE_POLICY(SET CMP0074 NEW)

# MSVC runtime library flags are selected by an abstraction.
CMAKE_POLICY(SET CMP0091 NEW)

# Avoid "ignoring duplicate libraries" warning on macOS (where possible).
IF(POLICY CMP0156)
  CMAKE_POLICY(SET CMP0156 NEW)
ENDIF()

# ---[ Project and semantic versioning.
PROJECT(XNNPACK C CXX ASM)

# --[ Use ccache if available
FIND_PROGRAM(CCACHE_BINARY "ccache")
IF(CCACHE_BINARY)
  MESSAGE(STATUS "Using ccache: ${CCACHE_BINARY}")
  SET(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_BINARY}" CACHE STRING "CXX compiler launcher" FORCE)
  SET(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_BINARY}" CACHE STRING "C compiler launcher" FORCE)
  IF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
    STRING(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
    STRING(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
    STRING(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
    STRING(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
    STRING(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_DEBUG_INIT "${CMAKE_C_FLAGS_DEBU_INITG}")
    STRING(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG_INIT "${CMAKE_CXX_FLAGS_DEBUG_INIT}")
    STRING(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${CMAKE_C_FLAGS_RELWITHDEBINFO_INIT}")
    STRING(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT}")
  ENDIF()
ENDIF()

SET(CMAKE_C_STANDARD 99)
SET(CMAKE_C_EXTENSIONS NO)
SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_STANDARD_REQUIRED YES)
SET(CMAKE_CXX_EXTENSIONS NO)

# ---[ Options.
SET(XNNPACK_LIBRARY_TYPE "default" CACHE STRING "Type of library (shared, static, or default) to build")
SET_PROPERTY(CACHE XNNPACK_LIBRARY_TYPE PROPERTY STRINGS default static shared)
IF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
  # Disable assembly when using MSVC until support is added.
  OPTION(XNNPACK_ENABLE_ASSEMBLY "Build XNNPACK with assembly micro-kernels" OFF)
  OPTION(XNNPACK_ENABLE_RNDNU16 "Build XNNPACK with RNDNU16 micro-kernels" OFF)
ELSE()
  OPTION(XNNPACK_ENABLE_ASSEMBLY "Build XNNPACK with assembly micro-kernels" ON)
  OPTION(XNNPACK_ENABLE_RNDNU16 "Build XNNPACK with RNDNU16 micro-kernels" ON)
ENDIF()
OPTION(XNNPACK_ENABLE_MEMOPT "Build XNNPACK with optimized memory allocation scheme" ON)
OPTION(XNNPACK_ENABLE_SPARSE "Build XNNPACK with graph rewriting for sparse inference" ON)
OPTION(XNNPACK_BUILD_LIBRARY "Build XNNPACK library" ON)
OPTION(XNNPACK_BUILD_TESTS "Build XNNPACK unit tests" ON)
OPTION(XNNPACK_BUILD_ALL_MICROKERNELS "Builds all XNNPACK Microkernels" ON)
OPTION(XNNPACK_BUILD_BENCHMARKS "Build XNNPACK benchmarks" ON)
OPTION(XNNPACK_BUILD_WITH_LIBM "Build XNNPACK with libm, can turn off on Windows to avoid mutiple math functions issue." ON)
OPTION(XNNPACK_BUILD_YNNPACK "Build YNNPACK library" OFF)
OPTION(XNNPACK_USE_SYSTEM_LIBS "Use system-provided dependency libraries" OFF)
OPTION(USE_GNU_SOURCE "Use _GNU_SOURCE macro" OFF)
IF(XNNPACK_BUILD_BENCHMARKS OR XNNPACK_BUILD_TESTS)
  SET(XNNPACK_BUILD_ALL_MICROKERNELS ON)
ENDIF()

# --- [ Determine target processor
IF(EMSCRIPTEN)
  MESSAGE(STATUS "Building XNNPACK for WebAssembly with Emscripten")
  SET(XNNPACK_TARGET_PROCESSOR "wasm")
ELSEIF(CMAKE_OSX_ARCHITECTURES)
  LIST(LENGTH CMAKE_OSX_ARCHITECTURES CMAKE_OSX_ARCHITECTURES_COUNT)
  IF(CMAKE_OSX_ARCHITECTURES_COUNT GREATER 1)
    MESSAGE(FATAL_ERROR "Unsupported XNNPACK build with multiple OSX architectures (${CMAKE_OSX_ARCHITECTURES}). "
      "Specify a single architecture in CMAKE_OSX_ARCHITECTURES and re-configure.")
  ENDIF()
  IF(NOT CMAKE_OSX_ARCHITECTURES MATCHES "^(x86_64|arm64|arm64e|arm64_32)$")
    MESSAGE(FATAL_ERROR "Unrecognized CMAKE_OSX_ARCHITECTURES value \"${CMAKE_OSX_ARCHITECTURES}\"")
  ENDIF()
  SET(XNNPACK_TARGET_PROCESSOR "${CMAKE_OSX_ARCHITECTURES}")
  ADD_COMPILE_OPTIONS("-Wno-shorten-64-to-32")
ELSEIF(CMAKE_GENERATOR MATCHES "^Visual Studio " AND CMAKE_GENERATOR_PLATFORM)
  IF(CMAKE_GENERATOR_PLATFORM STREQUAL "Win32")
    SET(XNNPACK_TARGET_PROCESSOR "x86")
  ELSEIF(CMAKE_GENERATOR_PLATFORM STREQUAL "x64")
    SET(XNNPACK_TARGET_PROCESSOR "x86_64")
  ELSEIF(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
    SET(XNNPACK_TARGET_PROCESSOR "arm64")
  ELSEIF(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64EC")
    SET(XNNPACK_TARGET_PROCESSOR "arm64")
  ELSE()
    MESSAGE(FATAL_ERROR "Unsupported Visual Studio architecture \"${CMAKE_GENERATOR_PLATFORM}\"")
  ENDIF()
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^i[3-7]86$")
  SET(XNNPACK_TARGET_PROCESSOR "x86")
ELSEIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64")
  SET(XNNPACK_TARGET_PROCESSOR "x86_64")
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^armv[5-8]")
  SET(XNNPACK_TARGET_PROCESSOR "arm")
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|ARM64)$")
  SET(XNNPACK_TARGET_PROCESSOR "arm64")
ELSEIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
  SET(XNNPACK_TARGET_PROCESSOR "ppc64")
ELSEIF(NOT XNNPACK_TARGET_PROCESSOR MATCHES "^(x86(_64)?|arm64|riscv(32|64|128)|Hexagon|ppc64)$")
  SET(XNNPACK_TARGET_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}")
ELSE()
  MESSAGE(FATAL_ERROR "Unrecognized CMAKE_SYSTEM_PROCESSOR value \"${CMAKE_SYSTEM_PROCESSOR}\"")
ENDIF()
MESSAGE(STATUS "Building for XNNPACK_TARGET_PROCESSOR: ${XNNPACK_TARGET_PROCESSOR}")

# Match Bazel's //build_config:aarch64 defaults. This includes arm64e and
# arm64_32 Apple targets, but excludes Windows ARM64.
IF(XNNPACK_TARGET_PROCESSOR MATCHES "^arm64" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
  SET(XNNPACK_TARGET_PROCESSOR_AARCH64_DEFAULTS ON)
ELSE()
  SET(XNNPACK_TARGET_PROCESSOR_AARCH64_DEFAULTS OFF)
ENDIF()

# --- [ Processor-specific options
OPTION(XNNPACK_ENABLE_ARM_FP16_SCALAR "Build XNNPACK with ARM FP16 (FP16 data processing) scalar micro-kernels" ON)
OPTION(XNNPACK_ENABLE_ARM_FP16_VECTOR "Build XNNPACK with ARM FP16 (FP16 data processing) vector micro-kernels" ON)
OPTION(XNNPACK_ENABLE_ARM_BF16 "Build XNNPACK with ARM BF16 (BFLOAT16) micro-kernels" ON)
OPTION(XNNPACK_ENABLE_ARM_DOTPROD "Build XNNPACK with ARM DotProd (integer dot product) micro-kernels" ON)
OPTION(XNNPACK_ENABLE_ARM_I8MM "Build XNNPACK with ARM I8MM (8-bit integer matrix multiply accumulate) micro-kernels" ON)
OPTION(XNNPACK_ENABLE_ARM_SME "Build XNNPACK with ARM SME micro-kernels" ON)
OPTION(XNNPACK_ENABLE_ARM_SME2 "Build XNNPACK with ARM SME2 micro-kernels" ON)

IF(NOT XNNPACK_TARGET_PROCESSOR MATCHES "arm(64)?")
  SET(XNNPACK_ENABLE_ARM_FP16_SCALAR OFF)
  SET(XNNPACK_ENABLE_ARM_FP16_VECTOR OFF)
  SET(XNNPACK_ENABLE_ARM_BF16 OFF)
  SET(XNNPACK_ENABLE_ARM_DOTPROD OFF)
ENDIF()
IF(NOT XNNPACK_TARGET_PROCESSOR_AARCH64_DEFAULTS)
  SET(XNNPACK_ENABLE_ARM_I8MM OFF)
  SET(XNNPACK_ENABLE_ARM_SME OFF)
  SET(XNNPACK_ENABLE_ARM_SME2 OFF)
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "11")
  SET(XNNPACK_ENABLE_ARM_I8MM OFF)
  SET(XNNPACK_ENABLE_ARM_SME OFF)
  SET(XNNPACK_ENABLE_ARM_SME2 OFF)
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "18")
  SET(XNNPACK_ENABLE_ARM_SME OFF)
  SET(XNNPACK_ENABLE_ARM_SME2 OFF)
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "10")
  SET(XNNPACK_ENABLE_ARM_SME OFF)
  SET(XNNPACK_ENABLE_ARM_SME2 OFF)
ENDIF()
OPTION(XNNPACK_ENABLE_RISCV_VECTOR "Build XNNPACK with RISC-V Vector micro-kernels" ON)
OPTION(XNNPACK_ENABLE_VSX "Build XNNPACK with VSX Vector micro-kernels for Power" ON)
OPTION(XNNPACK_ENABLE_SSE "Build XNNPACK with SSE micro-kernels" ON)
OPTION(XNNPACK_ENABLE_SSE2 "Build XNNPACK with SSE2 micro-kernels" ON)
OPTION(XNNPACK_ENABLE_SSSE3 "Build XNNPACK with SSSE3 micro-kernels" ON)
OPTION(XNNPACK_ENABLE_SSE41 "Build XNNPACK with SSE41 micro-kernels" ON)
OPTION(XNNPACK_ENABLE_AVX "Build XNNPACK with AVX micro-kernels" ON)
OPTION(XNNPACK_ENABLE_F16C "Build XNNPACK with F16C micro-kernels" ON)
OPTION(XNNPACK_ENABLE_FMA3 "Build XNNPACK with FMA3 micro-kernels" ON)
OPTION(XNNPACK_ENABLE_AVX2 "Build XNNPACK with AVX2 micro-kernels" ON)
OPTION(XNNPACK_ENABLE_AVXVNNI "Build XNNPACK with AVX-VNNI micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "11")
    SET(XNNPACK_ENABLE_AVXVNNI OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "15")
    SET(XNNPACK_ENABLE_AVXVNNI OFF)
  ENDIF()
ENDIF()
OPTION(XNNPACK_ENABLE_AVXVNNIINT8 "Build XNNPACK with AVX-VNNI-INT8 micro-kernels" ON)
IF(CMAKE_SYSTEM_NAME MATCHES "^(Android|Darwin|iOS)$")
  SET(XNNPACK_ENABLE_AVXVNNIINT8 OFF)
ENDIF()
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "17")
    SET(XNNPACK_ENABLE_AVXVNNIINT8 OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "17")
    SET(XNNPACK_ENABLE_AVXVNNIINT8 OFF)
  ENDIF()
# Disable AVXVNNIINT8 when using MSVC until support is added.
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
  SET(XNNPACK_ENABLE_AVXVNNIINT8 OFF)
ENDIF()
OPTION(XNNPACK_ENABLE_AVX256SKX "Build XNNPACK with AVX256SKX micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "11")
    SET(XNNPACK_ENABLE_AVX256SKX OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "15")
    SET(XNNPACK_ENABLE_AVX256SKX OFF)
  ENDIF()
ENDIF()
OPTION(XNNPACK_ENABLE_AVX256VNNI "Build XNNPACK with AVX256VNNI micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "11")
    SET(XNNPACK_ENABLE_AVX256VNNI OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "15")
    SET(XNNPACK_ENABLE_AVX256VNNI OFF)
  ENDIF()
ENDIF()
OPTION(XNNPACK_ENABLE_AVX256VNNIGFNI "Build XNNPACK with AVX256VNNIGFNI micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "11")
    SET(XNNPACK_ENABLE_AVX256VNNIGFNI OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "15")
    SET(XNNPACK_ENABLE_AVX256VNNIGFNI OFF)
  ENDIF()
ENDIF()
OPTION(XNNPACK_ENABLE_AVX512F "Build XNNPACK with AVX512F micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "8")
    SET(XNNPACK_ENABLE_AVX512F OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "6")
    SET(XNNPACK_ENABLE_AVX512F OFF)
  ENDIF()
ENDIF()
OPTION(XNNPACK_ENABLE_AVX512SKX "Build XNNPACK with AVX512SKX micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "8")
    SET(XNNPACK_ENABLE_AVX512SKX OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "6")
    SET(XNNPACK_ENABLE_AVX512SKX OFF)
  ENDIF()
ENDIF()
OPTION(XNNPACK_ENABLE_AVX512VBMI "Build XNNPACK with AVX512VBMI micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "8")
    SET(XNNPACK_ENABLE_AVX512VBMI OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "6")
    SET(XNNPACK_ENABLE_AVX512VBMI OFF)
  ENDIF()
ENDIF()
OPTION(XNNPACK_ENABLE_AVX512VNNI "Build XNNPACK with AVX512VNNI micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "8")
    SET(XNNPACK_ENABLE_AVX512VNNI OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "6")
    SET(XNNPACK_ENABLE_AVX512VNNI OFF)
  ENDIF()
ENDIF()
OPTION(XNNPACK_ENABLE_AVX512VNNIGFNI "Build XNNPACK with AVX512VNNIGFNI micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "8")
    SET(XNNPACK_ENABLE_AVX512VNNIGFNI OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "6")
    SET(XNNPACK_ENABLE_AVX512VNNIGFNI OFF)
  ENDIF()
ENDIF()
OPTION(XNNPACK_ENABLE_AVX512AMX "Build XNNPACK with AVX512-AMX micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  SET(XNNPACK_ENABLE_AVX512AMX OFF)
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "15")
    SET(XNNPACK_ENABLE_AVX512AMX OFF)
  ENDIF()
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR STREQUAL "x86")
  SET(XNNPACK_ENABLE_AVX512AMX OFF)
ENDIF()
OPTION(XNNPACK_ENABLE_AVX512FP16 "Build XNNPACK with AVX512-FP16 micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "13")
    SET(XNNPACK_ENABLE_AVX512FP16 OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "15")
    SET(XNNPACK_ENABLE_AVX512FP16 OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
  SET(XNNPACK_ENABLE_AVX512FP16 OFF)
ENDIF()
OPTION(XNNPACK_ENABLE_AVX512BF16 "Build XNNPACK with AVX512-BF16 micro-kernels" ON)
OPTION(XNNPACK_ENABLE_WASMRELAXEDSIMDFP16 "Build XNNPACK with WebAssembly Relaxed SIMD FP16 micro-kernels" ON)
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "13")
    SET(XNNPACK_ENABLE_AVX512BF16 OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "15")
    SET(XNNPACK_ENABLE_AVX512BF16 OFF)
  ENDIF()
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
  SET(XNNPACK_ENABLE_AVX512BF16 OFF)
  IF(MSVC_VERSION LESS_EQUAL 1941)
    # /vlen option not supported
    SET(XNNPACK_ENABLE_AVX256SKX OFF)
    SET(XNNPACK_ENABLE_AVX256VNNI OFF)
    SET(XNNPACK_ENABLE_AVX256VNNIGFNI OFF)
  ENDIF()
ENDIF()
OPTION(XNNPACK_ENABLE_HVX "Build XNNPACK with Hexagon HVX micro-kernels" ON)
OPTION(XNNPACK_ENABLE_KLEIDIAI "Use KleidiAI GEMM microkernels for Arm" ON)
IF(XNNPACK_TARGET_PROCESSOR_AARCH64_DEFAULTS AND XNNPACK_ENABLE_ARM_I8MM)
  IF (XNNPACK_ENABLE_KLEIDIAI)
    MESSAGE(STATUS "Enabling KleidiAI for Arm64")
  ENDIF()
ELSE()
  SET(XNNPACK_ENABLE_KLEIDIAI OFF)
ENDIF()
OPTION(XNNPACK_ENABLE_WASM_REVECTORIZE "Build XNNPACK with WASM SIMD AVX-256 revectorization micro-kernels" ON)
IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
  SET(XNNPACK_ENABLE_WASM_REVECTORIZE OFF)
ENDIF()

# ---[ CMake options
INCLUDE(GNUInstallDirs)

IF(XNNPACK_BUILD_TESTS)
  ENABLE_TESTING()
ENDIF()

ADD_COMPILE_DEFINITIONS("XNN_ENABLE_ARM_FP16_VECTOR=$<BOOL:${XNNPACK_ENABLE_ARM_FP16_VECTOR}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_ARM_FP16_SCALAR=$<BOOL:${XNNPACK_ENABLE_ARM_FP16_SCALAR}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_ARM_BF16=$<BOOL:${XNNPACK_ENABLE_ARM_BF16}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_ARM_DOTPROD=$<BOOL:${XNNPACK_ENABLE_ARM_DOTPROD}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_ARM_I8MM=$<BOOL:${XNNPACK_ENABLE_ARM_I8MM}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_ARM_SME=$<BOOL:${XNNPACK_ENABLE_ARM_SME}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_ARM_SME2=$<BOOL:${XNNPACK_ENABLE_ARM_SME2}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_RISCV_VECTOR=$<BOOL:${XNNPACK_ENABLE_RISCV_VECTOR}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_RISCV_FP16_VECTOR=$<BOOL:${XNNPACK_ENABLE_RISCV_FP16_VECTOR}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_SSE=$<BOOL:${XNNPACK_ENABLE_SSE}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_SSE2=$<BOOL:${XNNPACK_ENABLE_SSE2}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_SSSE3=$<BOOL:${XNNPACK_ENABLE_SSSE3}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_SSE41=$<BOOL:${XNNPACK_ENABLE_SSE41}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX=$<BOOL:${XNNPACK_ENABLE_AVX}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_F16C=$<BOOL:${XNNPACK_ENABLE_F16C}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_FMA3=$<BOOL:${XNNPACK_ENABLE_FMA3}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX2=$<BOOL:${XNNPACK_ENABLE_AVX2}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVXVNNI=$<BOOL:${XNNPACK_ENABLE_AVXVNNI}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVXVNNIINT8=$<BOOL:${XNNPACK_ENABLE_AVXVNNIINT8}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX256SKX=$<BOOL:${XNNPACK_ENABLE_AVX256SKX}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX256VNNI=$<BOOL:${XNNPACK_ENABLE_AVX256VNNI}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX256VNNIGFNI=$<BOOL:${XNNPACK_ENABLE_AVX256VNNIGFNI}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX512F=$<BOOL:${XNNPACK_ENABLE_AVX512F}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX512SKX=$<BOOL:${XNNPACK_ENABLE_AVX512SKX}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX512VBMI=$<BOOL:${XNNPACK_ENABLE_AVX512VBMI}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX512VNNI=$<BOOL:${XNNPACK_ENABLE_AVX512VNNI}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX512VNNIGFNI=$<BOOL:${XNNPACK_ENABLE_AVX512VNNIGFNI}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX512AMX=$<BOOL:${XNNPACK_ENABLE_AVX512AMX}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX512FP16=$<BOOL:${XNNPACK_ENABLE_AVX512FP16}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_WASMRELAXEDSIMDFP16=$<BOOL:${XNNPACK_ENABLE_WASMRELAXEDSIMDFP16}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_AVX512BF16=$<BOOL:${XNNPACK_ENABLE_AVX512BF16}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_VSX=$<BOOL:${XNNPACK_ENABLE_VSX}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_ASSEMBLY=$<BOOL:${XNNPACK_ENABLE_ASSEMBLY}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_SPARSE=$<BOOL:${XNNPACK_ENABLE_SPARSE}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_RNDNU16=$<BOOL:${XNNPACK_ENABLE_RNDNU16}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_HVX=$<BOOL:${XNNPACK_ENABLE_HVX}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_KLEIDIAI=$<BOOL:${XNNPACK_ENABLE_KLEIDIAI}>")
ADD_COMPILE_DEFINITIONS("XNN_ENABLE_WASM_REVECTORIZE=$<BOOL:${XNNPACK_ENABLE_WASM_REVECTORIZE}>")

IF(XNNPACK_TARGET_PROCESSOR MATCHES "Hexagon")
  ADD_COMPILE_DEFINITIONS("XNN_ENABLE_CPUINFO=0")
ELSE()
  ADD_COMPILE_DEFINITIONS("XNN_ENABLE_CPUINFO=1")
ENDIF()

IF(USE_GNU_SOURCE)
  ADD_COMPILE_DEFINITIONS(_GNU_SOURCE)
ENDIF()

IF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
  # Disable "unary minus operator applied to unsigned type, result still unsigned" warning
  ADD_COMPILE_OPTIONS("/wd4146")
  # Test files have many sections, increase the limit. See
  # https://learn.microsoft.com/en-us/cpp/build/reference/bigobj-increase-number-of-sections-in-dot-obj-file.
  ADD_COMPILE_OPTIONS("/bigobj")
  # Our float16 datatypes have constructors in C++ and not in C, which prompts a warning in MSVC
  ADD_COMPILE_OPTIONS("/wd4190")
ENDIF()

IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  # Disable "note: parameter passing for argument of type ... changed/will change in ..."
  ADD_COMPILE_OPTIONS("-Wno-psabi")

  # Don't generate fma automatically.
  ADD_COMPILE_OPTIONS("-ffp-contract=off")
ENDIF()

# ---[ Build flags
IF(NOT CMAKE_SYSTEM_NAME)
  MESSAGE(FATAL_ERROR "CMAKE_SYSTEM_NAME not defined")
ELSEIF(NOT CMAKE_SYSTEM_NAME MATCHES "^(Android|Darwin|iOS|Linux|Windows|CYGWIN|MSYS|QURT|Emscripten|Generic)$")
  MESSAGE(FATAL_ERROR "Unrecognized CMAKE_SYSTEM_NAME value \"${CMAKE_SYSTEM_NAME}\"")
ENDIF()
IF(CMAKE_SYSTEM_NAME MATCHES "Windows")
  # Disable min/max macros as they break std::min/max and std::numeric_limits<T>min/max.
  ADD_COMPILE_DEFINITIONS("NOMINMAX")
ENDIF()

IF(EMSCRIPTEN)
  ADD_COMPILE_OPTIONS("-msimd128")
  ADD_COMPILE_OPTIONS("-mfp16")
  ADD_COMPILE_OPTIONS("-mrelaxed-simd")
ENDIF()

IF(CMAKE_SYSTEM_NAME MATCHES "^(Android)$")
  IF(XNNPACK_TARGET_PROCESSOR MATCHES "^arm64")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,force-bti")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,force-bti")
  ENDIF()
ENDIF()

IF(CMAKE_SYSTEM_NAME MATCHES "^(Android|Linux)$")
  IF(XNNPACK_TARGET_PROCESSOR MATCHES "^arm64")
    IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
      set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mbranch-protection=bti")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mbranch-protection=bti")
      # GCC doesn't support this flag yet
      set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -mmark-bti-property")
    ELSE()
      MESSAGE(WARNING "Security: XNNPACK doesn't support BTI control flow integrity with GCC. Continuing.")
    ENDIF()
  ENDIF()
ENDIF()

# ---[ Download deps
IF(NOT XNNPACK_USE_SYSTEM_LIBS)
  IF(NOT DEFINED CPUINFO_SOURCE_DIR)
    MESSAGE(STATUS "Downloading cpuinfo to ${CMAKE_BINARY_DIR}/cpuinfo-source (define CPUINFO_SOURCE_DIR to avoid it)")
    CONFIGURE_FILE(cmake/DownloadCpuinfo.cmake "${CMAKE_BINARY_DIR}/cpuinfo-download/CMakeLists.txt")
    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/cpuinfo-download")
    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/cpuinfo-download")
    SET(CPUINFO_SOURCE_DIR "${CMAKE_BINARY_DIR}/cpuinfo-source" CACHE STRING "cpuinfo source directory")

  ENDIF()

  IF(NOT DEFINED PTHREADPOOL_SOURCE_DIR)
    MESSAGE(STATUS "Downloading pthreadpool to ${CMAKE_BINARY_DIR}/pthreadpool-source (define PTHREADPOOL_SOURCE_DIR to avoid it)")
    CONFIGURE_FILE(cmake/DownloadPThreadPool.cmake "${CMAKE_BINARY_DIR}/pthreadpool-download/CMakeLists.txt")
    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/pthreadpool-download")
    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/pthreadpool-download")
    SET(PTHREADPOOL_SOURCE_DIR "${CMAKE_BINARY_DIR}/pthreadpool-source" CACHE STRING "pthreadpool source directory")
  ENDIF()

  IF(XNNPACK_BUILD_TESTS AND NOT DEFINED GOOGLETEST_SOURCE_DIR)
    MESSAGE(STATUS "Downloading Google Test to ${CMAKE_BINARY_DIR}/googletest-source (define GOOGLETEST_SOURCE_DIR to avoid it)")
    CONFIGURE_FILE(cmake/DownloadGoogleTest.cmake "${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt")
    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googletest-download")
    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googletest-download")
    SET(GOOGLETEST_SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-source" CACHE STRING "Google Test source directory")
  ENDIF()

  IF(XNNPACK_BUILD_BENCHMARKS AND NOT DEFINED GOOGLEBENCHMARK_SOURCE_DIR)
    MESSAGE(STATUS "Downloading Google Benchmark to ${CMAKE_BINARY_DIR}/googlebenchmark-source (define GOOGLEBENCHMARK_SOURCE_DIR to avoid it)")
    CONFIGURE_FILE(cmake/DownloadGoogleBenchmark.cmake "${CMAKE_BINARY_DIR}/googlebenchmark-download/CMakeLists.txt")
    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googlebenchmark-download")
    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googlebenchmark-download")
    SET(GOOGLEBENCHMARK_SOURCE_DIR "${CMAKE_BINARY_DIR}/googlebenchmark-source" CACHE STRING "Google Benchmark source directory")
  ENDIF()

  IF(XNNPACK_ENABLE_KLEIDIAI AND NOT DEFINED KLEIDIAI_SOURCE_DIR)
    MESSAGE(STATUS "Downloading KleidiAI to ${CMAKE_BINARY_DIR}/kleidiai-source (define KLEIDIAI_SOURCE_DIR to avoid it)")
    CONFIGURE_FILE(cmake/DownloadKleidiAI.cmake "${CMAKE_BINARY_DIR}/kleidiai-download/CMakeLists.txt")
    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/kleidiai-download")
    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/kleidiai-download")
    SET(KLEIDIAI_SOURCE_DIR "${CMAKE_BINARY_DIR}/kleidiai-source" CACHE STRING "kleidiai source directory")
  ENDIF()
ENDIF()

# ---[ XNNPACK library

IF (NOT DEFINED Python_EXECUTABLE)
  find_package(Python COMPONENTS Interpreter)

  IF(NOT Python_FOUND)
    SET(PYTHON_EXECUTABLE "python3")
  ENDIF()
ENDIF()

# Generate and load the micorkernels.cmake files.
MESSAGE(STATUS "Generating microkernels.cmake")
EXECUTE_PROCESS(
  COMMAND "${Python_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/tools/update-microkernels.py" --output "${PROJECT_BINARY_DIR}"
  RESULT_VARIABLE UPDATE_MICROKERNELS_RESULT
)
IF(NOT UPDATE_MICROKERNELS_RESULT EQUAL 0)
  MESSAGE(FATAL_ERROR "Failed to generate \"microkernels.cmake\".")
ENDIF()
INCLUDE("${PROJECT_BINARY_DIR}/cmake/gen/microkernels.cmake")

SET(OPERATOR_SRCS
  src/operator-delete.c
  src/operators/argmax-pooling-nhwc.c
  src/operators/average-pooling-nhwc.c
  src/operators/batch-matrix-multiply-nc.c
  src/operators/binary-elementwise-nd.c
  src/operators/constant-pad-nd.c
  src/operators/convolution-nchw.c
  src/operators/convolution-nhwc.c
  src/operators/deconvolution-nhwc.c
  src/operators/dynamic-fully-connected-nc.c
  src/operators/fully-connected-nc.c
  src/operators/max-pooling-nhwc.c
  src/operators/pack-lh.c
  src/operators/reduce-nd.c
  src/operators/resize-bilinear-nchw.c
  src/operators/resize-bilinear-nhwc.c
  src/operators/rope-nthc.c
  src/operators/slice-nd.c
  src/operators/softmax-nc.c
  src/operators/transpose-nd.c
  src/operators/unary-elementwise-nc.c
  src/operators/unpooling-nhwc.c)

SET(REFERENCE_SRCS
  src/reference/unary-elementwise.cc
  src/reference/binary-elementwise.cc)

SET(SUBGRAPH_SRCS
  src/memory-planner.c
  src/runtime.c
  src/subgraph.c
  src/subgraph/argmax-pooling-2d.c
  src/subgraph/average-pooling-2d.c
  src/subgraph/batch-matrix-multiply.c
  src/subgraph/binary.c
  src/subgraph/concatenate.c
  src/subgraph/convolution-2d.c
  src/subgraph/copy.c
  src/subgraph/deconvolution-2d.c
  src/subgraph/deprecated.c
  src/subgraph/depth-to-space-2d.c
  src/subgraph/depthwise-convolution-2d.c
  src/subgraph/even-split.c
  src/subgraph/fully-connected-sparse.c
  src/subgraph/fully-connected.c
  src/subgraph/max-pooling-2d.c
  src/subgraph/pack-lh.c
  src/subgraph/reshape-helpers.c
  src/subgraph/rewrites/fp16_to_fp32.cc
  src/subgraph/rope.c
  src/subgraph/softmax.c
  src/subgraph/space-to-depth-2d.c
  src/subgraph/static-constant-pad.c
  src/subgraph/static-reduce.c
  src/subgraph/static-resize-bilinear-2d.c
  src/subgraph/static-slice.c
  src/subgraph/static-transpose.c
  src/subgraph/subgraph-utils.c
  src/subgraph/unpooling-2d.c
  src/subgraph/unary.c
  src/subgraph/validation.c
  src/tensor.c)

SET(LOGGING_SRCS
  src/enums/allocation-type.c
  src/enums/datatype-strings.c
  src/enums/microkernel-type.c
  src/enums/node-type.c
  src/enums/operator-type.c
  src/log.c)

SET(XNNPACK_SRCS
  src/configs/argmaxpool-config.c
  src/configs/avgpool-config.c
  src/configs/binary-elementwise-config.c
  src/configs/cmul-config.c
  src/configs/conv-hwc2chw-config.c
  src/configs/dwconv-config.c
  src/configs/dwconv2d-chw-config.c
  src/configs/gemm-config.c
  src/configs/ibilinear-chw-config.c
  src/configs/ibilinear-config.c
  src/configs/lut32norm-config.c
  src/configs/maxpool-config.c
  src/configs/pack-lh-config.c
  src/configs/raddstoreexpminusmax-config.c
  src/configs/reduce-config.c
  src/configs/spmm-config.c
  src/configs/transpose-config.c
  src/configs/unary-elementwise-config.c
  src/configs/unpool-config.c
  src/configs/vmulcaddc-config.c
  src/configs/xx-fill-config.c
  src/configs/xx-pad-config.c
  src/configs/x8-lut-config.c
  src/init.c
  src/params.c
  "${PROJECT_BINARY_DIR}/build_identifier.c")

SET(TABLE_SRCS
  src/tables/exp2-k-over-64.c
  src/tables/exp2-k-over-2048.c
  src/tables/exp2minus-k-over-4.c
  src/tables/exp2minus-k-over-8.c
  src/tables/exp2minus-k-over-16.c
  src/tables/exp2minus-k-over-32.c
  src/tables/exp2minus-k-over-64.c
  src/tables/exp2minus-k-over-2048.c
  src/tables/vlog.c)

SET(PROD_MICROKERNEL_SRCS ${PROD_SCALAR_MICROKERNEL_SRCS})
SET(NON_PROD_MICROKERNEL_SRCS ${NON_PROD_SCALAR_MICROKERNEL_SRCS})
IF(XNNPACK_TARGET_PROCESSOR STREQUAL "arm")
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_ARMSIMD32_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEON_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONFP16_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONFMA_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONV8_MICROKERNEL_SRCS})
  IF(XNNPACK_ENABLE_ARM_FP16_SCALAR)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_FP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_FP16_VECTOR)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONFP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_DOTPROD)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONDOT_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_DOTPROD AND XNNPACK_ENABLE_ARM_FP16_VECTOR)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONDOTFP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_BF16)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONBF16_MICROKERNEL_SRCS})
  ENDIF()
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_ARMSIMD32_MICROKERNEL_SRCS})
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEON_MICROKERNEL_SRCS})
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONFP16_MICROKERNEL_SRCS})
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONFMA_MICROKERNEL_SRCS})
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONV8_MICROKERNEL_SRCS})
  IF(XNNPACK_ENABLE_ARM_FP16_SCALAR)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_FP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_FP16_VECTOR AND XNNPACK_ENABLE_ARM_DOTPROD)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONDOTFP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_FP16_VECTOR)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONFP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_BF16)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONBF16_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_DOTPROD)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONDOT_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ASSEMBLY)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AARCH32_ASM_MICROKERNEL_SRCS})
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AARCH32_ASM_MICROKERNEL_SRCS})
  ENDIF()
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR MATCHES "^arm64")
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEON_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONFP16_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONFMA_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONV8_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEON_AARCH64_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONFMA_AARCH64_MICROKERNEL_SRCS})
  IF(XNNPACK_ENABLE_ARM_FP16_SCALAR)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_FP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_FP16_VECTOR)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONFP16ARITH_MICROKERNEL_SRCS})
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONFP16ARITH_AARCH64_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_DOTPROD)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONDOT_MICROKERNEL_SRCS})
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONDOT_AARCH64_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_DOTPROD AND XNNPACK_ENABLE_ARM_FP16_VECTOR)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONDOTFP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_I8MM)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONI8MM_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_SME)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONSME_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_SME2)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONSME2_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_BF16)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_NEONBF16_MICROKERNEL_SRCS})
  ENDIF()
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEON_MICROKERNEL_SRCS})
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONFP16_MICROKERNEL_SRCS})
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONFMA_MICROKERNEL_SRCS})
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONV8_MICROKERNEL_SRCS})
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEON_AARCH64_MICROKERNEL_SRCS})
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONFMA_AARCH64_MICROKERNEL_SRCS})
  IF(XNNPACK_ENABLE_ARM_FP16_SCALAR)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_FP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_FP16_VECTOR AND XNNPACK_ENABLE_ARM_DOTPROD)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONDOTFP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_FP16_VECTOR)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONFP16ARITH_MICROKERNEL_SRCS})
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONFP16ARITH_AARCH64_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_BF16)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONBF16_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_DOTPROD)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONDOT_MICROKERNEL_SRCS})
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONDOT_AARCH64_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_I8MM)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONI8MM_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_SME)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONSME_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ARM_SME2)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_NEONSME2_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_ASSEMBLY)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AARCH64_ASM_MICROKERNEL_SRCS})
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AARCH64_ASM_MICROKERNEL_SRCS})
  ENDIF()
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR MATCHES "^x86(_64)?$")
  IF(XNNPACK_ENABLE_ASSEMBLY AND XNNPACK_TARGET_PROCESSOR MATCHES "x86_64")
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AMD64_ASM_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_SSE)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_SSE_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_SSE2)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_SSE2_MICROKERNEL_SRCS})
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_SSE2FMA_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_SSSE3)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_SSSE3_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_SSE41)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_SSE41_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_F16C)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_F16C_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_FMA3)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_FMA3_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX2)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX2_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVXVNNI)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVXVNNI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVXVNNIINT8)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVXVNNIINT8_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX256SKX)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX256SKX_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX256VNNI)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX256VNNI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX256VNNIGFNI)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX256VNNIGFNI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512F)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX512F_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512SKX)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX512SKX_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512VBMI)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX512VBMI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512VNNI)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX512VNNI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512VNNIGFNI)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX512VNNIGFNI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512AMX)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX512AMX_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512FP16)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX512FP16_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512BF16)
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_AVX512BF16_MICROKERNEL_SRCS})
  ENDIF()

  IF(XNNPACK_ENABLE_ASSEMBLY AND XNNPACK_TARGET_PROCESSOR MATCHES "x86_64")
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AMD64_ASM_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_SSE)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_SSE_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_SSE2)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_SSE2_MICROKERNEL_SRCS})
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_SSE2FMA_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_SSSE3)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_SSSE3_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_SSE41)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_SSE41_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_F16C)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_F16C_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_FMA3)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_FMA3_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX2)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX2_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVXVNNI)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVXVNNI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVXVNNIINT8)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVXVNNIINT8_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX256SKX)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX256SKX_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX256VNNI)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX256VNNI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX256VNNIGFNI)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX256VNNIGFNI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512F)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX512F_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512SKX)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX512SKX_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512VBMI)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX512VBMI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512VNNI)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX512VNNI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512VNNIGFNI)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX512VNNIGFNI_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512AMX)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX512AMX_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512FP16)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX512FP16_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_AVX512BF16)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_AVX512BF16_MICROKERNEL_SRCS})
  ENDIF()
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR MATCHES "Hexagon")
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_HEXAGON_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_HEXAGON_MICROKERNEL_SRCS})
  IF(XNNPACK_ENABLE_HVX)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_HVX_MICROKERNEL_SRCS})
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_HVX_MICROKERNEL_SRCS})
  ENDIF()
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR MATCHES "^ppc64")
  IF(XNNPACK_ENABLE_VSX)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_PPC64_MICROKERNEL_SRCS})
  ENDIF()
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR MATCHES "^riscv")
  IF(XNNPACK_ENABLE_RISCV_VECTOR)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_RVV_MICROKERNEL_SRCS})
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_RVV_MICROKERNEL_SRCS})
  ENDIF()
  IF(XNNPACK_ENABLE_RISCV_FP16_VECTOR)
    LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_RVVFP16ARITH_MICROKERNEL_SRCS})
    LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_RVVFP16ARITH_MICROKERNEL_SRCS})
  ENDIF()
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR MATCHES "^wasm")
  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_WASMRELAXEDSIMD_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_WASMRELAXEDSIMD_MICROKERNEL_SRCS})

  LIST(APPEND NON_PROD_MICROKERNEL_SRCS ${NON_PROD_WASMSIMD_MICROKERNEL_SRCS})
  LIST(APPEND PROD_MICROKERNEL_SRCS ${PROD_WASMSIMD_MICROKERNEL_SRCS})
ENDIF()

SET(ALL_MICROKERNEL_SRCS ${PROD_MICROKERNEL_SRCS} ${NON_PROD_MICROKERNEL_SRCS})

LIST(SORT PROD_MICROKERNEL_SRCS)
STRING(REPLACE ";" "\n" PROD_MICROKERNEL_SRCS_WITH_NEWLINES "${PROD_MICROKERNEL_SRCS}")
FILE(GENERATE OUTPUT "${PROJECT_BINARY_DIR}/prod_microkernel_srcs.txt" CONTENT "${PROD_MICROKERNEL_SRCS_WITH_NEWLINES}")
ADD_CUSTOM_COMMAND(
  OUTPUT "${PROJECT_BINARY_DIR}/build_identifier.c"
  COMMAND "${Python_EXECUTABLE}" "scripts/generate-build-identifier.py" --output "${PROJECT_BINARY_DIR}/build_identifier.c" --input_file_list "${PROJECT_BINARY_DIR}/prod_microkernel_srcs.txt"
  DEPENDS "${PROJECT_BINARY_DIR}/prod_microkernel_srcs.txt"
  WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)

# Create a dummy library that contains shared dependencies and definitions for
# all other XNNPACK targets.
ADD_LIBRARY(xnnpack-base INTERFACE)

ADD_LIBRARY(xnnpack-sanitizers OBJECT src/sanitizers.c)
ADD_LIBRARY(xnnpack-microkernels-prod STATIC ${PROD_MICROKERNEL_SRCS} ${TABLE_SRCS})
TARGET_LINK_LIBRARIES(xnnpack-microkernels-prod PUBLIC xnnpack-sanitizers)
IF(XNNPACK_BUILD_ALL_MICROKERNELS)
  ADD_LIBRARY(xnnpack-microkernels-all STATIC ${NON_PROD_MICROKERNEL_SRCS})
  TARGET_LINK_LIBRARIES(xnnpack-microkernels-all PUBLIC xnnpack-microkernels-prod)
ENDIF()
ADD_LIBRARY(xnnpack-hardware-config OBJECT src/configs/hardware-config.c src/xnnpack/init-once.c)
ADD_LIBRARY(xnnpack-indirection OBJECT src/indirection.c)
ADD_LIBRARY(xnnpack-logging OBJECT ${LOGGING_SRCS})
ADD_LIBRARY(xnnpack-microparams-init OBJECT src/microparams-init.c)
ADD_LIBRARY(xnnpack-normalization OBJECT src/normalization.c)
ADD_LIBRARY(xnnpack-pack-lh OBJECT src/pack-lh.cc)
ADD_LIBRARY(xnnpack-packing OBJECT src/reference/packing.cc)
TARGET_LINK_LIBRARIES(xnnpack-hardware-config PRIVATE xnnpack-base xnnpack-logging)
TARGET_LINK_LIBRARIES(xnnpack-indirection PRIVATE xnnpack-base)
TARGET_LINK_LIBRARIES(xnnpack-logging PRIVATE xnnpack-base)
IF(XNNPACK_BUILD_ALL_MICROKERNELS)
  TARGET_LINK_LIBRARIES(xnnpack-microkernels-all PRIVATE xnnpack-base)
ENDIF()
TARGET_LINK_LIBRARIES(xnnpack-microkernels-prod PRIVATE xnnpack-base)
TARGET_LINK_LIBRARIES(xnnpack-microparams-init PRIVATE xnnpack-base)
TARGET_LINK_LIBRARIES(xnnpack-normalization PRIVATE xnnpack-base)
TARGET_LINK_LIBRARIES(xnnpack-pack-lh PRIVATE xnnpack-base xnnpack-logging)
TARGET_LINK_LIBRARIES(xnnpack-packing PRIVATE xnnpack-base xnnpack-logging)
IF(XNNPACK_BUILD_LIBRARY)
  ADD_LIBRARY(xnnpack-allocator OBJECT src/allocator.c)
  ADD_LIBRARY(xnnpack-cache OBJECT src/cache.c)
  ADD_LIBRARY(xnnpack-datatype OBJECT src/datatype.c)
  ADD_LIBRARY(xnnpack-operator-delete OBJECT src/operator-delete.c)
  ADD_LIBRARY(xnnpack-fingerprint-id OBJECT src/operators/fingerprint_id.c)
  ADD_LIBRARY(xnnpack-fingerprint-cache OBJECT src/operators/fingerprint_cache.c)
  ADD_LIBRARY(xnnpack-fingerprint-check OBJECT src/xnnpack/fingerprint_check.c)
  ADD_LIBRARY(xnnpack-memory OBJECT src/memory.c)
  ADD_LIBRARY(xnnpack-microkernel-utils OBJECT src/microkernel-utils.c)
  ADD_LIBRARY(xnnpack-mutex OBJECT src/mutex.c)
  ADD_LIBRARY(xnnpack-operators OBJECT ${OPERATOR_SRCS})
  ADD_LIBRARY(xnnpack-operator-run OBJECT src/operator-run.c)
  ADD_LIBRARY(xnnpack-operator-utils OBJECT src/operator-utils.c)
  ADD_LIBRARY(xnnpack-reference-ukernels OBJECT ${REFERENCE_SRCS})
  ADD_LIBRARY(xnnpack-subgraph OBJECT ${SUBGRAPH_SRCS})
  # Need C_EXTENSIONS to get constants for mmap (MAP_ANONYMOUS).
  SET_TARGET_PROPERTIES(xnnpack-memory PROPERTIES C_EXTENSIONS YES)
  IF(XNNPACK_LIBRARY_TYPE STREQUAL "default")
    ADD_LIBRARY(XNNPACK ${XNNPACK_SRCS})
  ELSEIF(XNNPACK_LIBRARY_TYPE STREQUAL "shared")
    ADD_LIBRARY(XNNPACK SHARED ${XNNPACK_SRCS})
  ELSEIF(XNNPACK_LIBRARY_TYPE STREQUAL "static")
    ADD_LIBRARY(XNNPACK STATIC ${XNNPACK_SRCS})
  ELSE()
    MESSAGE(FATAL_ERROR "Unsupported XNNPACK library type \"${XNNPACK_LIBRARY_TYPE}\". Must be \"static\", \"shared\", or \"default\"")
  ENDIF()

  TARGET_LINK_LIBRARIES(xnnpack-allocator PRIVATE xnnpack-base xnnpack-logging)
  TARGET_LINK_LIBRARIES(xnnpack-cache PRIVATE xnnpack-base xnnpack-logging)
  TARGET_LINK_LIBRARIES(xnnpack-datatype PRIVATE xnnpack-base)
  TARGET_LINK_LIBRARIES(xnnpack-operator-delete PRIVATE xnnpack-base xnnpack-logging)
  TARGET_LINK_LIBRARIES(xnnpack-memory PRIVATE xnnpack-base xnnpack-logging)
  TARGET_LINK_LIBRARIES(xnnpack-microkernel-utils PRIVATE xnnpack-base xnnpack-hardware-config xnnpack-logging)
  TARGET_LINK_LIBRARIES(xnnpack-mutex PRIVATE xnnpack-base xnnpack-logging)
  TARGET_LINK_LIBRARIES(xnnpack-operators PRIVATE xnnpack-base xnnpack-allocator xnnpack-indirection
      xnnpack-logging xnnpack-microkernel-utils xnnpack-normalization xnnpack-operator-utils xnnpack-pack-lh xnnpack-packing
      xnnpack-reference-ukernels xnnpack-datatype)
  TARGET_LINK_LIBRARIES(xnnpack-fingerprint-cache PRIVATE xnnpack-base xnnpack-allocator xnnpack-cache xnnpack-mutex xnnpack-operator-delete)
  TARGET_LINK_LIBRARIES(xnnpack-fingerprint-check PRIVATE xnnpack-base xnnpack-logging xnnpack-fingerprint-cache xnnpack-operators)
  TARGET_LINK_LIBRARIES(xnnpack-operator-run PRIVATE xnnpack-base xnnpack-logging)
  TARGET_LINK_LIBRARIES(xnnpack-operator-utils PRIVATE xnnpack-base xnnpack-logging)
  TARGET_LINK_LIBRARIES(xnnpack-reference-ukernels PRIVATE xnnpack-base xnnpack-datatype)
  TARGET_LINK_LIBRARIES(xnnpack-subgraph PRIVATE xnnpack-base xnnpack-allocator xnnpack-cache xnnpack-logging xnnpack-memory xnnpack-mutex xnnpack-operators xnnpack-operator-run xnnpack-datatype)
  TARGET_LINK_LIBRARIES(XNNPACK PRIVATE xnnpack-base xnnpack-allocator xnnpack-cache
      xnnpack-hardware-config xnnpack-indirection xnnpack-memory xnnpack-microkernel-utils xnnpack-microparams-init
      xnnpack-mutex xnnpack-normalization xnnpack-operators xnnpack-operator-run
      xnnpack-operator-utils xnnpack-pack-lh xnnpack-packing xnnpack-fingerprint-id xnnpack-fingerprint-cache xnnpack-microkernels-prod
      xnnpack-subgraph xnnpack-datatype xnnpack-reference-ukernels)
  TARGET_LINK_LIBRARIES(XNNPACK PUBLIC pthreadpool xnnpack-logging xnnpack-fingerprint-check)
  SET_TARGET_PROPERTIES(XNNPACK PROPERTIES C_EXTENSIONS YES)
ENDIF()
IF(NOT MSVC)
  SET_PROPERTY(SOURCE ${ALL_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-math-errno")
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR STREQUAL "arm")
  SET_PROPERTY(SOURCE ${ALL_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -marm")
  SET_PROPERTY(SOURCE ${ALL_ARMSIMD32_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv6 -mfpu=vfp -munaligned-access")
  SET_PROPERTY(SOURCE ${ALL_NEON_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv7-a -mfpu=neon")
  SET_PROPERTY(SOURCE ${ALL_NEONFP16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv7-a -mfpu=neon-fp16")
  # GCC requires -mfp16-format=ieee to define __fp16 type, but Clang doesn't support this option at all.
  IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
    SET_PROPERTY(SOURCE ${ALL_NEONFP16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfp16-format=ieee")
    SET_PROPERTY(SOURCE ${ALL_FP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfp16-format=ieee")
    SET_PROPERTY(SOURCE ${ALL_NEONDOTFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfp16-format=ieee")
    SET_PROPERTY(SOURCE ${ALL_NEONFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfp16-format=ieee")
  ENDIF()
  SET_PROPERTY(SOURCE ${ALL_NEONFMA_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv7-a -mfpu=neon-vfpv4")
  SET_PROPERTY(SOURCE ${ALL_NEONV8_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8-a -mfpu=neon-fp-armv8")
  # -mfpu=fp-armv8 should suffice for FP16ARITH microkernels, if not for GCC emitting wrong directives for assembler
  # -fno-math-errno for the vsqrth_f16 polyfill using sqrtf
  # -ffinite-math-only for the vminnmh_f16/vmaxnmh_f16 polyfills using compare + select
  SET_PROPERTY(SOURCE ${ALL_FP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+fp16 -mfpu=neon-fp-armv8 -fno-math-errno -ffinite-math-only")
  SET_PROPERTY(SOURCE ${ALL_NEONDOTFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+dotprod+fp16 -mfpu=neon-fp-armv8 -fno-math-errno -ffinite-math-only")
  SET_PROPERTY(SOURCE ${ALL_NEONFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+fp16 -mfpu=neon-fp-armv8")
  SET_PROPERTY(SOURCE ${ALL_NEONBF16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+bf16 -mfpu=neon-fp-armv8")
  SET_PROPERTY(SOURCE ${ALL_NEONDOT_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+dotprod -mfpu=neon-fp-armv8")
  SET_PROPERTY(SOURCE ${ALL_AARCH32_ASM_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+dotprod+fp16 -mfpu=neon-fp-armv8")
  # Workground the neon detection bug in ARM v8
  # Related links:
  #   https://github.com/android/ndk/issues/910
  #   https://reviews.llvm.org/D58477
  IF(ANDROID_NDK_MAJOR AND ANDROID_NDK_MAJOR LESS 21)
    SET_PROPERTY(SOURCE ${ALL_NEONV8_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfloat-abi=softfp")
    SET_PROPERTY(SOURCE ${ALL_FP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfloat-abi=softfp")
    SET_PROPERTY(SOURCE ${ALL_NEONDOTFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfloat-abi=softfp")
    SET_PROPERTY(SOURCE ${ALL_NEONFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfloat-abi=softfp")
    SET_PROPERTY(SOURCE ${ALL_NEONBF16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfloat-abi=softfp")
    SET_PROPERTY(SOURCE ${ALL_NEONDOT_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfloat-abi=softfp")
    SET_PROPERTY(SOURCE ${ALL_AARCH32_ASM_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mfloat-abi=softfp")
  ENDIF()
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR MATCHES "^arm64")
  IF(MSVC)
    SET_PROPERTY(SOURCE ${ALL_FP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
    SET_PROPERTY(SOURCE ${ALL_NEONFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
    SET_PROPERTY(SOURCE ${ALL_NEONDOTFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
    SET_PROPERTY(SOURCE ${ALL_NEONFP16ARITH_AARCH64_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
    SET_PROPERTY(SOURCE ${ALL_NEONBF16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
    SET_PROPERTY(SOURCE ${ALL_NEONDOT_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
    SET_PROPERTY(SOURCE ${ALL_NEONDOT_AARCH64_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
    SET_PROPERTY(SOURCE ${ALL_NEONI8MM_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
    SET_PROPERTY(SOURCE ${ALL_NEONSME_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
    SET_PROPERTY(SOURCE ${ALL_NEONSME2_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
    SET_PROPERTY(SOURCE ${ALL_AARCH64_ASM_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:armv8.2")
  ELSE()
    SET_PROPERTY(SOURCE ${ALL_FP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+fp16")
    SET_PROPERTY(SOURCE ${ALL_NEONFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+fp16")
    SET_PROPERTY(SOURCE ${ALL_NEONDOTFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+dotprod+fp16")
    SET_PROPERTY(SOURCE ${ALL_NEONFP16ARITH_AARCH64_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+fp16")
    SET_PROPERTY(SOURCE ${ALL_NEONBF16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+bf16")
    SET_PROPERTY(SOURCE ${ALL_NEONDOT_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+dotprod")
    SET_PROPERTY(SOURCE ${ALL_NEONDOT_AARCH64_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+dotprod")
    SET_PROPERTY(SOURCE ${ALL_NEONI8MM_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+i8mm+fp16")
    SET_PROPERTY(SOURCE ${ALL_NEONSME_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+sve+sve2")
    SET_PROPERTY(SOURCE ${ALL_NEONSME2_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+sve+sve2")
    SET_PROPERTY(SOURCE ${ALL_AARCH64_ASM_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=armv8.2-a+fp16+dotprod")
  ENDIF()
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR MATCHES "^ppc64")
  IF(XNNPACK_ENABLE_VSX)
    SET_PROPERTY(SOURCE ${ALL_PPC_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mvsx")
  ENDIF()
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR MATCHES "^riscv")
  IF(XNNPACK_ENABLE_RISCV_VECTOR)
    SET_PROPERTY(SOURCE ${ALL_RVV_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=rv64gcv -mabi=lp64d")
  ENDIF()
  SET_PROPERTY(SOURCE ${ALL_RVVFP16ARITH_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -march=rv64gcv_zvfh -mabi=lp64d")
ENDIF()
IF(XNNPACK_TARGET_PROCESSOR MATCHES "^x86(_64)?$")
  IF(MSVC)
    IF(XNNPACK_TARGET_PROCESSOR STREQUAL "x86" OR CMAKE_SIZEOF_VOID_P EQUAL 4)
      SET_PROPERTY(SOURCE ${ALL_SSE_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:SSE")
      SET_PROPERTY(SOURCE ${ALL_SSE2_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:SSE2")
      SET_PROPERTY(SOURCE ${ALL_SSSE3_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:SSE2")
      SET_PROPERTY(SOURCE ${ALL_SSE41_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:SSE2")
    ENDIF()
    SET_PROPERTY(SOURCE ${ALL_AVX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX")
    SET_PROPERTY(SOURCE ${ALL_F16C_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX")
    SET_PROPERTY(SOURCE ${ALL_FMA3_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX")
    SET_PROPERTY(SOURCE ${ALL_AVXVNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX2")
    SET_PROPERTY(SOURCE ${ALL_AVXVNNIINT8_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX2")
    SET_PROPERTY(SOURCE ${ALL_AVX256SKX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX512 /vlen=256")
    SET_PROPERTY(SOURCE ${ALL_AVX256VNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX512 /vlen=256")
    SET_PROPERTY(SOURCE ${ALL_AVX256VNNIGFNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX512 /vlen=256")
    SET_PROPERTY(SOURCE ${ALL_AVX512F_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX512")
    SET_PROPERTY(SOURCE ${ALL_AVX512SKX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX512")
    SET_PROPERTY(SOURCE ${ALL_AVX512BF16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX512")
    SET_PROPERTY(SOURCE ${ALL_AVX512VBMI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX512")
    SET_PROPERTY(SOURCE ${ALL_AVX512VNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX512")
    SET_PROPERTY(SOURCE ${ALL_AVX2_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " /arch:AVX2")
    IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
      SET_PROPERTY(SOURCE ${ALL_SSE_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-msse -clang:-mno-sse2")
      SET_PROPERTY(SOURCE ${ALL_SSE2_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-msse2 -clang:-mno-sse3")
      SET_PROPERTY(SOURCE ${ALL_SSSE3_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mssse3 -clang:-mno-sse4.1")
      SET_PROPERTY(SOURCE ${ALL_SSE41_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-msse4.1 -clang:-mno-sse4.2")
      SET_PROPERTY(SOURCE ${ALL_AVX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mavx -clang:-mno-avx2 -clang:-mno-fma -clang:-mno-f16c")
      SET_PROPERTY(SOURCE ${ALL_F16C_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mno-avx2 -clang:-mno-fma")
      SET_PROPERTY(SOURCE ${ALL_FMA3_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mno-avx2")
      SET_PROPERTY(SOURCE ${ALL_AVX2_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx2")
      SET_PROPERTY(SOURCE ${ALL_AVXVNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx2 -clang:-mavxvnni -clang:-mgfni")
      SET_PROPERTY(SOURCE ${ALL_AVXVNNIINT8_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx2 -clang:-mavxvnniint8 -clang:-mgfni")
      SET_PROPERTY(SOURCE ${ALL_AVX256SKX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx512f -clang:-mavx512cd -clang:-mavx512bw -clang:-mavx512dq -clang:-mavx512vl")
      SET_PROPERTY(SOURCE ${ALL_AVX256VNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx512f -clang:-mavx512cd -clang:-mavx512bw -clang:-mavx512dq -clang:-mavx512vl -clang:-mavx512vnni")
      SET_PROPERTY(SOURCE ${ALL_AVX256VNNIGFNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx512f -clang:-mavx512cd -clang:-mavx512bw -clang:-mavx512dq -clang:-mavx512vl -clang:-mavx512vnni -clang:-mgfni")
      SET_PROPERTY(SOURCE ${ALL_AVX512F_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mavx512f")
      SET_PROPERTY(SOURCE ${ALL_AVX512SKX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx512f -clang:-mavx512cd -clang:-mavx512bw -clang:-mavx512dq -clang:-mavx512vl")
      SET_PROPERTY(SOURCE ${ALL_AVX512BF16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx512f -clang:-mavx512cd -clang:-mavx512bw -clang:-mavx512dq -clang:-mavx512vl -clang:-mavx512bf16")
      SET_PROPERTY(SOURCE ${ALL_AVX512VBMI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx512f -clang:-mavx512cd -clang:-mavx512bw -clang:-mavx512dq -clang:-mavx512vl -clang:-mavx512vbmi")
      SET_PROPERTY(SOURCE ${ALL_AVX512VNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx512f -clang:-mavx512cd -clang:-mavx512bw -clang:-mavx512dq -clang:-mavx512vl -clang:-mavx512vnni")
      SET_PROPERTY(SOURCE ${ALL_AVX512VNNIGFNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx512f -clang:-mavx512cd -clang:-mavx512bw -clang:-mavx512dq -clang:-mavx512vl -clang:-mavx512vnni -clang:-mgfni")
      SET_PROPERTY(SOURCE ${ALL_AVX512FP16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx512f -clang:-mavx512cd -clang:-mavx512bw -clang:-mavx512dq -clang:-mavx512vl -clang:-mavx512vnni -clang:-mgfni -clang:-mavx512fp16")
      SET_PROPERTY(SOURCE ${ALL_AVX512AMX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -clang:-mf16c -clang:-mfma -clang:-mavx512f -clang:-mavx512cd -clang:-mavx512bw -clang:-mavx512dq -clang:-mavx512vl -clang:-mavx512vnni -clang:-mgfni -clang:-mamx-tile -clang:-mamx-int8")
    ENDIF()
  ELSE()
    IF (NOT CMAKE_SYSTEM_NAME MATCHES "^(iOS|Fuchsia)$")
      IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
        SET_PROPERTY(SOURCE ${ALL_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mpreferred-stack-boundary=6 -fomit-frame-pointer -mstackrealign -mincoming-stack-boundary=4")
      ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
        SET_PROPERTY(SOURCE ${ALL_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mstack-alignment=64 -fomit-frame-pointer -mstackrealign")
      ELSE()
        SET_PROPERTY(SOURCE ${ALL_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fomit-frame-pointer")
      ENDIF()
    ENDIF()
    SET_PROPERTY(SOURCE ${ALL_SSE_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -msse -mno-sse2")
    SET_PROPERTY(SOURCE ${ALL_SSE2_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -msse2 -mno-sse3")
    SET_PROPERTY(SOURCE ${ALL_SSSE3_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mssse3 -mno-sse4.1")
    SET_PROPERTY(SOURCE ${ALL_SSE41_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -msse4.1 -mno-sse4.2")
    SET_PROPERTY(SOURCE ${ALL_AVX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mavx -mno-avx2 -mno-fma -mno-f16c")
    SET_PROPERTY(SOURCE ${ALL_F16C_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mno-avx2 -mno-fma")
    SET_PROPERTY(SOURCE ${ALL_FMA3_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mno-avx2")
    SET_PROPERTY(SOURCE ${ALL_AVX2_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx2")
    SET_PROPERTY(SOURCE ${ALL_AVXVNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx2 -mavxvnni -mgfni")
    SET_PROPERTY(SOURCE ${ALL_AVXVNNIINT8_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx2 -mavxvnniint8 -mgfni")
    SET_PROPERTY(SOURCE ${ALL_AVX256SKX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl")
    SET_PROPERTY(SOURCE ${ALL_AVX256VNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni")
    SET_PROPERTY(SOURCE ${ALL_AVX256VNNIGFNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni -mgfni")
    SET_PROPERTY(SOURCE ${ALL_AVX512F_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mavx512f")
    SET_PROPERTY(SOURCE ${ALL_AVX512SKX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl")
    SET_PROPERTY(SOURCE ${ALL_AVX512BF16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512bf16")
    SET_PROPERTY(SOURCE ${ALL_AVX512VBMI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vbmi")
    SET_PROPERTY(SOURCE ${ALL_AVX512VNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni")
    SET_PROPERTY(SOURCE ${ALL_AVX512VNNIGFNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni -mgfni")
    SET_PROPERTY(SOURCE ${ALL_AVX512FP16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni -mgfni -mavx512fp16")
    SET_PROPERTY(SOURCE ${ALL_AVX512AMX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -mf16c -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni -mgfni -mamx-tile -mamx-int8")
    IF(MINGW OR CMAKE_SYSTEM_NAME MATCHES "^(CYGWIN|MSYS)$")
      # Work-around for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65782
      SET_PROPERTY(SOURCE ${ALL_AVX512F_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-asynchronous-unwind-tables")
      SET_PROPERTY(SOURCE ${ALL_AVX512SKX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-asynchronous-unwind-tables")
      SET_PROPERTY(SOURCE ${ALL_AVX512BF16_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-asynchronous-unwind-tables")
      SET_PROPERTY(SOURCE ${ALL_AVX512VBMI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-asynchronous-unwind-tables")
      SET_PROPERTY(SOURCE ${ALL_AVX512VNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-asynchronous-unwind-tables")
      SET_PROPERTY(SOURCE ${ALL_AVXVNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-asynchronous-unwind-tables")
      SET_PROPERTY(SOURCE ${ALL_AVXVNNIINT8_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-asynchronous-unwind-tables")
      SET_PROPERTY(SOURCE ${ALL_AVX256SKX_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-asynchronous-unwind-tables")
      SET_PROPERTY(SOURCE ${ALL_AVX256VNNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-asynchronous-unwind-tables")
      SET_PROPERTY(SOURCE ${ALL_AVX256VNNIGFNI_MICROKERNEL_SRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-asynchronous-unwind-tables")
    ENDIF()
  ENDIF()
ENDIF()

# Set `XNN_LOG_LEVEL` transitively for all targets that depend on `logging`.
TARGET_COMPILE_DEFINITIONS(xnnpack-logging PUBLIC "XNN_LOG_LEVEL=$<$<CONFIG:Debug>:5>$<$<NOT:$<CONFIG:Debug>>:0>")

IF(MSVC)
  # Even though MSVC has __restrict, it can't be used in all the same contexts as the C99 restrict keyword
  TARGET_COMPILE_DEFINITIONS(xnnpack-base INTERFACE "restrict=")

  IF(XNNPACK_BUILD_ALL_MICROKERNELS)
    TARGET_COMPILE_OPTIONS(xnnpack-microkernels-all PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O2>")
  ENDIF()
  TARGET_COMPILE_OPTIONS(xnnpack-microkernels-prod PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O2>")
  TARGET_COMPILE_OPTIONS(xnnpack-hardware-config PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O2>")
  TARGET_COMPILE_OPTIONS(xnnpack-indirection PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O2>")
  TARGET_COMPILE_OPTIONS(xnnpack-microparams-init PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O2>")
  TARGET_COMPILE_OPTIONS(xnnpack-normalization PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O1>")
  TARGET_COMPILE_OPTIONS(xnnpack-pack-lh PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O2>")
  TARGET_COMPILE_OPTIONS(xnnpack-packing PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O2>")
  IF(XNNPACK_BUILD_LIBRARY)
    TARGET_COMPILE_OPTIONS(xnnpack-microkernel-utils PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O2>")
    TARGET_COMPILE_OPTIONS(xnnpack-operator-run PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O2>")
    TARGET_COMPILE_OPTIONS(xnnpack-operator-utils PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O2>")
    TARGET_COMPILE_OPTIONS(xnnpack-cache PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O1>")
    TARGET_COMPILE_OPTIONS(xnnpack-mutex PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O1>")
    TARGET_COMPILE_OPTIONS(xnnpack-subgraph PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O1>")
    TARGET_COMPILE_OPTIONS(xnnpack-operators PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O1>")
    TARGET_COMPILE_OPTIONS(XNNPACK PRIVATE "$<$<NOT:$<CONFIG:Debug>>:/O1>")
  ENDIF()
ELSE()
  TARGET_COMPILE_OPTIONS(xnnpack-base INTERFACE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
  IF(XNNPACK_BUILD_ALL_MICROKERNELS)
    TARGET_COMPILE_OPTIONS(xnnpack-microkernels-all PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
  ENDIF()
  TARGET_COMPILE_OPTIONS(xnnpack-microkernels-prod PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
  TARGET_COMPILE_OPTIONS(xnnpack-hardware-config PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
  TARGET_COMPILE_OPTIONS(xnnpack-indirection PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
  TARGET_COMPILE_OPTIONS(xnnpack-microparams-init PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
  TARGET_COMPILE_OPTIONS(xnnpack-normalization PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-Os>")
  TARGET_COMPILE_OPTIONS(xnnpack-pack-lh PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
  TARGET_COMPILE_OPTIONS(xnnpack-packing PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
  IF(XNNPACK_BUILD_LIBRARY)
    TARGET_COMPILE_OPTIONS(xnnpack-microkernel-utils PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
    TARGET_COMPILE_OPTIONS(xnnpack-operator-run PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
    TARGET_COMPILE_OPTIONS(xnnpack-operator-utils PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O2>")
    TARGET_COMPILE_OPTIONS(xnnpack-cache PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-Os>")
    TARGET_COMPILE_OPTIONS(xnnpack-mutex PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-Os>")
    TARGET_COMPILE_OPTIONS(xnnpack-subgraph PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-Os>")
    TARGET_COMPILE_OPTIONS(xnnpack-operators PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-Os>")
    TARGET_COMPILE_OPTIONS(XNNPACK PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-Os>")
  ENDIF()
ENDIF()

INCLUDE_DIRECTORIES(.)
TARGET_INCLUDE_DIRECTORIES(xnnpack-hardware-config PRIVATE include src ${CPUINFO_SOURCE_DIR}/include)
IF(XNNPACK_BUILD_LIBRARY)
  TARGET_INCLUDE_DIRECTORIES(XNNPACK PUBLIC include)
  IF(WIN32)
    # Target Windows 7+ API
    TARGET_COMPILE_DEFINITIONS(XNNPACK PRIVATE _WIN32_WINNT=0x0601)
    TARGET_COMPILE_DEFINITIONS(xnnpack-mutex PRIVATE _WIN32_WINNT=0x0601)
  ENDIF()
  SET_PROPERTY(TARGET XNNPACK PROPERTY PUBLIC_HEADER include/xnnpack.h)
ENDIF()

# ---[ Find libm
IF(XNNPACK_BUILD_WITH_LIBM)
  FIND_LIBRARY(LIBM m)
  IF(LIBM)
    IF(XNNPACK_BUILD_ALL_MICROKERNELS)
      TARGET_LINK_LIBRARIES(xnnpack-microkernels-all PRIVATE $<BUILD_INTERFACE:${LIBM}> $<INSTALL_INTERFACE:m>)
    ENDIF()
    TARGET_LINK_LIBRARIES(xnnpack-microkernels-prod PRIVATE $<BUILD_INTERFACE:${LIBM}> $<INSTALL_INTERFACE:m>)
    TARGET_LINK_LIBRARIES(xnnpack-hardware-config PRIVATE $<BUILD_INTERFACE:${LIBM}> $<INSTALL_INTERFACE:m>)
    TARGET_LINK_LIBRARIES(xnnpack-indirection PRIVATE $<BUILD_INTERFACE:${LIBM}> $<INSTALL_INTERFACE:m>)
    TARGET_LINK_LIBRARIES(xnnpack-subgraph PRIVATE $<BUILD_INTERFACE:${LIBM}> $<INSTALL_INTERFACE:m>)
    IF(XNNPACK_BUILD_LIBRARY)
      TARGET_LINK_LIBRARIES(XNNPACK PRIVATE $<BUILD_INTERFACE:${LIBM}> $<INSTALL_INTERFACE:m>)
    ENDIF()
  ENDIF()
ENDIF()

# ---[ Configure cpuinfo
IF(NOT TARGET cpuinfo)
  IF(NOT XNNPACK_USE_SYSTEM_LIBS)
    SET(CPUINFO_BUILD_TOOLS OFF CACHE BOOL "")
    SET(CPUINFO_BUILD_UNIT_TESTS OFF CACHE BOOL "")
    SET(CPUINFO_BUILD_MOCK_TESTS OFF CACHE BOOL "")
    SET(CPUINFO_BUILD_BENCHMARKS OFF CACHE BOOL "")
    ADD_SUBDIRECTORY(
      "${CPUINFO_SOURCE_DIR}"
      "${CMAKE_BINARY_DIR}/cpuinfo")
  ELSE()
    ADD_LIBRARY(cpuinfo SHARED IMPORTED)
    FIND_LIBRARY(CPUINFO_LIBRARY cpuinfo PATHS "${CPUINFO_SOURCE_DIR}/lib")
    IF(NOT CPUINFO_LIBRARY)
      MESSAGE(FATAL_ERROR "Cannot find cpuinfo")
    ENDIF()
    TARGET_INCLUDE_DIRECTORIES(cpuinfo INTERFACE "${CPUINFO_SOURCE_DIR}/include")
    SET_PROPERTY(TARGET cpuinfo PROPERTY IMPORTED_LOCATION "${CPUINFO_LIBRARY}")
    SET_PROPERTY(TARGET cpuinfo PROPERTY IMPORTED_IMPLIB "${CPUINFO_LIBRARY}")
  ENDIF()
ENDIF()
IF(XNNPACK_BUILD_LIBRARY)
  TARGET_LINK_LIBRARIES(xnnpack-hardware-config PRIVATE cpuinfo)
  TARGET_LINK_LIBRARIES(XNNPACK PRIVATE cpuinfo)
ENDIF()

# ---[ Configure pthreadpool
IF(NOT TARGET pthreadpool)
  IF(NOT XNNPACK_USE_SYSTEM_LIBS)
    SET(PTHREADPOOL_BUILD_TESTS OFF CACHE BOOL "")
    SET(PTHREADPOOL_BUILD_BENCHMARKS OFF CACHE BOOL "")
    SET(PTHREADPOOL_ALLOW_DEPRECATED_API OFF CACHE BOOL "")
    ADD_SUBDIRECTORY(
      "${PTHREADPOOL_SOURCE_DIR}"
      "${CMAKE_BINARY_DIR}/pthreadpool")
  ELSE()
    ADD_LIBRARY(pthreadpool SHARED IMPORTED)
    FIND_LIBRARY(PTHREADPOOL_LIBRARY pthreadpool PATHS "${PTHREADPOOL_SOURCE_DIR}/lib")
    IF(NOT PTHREADPOOL_LIBRARY)
      MESSAGE(FATAL_ERROR "Cannot find pthreadpool")
    ENDIF()
    FIND_PACKAGE(Threads REQUIRED)
    TARGET_INCLUDE_DIRECTORIES(pthreadpool INTERFACE "${PTHREADPOOL_SOURCE_DIR}/include")
    TARGET_LINK_LIBRARIES(pthreadpool INTERFACE Threads::Threads)
    SET_PROPERTY(TARGET pthreadpool PROPERTY IMPORTED_LOCATION "${PTHREADPOOL_LIBRARY}")
    SET_PROPERTY(TARGET pthreadpool PROPERTY IMPORTED_IMPLIB "${PTHREADPOOL_LIBRARY}")
  ENDIF()
ENDIF()
TARGET_LINK_LIBRARIES(xnnpack-base INTERFACE pthreadpool)



IF(XNNPACK_BUILD_LIBRARY)
  INSTALL(TARGETS XNNPACK xnnpack-microkernels-prod
      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
      PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
ENDIF()

# ---[ Configure KleidiAI
IF(XNNPACK_ENABLE_KLEIDIAI)
  IF(NOT TARGET kleidiai)
    IF(NOT XNNPACK_USE_SYSTEM_LIBS)
      SET(KLEIDIAI_BUILD_TESTS OFF CACHE BOOL "")
      ADD_SUBDIRECTORY(
        "${KLEIDIAI_SOURCE_DIR}"
        "${CMAKE_BINARY_DIR}/kleidiai")
    ELSE()
      ADD_LIBRARY(kleidiai SHARED IMPORTED)
      FIND_LIBRARY(KLEIDIAI_LIBRARY kleidiai PATHS "${KLEIDIAI_SOURCE_DIR}/lib")
      IF(NOT KLEIDIAI_LIBRARY)
        MESSAGE(FATAL_ERROR "Cannot find KleidiAI")
      ENDIF()
      TARGET_INCLUDE_DIRECTORIES(kleidiai INTERFACE "${KLEIDIAI_SOURCE_DIR}")
      SET_PROPERTY(TARGET kleidiai PROPERTY IMPORTED_LOCATION "${KLEIDIAI_LIBRARY}")
      SET_PROPERTY(TARGET kleidiai PROPERTY IMPORTED_IMPLIB "${KLEIDIAI_LIBRARY}")
    ENDIF()
  ENDIF()
  TARGET_LINK_LIBRARIES(xnnpack-base INTERFACE kleidiai)
ENDIF()

# ---[ YNNPACK
IF(XNNPACK_BUILD_YNNPACK)
  ADD_SUBDIRECTORY(ynnpack)
ENDIF()

# ---[ XNNPACK unit tests
IF(XNNPACK_BUILD_TESTS)
  ADD_SUBDIRECTORY(test)
ENDIF()

# ---[ XNNPACK microbenchmarks
IF(XNNPACK_BUILD_BENCHMARKS)
  ADD_SUBDIRECTORY(bench)
ENDIF()

