cmake_minimum_required(VERSION 3.22)
project(openweights_apple_benchmark LANGUAGES C CXX OBJC OBJCXX)
set(CMAKE_CXX_STANDARD 17)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
set(GGML_BACKEND_DL OFF CACHE BOOL "" FORCE)
set(GGML_CPU_ALL_VARIANTS OFF CACHE BOOL "" FORCE)
set(GGML_NATIVE OFF CACHE BOOL "" FORCE)
set(GGML_METAL ON CACHE BOOL "" FORCE)
set(GGML_METAL_EMBED_LIBRARY ON CACHE BOOL "" FORCE)
set(GGML_ACCELERATE ON CACHE BOOL "" FORCE)
set(GGML_OPENMP OFF CACHE BOOL "" FORCE)
set(LLAMA_BUILD_COMMON ON CACHE BOOL "" FORCE)
set(LLAMA_BUILD_MTMD ON CACHE BOOL "" FORCE)
set(LLAMA_BUILD_TOOLS OFF CACHE BOOL "" FORCE)
set(LLAMA_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(LLAMA_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(LLAMA_CURL OFF CACHE BOOL "" FORCE)
set(ENGINE "${CMAKE_CURRENT_SOURCE_DIR}/../../../core/engine/src/main/cpp")
option(OW_GGUF_ONLY "Build the older-iOS GGUF benchmark without ExecuTorch tokenizer addons" OFF)
if (NOT OW_GGUF_ONLY)
set(TOKENIZERS "${CMAKE_CURRENT_SOURCE_DIR}/../.build/deps/tokenizers")
set(PCRE2_BUILD_PCRE2_8 ON CACHE BOOL "" FORCE)
set(PCRE2_BUILD_PCRE2_16 OFF CACHE BOOL "" FORCE)
set(PCRE2_BUILD_PCRE2_32 OFF CACHE BOOL "" FORCE)
set(PCRE2_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(PCRE2_BUILD_PCRE2GREP OFF CACHE BOOL "" FORCE)
set(PCRE2_SUPPORT_JIT OFF CACHE BOOL "" FORCE)
add_subdirectory("${TOKENIZERS}/third-party/pcre2" pcre2 EXCLUDE_FROM_ALL)
# The prebuilt iOS LLM package omits the optional regex required by Qwen's
# unmodified tokenizer. Link the addon from its matching source revision.
add_library(ow_regex_lookahead STATIC
    "${TOKENIZERS}/src/pcre2_regex.cpp"
    "${TOKENIZERS}/src/regex_lookahead.cpp"
    "${TOKENIZERS}/src/std_regex.cpp")
target_include_directories(ow_regex_lookahead PRIVATE "${TOKENIZERS}/include" "${CMAKE_CURRENT_BINARY_DIR}/pcre2")
target_link_libraries(ow_regex_lookahead PRIVATE pcre2-8-static)
set_target_properties(ow_regex_lookahead PROPERTIES CXX_STANDARD 20)
endif()
include("${ENGINE}/PatchGGMLGraphOffset.cmake")
add_subdirectory("${ENGINE}/llama.cpp" llama EXCLUDE_FROM_ALL)
# ExecuTorch's tokenizer bundles another version of llama.cpp's Unicode helpers.
# Keep each tokenizer's functions and tables separate when both are linked.
file(READ "${ENGINE}/llama.cpp/src/unicode.h" UNICODE_API)
file(READ "${ENGINE}/llama.cpp/src/unicode-data.h" UNICODE_DATA)
string(REGEX MATCHALL "unicode_[a-zA-Z0-9_]+" UNICODE_NAMES "${UNICODE_API}${UNICODE_DATA}")
list(REMOVE_DUPLICATES UNICODE_NAMES)
foreach(NAME IN LISTS UNICODE_NAMES)
    target_compile_definitions(llama PUBLIC "${NAME}=ow_llama_${NAME}")
endforeach()
target_compile_definitions(llama PUBLIC range_nfd=ow_llama_range_nfd)
add_library(openweights_apple STATIC "${ENGINE}/engine_session.cpp" OWSession.mm)
target_include_directories(openweights_apple PRIVATE
    "${ENGINE}" "${ENGINE}/llama.cpp/include" "${ENGINE}/llama.cpp/ggml/include"
    "${ENGINE}/llama.cpp/common" "${ENGINE}/llama.cpp/tools/mtmd" "${ENGINE}/llama.cpp/vendor")
target_compile_options(openweights_apple PRIVATE "$<$<COMPILE_LANGUAGE:OBJCXX>:-fobjc-arc>")
target_link_libraries(openweights_apple PRIVATE llama ggml llama-common mtmd "-framework Foundation")
