# cmake/MetalShaderCompile.cmake — Compile Metal shaders to metallib # # Usage: # include(cmake/MetalShaderCompile.cmake) # turboquant_add_metal_shader(TARGET shader_target SOURCE ggml-metal-turbo.metal) # # On non-macOS platforms, this is a no-op (shader is installed as source). # If Metal toolchain is not installed, shader compilation is skipped gracefully. function(turboquant_add_metal_shader) cmake_parse_arguments(ARGS "" "TARGET;SOURCE;OUTPUT" "" ${ARGN}) if(NOT APPLE) # On non-Apple platforms, just ensure the .metal file is included # in install targets. Runtime compilation is not available. message(STATUS "Metal shader compilation skipped (not on Apple platform)") return() endif() find_program(XCRUN_EXECUTABLE xcrun) if(NOT XCRUN_EXECUTABLE) message(WARNING "xcrun not found — Metal shader compilation disabled") return() endif() # Check if Metal toolchain is actually installed execute_process( COMMAND "${XCRUN_EXECUTABLE}" -sdk macosx metal --version OUTPUT_VARIABLE METAL_VERSION ERROR_VARIABLE METAL_VERSION_ERR RESULT_VARIABLE METAL_VERSION_RESULT TIMEOUT 10 ) if(NOT METAL_VERSION_RESULT EQUAL 0) message(WARNING "Metal toolchain not installed (xcrun metal failed) — shader compilation disabled") message(STATUS " Install with: xcodebuild -downloadComponent MetalToolchain") return() endif() set(METAL_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_SOURCE}") set(METAL_AIR "${CMAKE_CURRENT_BINARY_DIR}/ggml-metal-turbo.air") set(METAL_LIB "${CMAKE_CURRENT_BINARY_DIR}/ggml-metal-turbo.metallib") if(ARGS_OUTPUT) set(METAL_LIB "${ARGS_OUTPUT}") endif() # Step 1: Compile .metal → .air (Metal intermediate) add_custom_command( OUTPUT "${METAL_AIR}" COMMAND "${XCRUN_EXECUTABLE}" -sdk macosx metal -c "${METAL_SOURCE}" -o "${METAL_AIR}" -std=metal2.4 -O2 DEPENDS "${METAL_SOURCE}" COMMENT "Compiling Metal shader: ${ARGS_SOURCE}" VERBATIM ) # Step 2: Link .air → .metallib (Metal library) add_custom_command( OUTPUT "${METAL_LIB}" COMMAND "${XCRUN_EXECUTABLE}" -sdk macosx metallib "${METAL_AIR}" -o "${METAL_LIB}" DEPENDS "${METAL_AIR}" COMMENT "Linking Metal library: ggml-metal-turbo.metallib" VERBATIM ) # Create target add_custom_target(${ARGS_TARGET} ALL DEPENDS "${METAL_LIB}" ) # Install metallib alongside the binary install(FILES "${METAL_LIB}" DESTINATION bin COMPONENT runtime ) # Also install raw .metal for runtime compilation fallback install(FILES "${METAL_SOURCE}" DESTINATION bin COMPONENT runtime ) message(STATUS "Metal shader compilation configured: ${ARGS_SOURCE} -> ${METAL_LIB}") endfunction()