From 79cbfcdfde82c8847551f67f4b951a410794a5c6 Mon Sep 17 00:00:00 2001 From: medmekk Date: Sat, 1 Nov 2025 10:11:08 +0000 Subject: [PATCH 01/10] add includes --- build2cmake/src/templates/metal/compile-metal.cmake | 12 +++++++++++- build2cmake/src/templates/metal/preamble.cmake | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/build2cmake/src/templates/metal/compile-metal.cmake b/build2cmake/src/templates/metal/compile-metal.cmake index d7c7a365..8a83bf1f 100644 --- a/build2cmake/src/templates/metal/compile-metal.cmake +++ b/build2cmake/src/templates/metal/compile-metal.cmake @@ -4,12 +4,22 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) find_program(METAL_COMPILER xcrun REQUIRED) # Set Metal compiler flags - set(METAL_FLAGS "-std=metal3.0" "-O2") + set(METAL_FLAGS "-std=metal3.2" "-O2") # Output directory for compiled metallib set(METALLIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/metallib") file(MAKE_DIRECTORY ${METALLIB_OUTPUT_DIR}) + set(METAL_INCLUDE_DIRS + "${CMAKE_SOURCE_DIR}/gptoss_kernels/source/include" + "${CMAKE_SOURCE_DIR}/gptoss_kernels/include" + "${CMAKE_SOURCE_DIR}/." + ) + + foreach(INC ${METAL_INCLUDE_DIRS}) + list(APPEND METAL_FLAGS "-I${INC}") + endforeach() + # Separate .metal files from .h files and compile .metal files to .air set(AIR_FILES) set(METAL_FILES) diff --git a/build2cmake/src/templates/metal/preamble.cmake b/build2cmake/src/templates/metal/preamble.cmake index c5cf4256..0f7b4f95 100644 --- a/build2cmake/src/templates/metal/preamble.cmake +++ b/build2cmake/src/templates/metal/preamble.cmake @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.26) -project({{name}} LANGUAGES CXX) +project({{name}} LANGUAGES CXX C OBJC OBJCXX) set(CMAKE_OSX_DEPLOYMENT_TARGET "15.0" CACHE STRING "Minimum macOS deployment version") From fad05ca766ed2594afc3e83e80ff0ba63a5a890e Mon Sep 17 00:00:00 2001 From: medmekk Date: Sat, 1 Nov 2025 11:00:55 +0000 Subject: [PATCH 02/10] xcrun => metal & metallib --- .../src/templates/metal/compile-metal.cmake | 139 +++++++++++------- 1 file changed, 89 insertions(+), 50 deletions(-) diff --git a/build2cmake/src/templates/metal/compile-metal.cmake b/build2cmake/src/templates/metal/compile-metal.cmake index 8a83bf1f..4ad8897f 100644 --- a/build2cmake/src/templates/metal/compile-metal.cmake +++ b/build2cmake/src/templates/metal/compile-metal.cmake @@ -1,30 +1,58 @@ # Metal shader compilation function function(compile_metal_shaders TARGET_NAME METAL_SOURCES) - # Find the Metal compiler - find_program(METAL_COMPILER xcrun REQUIRED) - - # Set Metal compiler flags + # Prefer Apple toolchain directly; fall back to /usr/bin/xcrun; last resort: any xcrun on PATH + find_program(METAL_TOOL metal + HINTS + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin + /Library/Developer/CommandLineTools/usr/bin + /usr/bin + NO_CACHE + ) + find_program(METALLIB_TOOL metallib + HINTS + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin + /Library/Developer/CommandLineTools/usr/bin + /usr/bin + NO_CACHE + ) + find_program(APPLE_XCRUN /usr/bin/xcrun NO_CACHE) + if(NOT METAL_TOOL OR NOT METALLIB_TOOL) + if(NOT APPLE_XCRUN) + # Last resort if absolutely necessary (may resolve to Nix wrapper) + find_program(ANY_XCRUN xcrun) + endif() + endif() + if(METAL_TOOL AND METALLIB_TOOL) + set(USE_DIRECT_TOOLS TRUE) + elseif(APPLE_XCRUN) + set(USE_XCRUN ${APPLE_XCRUN}) + elseif(ANY_XCRUN) + set(USE_XCRUN ${ANY_XCRUN}) + else() + message(FATAL_ERROR "No Apple Metal toolchain found (metal/metallib or /usr/bin/xcrun).") + endif() + + # Flags set(METAL_FLAGS "-std=metal3.2" "-O2") - - # Output directory for compiled metallib - set(METALLIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/metallib") - file(MAKE_DIRECTORY ${METALLIB_OUTPUT_DIR}) - + + # Include dirs for in shaders set(METAL_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/gptoss_kernels/source/include" "${CMAKE_SOURCE_DIR}/gptoss_kernels/include" "${CMAKE_SOURCE_DIR}/." ) - foreach(INC ${METAL_INCLUDE_DIRS}) list(APPEND METAL_FLAGS "-I${INC}") endforeach() - # Separate .metal files from .h files and compile .metal files to .air + # Output dir for metallib + set(METALLIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/metallib") + file(MAKE_DIRECTORY ${METALLIB_OUTPUT_DIR}) + + # Separate .metal files set(AIR_FILES) set(METAL_FILES) set(HEADER_FILES) - foreach(SOURCE_FILE ${METAL_SOURCES}) if(SOURCE_FILE MATCHES "\\.metal$") list(APPEND METAL_FILES ${SOURCE_FILE}) @@ -32,45 +60,64 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) list(APPEND HEADER_FILES ${SOURCE_FILE}) endif() endforeach() - + + # Compile .metal → .air foreach(METAL_FILE ${METAL_FILES}) get_filename_component(METAL_NAME ${METAL_FILE} NAME_WE) set(AIR_FILE "${CMAKE_BINARY_DIR}/${METAL_NAME}.air") - - # Include header files as dependencies - set(ALL_DEPENDENCIES ${CMAKE_CURRENT_SOURCE_DIR}/${METAL_FILE}) + + set(ALL_DEPENDENCIES ${CMAKE_SOURCE_DIR}/${METAL_FILE}) foreach(HEADER_FILE ${HEADER_FILES}) - list(APPEND ALL_DEPENDENCIES ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FILE}) + list(APPEND ALL_DEPENDENCIES ${CMAKE_SOURCE_DIR}/${HEADER_FILE}) endforeach() - - add_custom_command( - OUTPUT ${AIR_FILE} - COMMAND ${METAL_COMPILER} -sdk macosx metal ${METAL_FLAGS} - -c ${CMAKE_CURRENT_SOURCE_DIR}/${METAL_FILE} - -o ${AIR_FILE} - DEPENDS ${ALL_DEPENDENCIES} - COMMENT "Compiling Metal shader ${METAL_FILE} to ${AIR_FILE}" - VERBATIM - ) - + + if(USE_DIRECT_TOOLS) + add_custom_command( + OUTPUT ${AIR_FILE} + COMMAND ${METAL_TOOL} ${METAL_FLAGS} + -c ${CMAKE_SOURCE_DIR}/${METAL_FILE} + -o ${AIR_FILE} + DEPENDS ${ALL_DEPENDENCIES} + COMMENT "Compiling Metal shader ${METAL_FILE} to ${AIR_FILE}" + VERBATIM + ) + else() + add_custom_command( + OUTPUT ${AIR_FILE} + COMMAND ${USE_XCRUN} -sdk macosx metal ${METAL_FLAGS} + -c ${CMAKE_SOURCE_DIR}/${METAL_FILE} + -o ${AIR_FILE} + DEPENDS ${ALL_DEPENDENCIES} + COMMENT "Compiling Metal shader ${METAL_FILE} to ${AIR_FILE}" + VERBATIM + ) + endif() list(APPEND AIR_FILES ${AIR_FILE}) endforeach() - - # Link all .air files into a single .metallib + + # Link .air → .metallib set(METALLIB_FILE "${METALLIB_OUTPUT_DIR}/${TARGET_NAME}.metallib") - add_custom_command( - OUTPUT ${METALLIB_FILE} - COMMAND ${METAL_COMPILER} -sdk macosx metallib ${AIR_FILES} - -o ${METALLIB_FILE} - DEPENDS ${AIR_FILES} - COMMENT "Linking Metal library ${METALLIB_FILE}" - VERBATIM - ) - - # Generate C++ header with embedded metallib data + if(USE_DIRECT_TOOLS) + add_custom_command( + OUTPUT ${METALLIB_FILE} + COMMAND ${METALLIB_TOOL} ${AIR_FILES} -o ${METALLIB_FILE} + DEPENDS ${AIR_FILES} + COMMENT "Linking Metal library ${METALLIB_FILE}" + VERBATIM + ) + else() + add_custom_command( + OUTPUT ${METALLIB_FILE} + COMMAND ${USE_XCRUN} -sdk macosx metallib ${AIR_FILES} -o ${METALLIB_FILE} + DEPENDS ${AIR_FILES} + COMMENT "Linking Metal library ${METALLIB_FILE}" + VERBATIM + ) + endif() + + # Embed metallib set(METALLIB_HEADER "${CMAKE_BINARY_DIR}/${TARGET_NAME}_metallib.h") set(METALLIB_TO_HEADER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/cmake/metallib_to_header.py") - add_custom_command( OUTPUT ${METALLIB_HEADER} COMMAND ${Python_EXECUTABLE} ${METALLIB_TO_HEADER_SCRIPT} ${METALLIB_FILE} ${METALLIB_HEADER} ${TARGET_NAME} @@ -78,18 +125,10 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) COMMENT "Generating embedded Metal library header ${METALLIB_HEADER}" VERBATIM ) - - # Create a custom target for the metallib add_custom_target(${TARGET_NAME}_metallib ALL DEPENDS ${METALLIB_FILE} ${METALLIB_HEADER}) - - # Add dependency to main target add_dependencies(${TARGET_NAME} ${TARGET_NAME}_metallib) - - # Add the generated header to include directories target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_BINARY_DIR}) - - # Pass the metallib header and namespace as compile definitions - target_compile_definitions(${TARGET_NAME} PRIVATE + target_compile_definitions(${TARGET_NAME} PRIVATE EMBEDDED_METALLIB_HEADER="${TARGET_NAME}_metallib.h" EMBEDDED_METALLIB_NAMESPACE=${TARGET_NAME}_metal ) From ac16edd5da112d0a085b60c353fd9c34d5c485ab Mon Sep 17 00:00:00 2001 From: medmekk Date: Sat, 1 Nov 2025 11:10:24 +0000 Subject: [PATCH 03/10] revert --- .../src/templates/metal/compile-metal.cmake | 139 +++++++----------- 1 file changed, 50 insertions(+), 89 deletions(-) diff --git a/build2cmake/src/templates/metal/compile-metal.cmake b/build2cmake/src/templates/metal/compile-metal.cmake index 4ad8897f..8a83bf1f 100644 --- a/build2cmake/src/templates/metal/compile-metal.cmake +++ b/build2cmake/src/templates/metal/compile-metal.cmake @@ -1,58 +1,30 @@ # Metal shader compilation function function(compile_metal_shaders TARGET_NAME METAL_SOURCES) - # Prefer Apple toolchain directly; fall back to /usr/bin/xcrun; last resort: any xcrun on PATH - find_program(METAL_TOOL metal - HINTS - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin - /Library/Developer/CommandLineTools/usr/bin - /usr/bin - NO_CACHE - ) - find_program(METALLIB_TOOL metallib - HINTS - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin - /Library/Developer/CommandLineTools/usr/bin - /usr/bin - NO_CACHE - ) - find_program(APPLE_XCRUN /usr/bin/xcrun NO_CACHE) - if(NOT METAL_TOOL OR NOT METALLIB_TOOL) - if(NOT APPLE_XCRUN) - # Last resort if absolutely necessary (may resolve to Nix wrapper) - find_program(ANY_XCRUN xcrun) - endif() - endif() - if(METAL_TOOL AND METALLIB_TOOL) - set(USE_DIRECT_TOOLS TRUE) - elseif(APPLE_XCRUN) - set(USE_XCRUN ${APPLE_XCRUN}) - elseif(ANY_XCRUN) - set(USE_XCRUN ${ANY_XCRUN}) - else() - message(FATAL_ERROR "No Apple Metal toolchain found (metal/metallib or /usr/bin/xcrun).") - endif() - - # Flags + # Find the Metal compiler + find_program(METAL_COMPILER xcrun REQUIRED) + + # Set Metal compiler flags set(METAL_FLAGS "-std=metal3.2" "-O2") - - # Include dirs for in shaders + + # Output directory for compiled metallib + set(METALLIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/metallib") + file(MAKE_DIRECTORY ${METALLIB_OUTPUT_DIR}) + set(METAL_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/gptoss_kernels/source/include" "${CMAKE_SOURCE_DIR}/gptoss_kernels/include" "${CMAKE_SOURCE_DIR}/." ) + foreach(INC ${METAL_INCLUDE_DIRS}) list(APPEND METAL_FLAGS "-I${INC}") endforeach() - # Output dir for metallib - set(METALLIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/metallib") - file(MAKE_DIRECTORY ${METALLIB_OUTPUT_DIR}) - - # Separate .metal files + # Separate .metal files from .h files and compile .metal files to .air set(AIR_FILES) set(METAL_FILES) set(HEADER_FILES) + foreach(SOURCE_FILE ${METAL_SOURCES}) if(SOURCE_FILE MATCHES "\\.metal$") list(APPEND METAL_FILES ${SOURCE_FILE}) @@ -60,64 +32,45 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) list(APPEND HEADER_FILES ${SOURCE_FILE}) endif() endforeach() - - # Compile .metal → .air + foreach(METAL_FILE ${METAL_FILES}) get_filename_component(METAL_NAME ${METAL_FILE} NAME_WE) set(AIR_FILE "${CMAKE_BINARY_DIR}/${METAL_NAME}.air") - - set(ALL_DEPENDENCIES ${CMAKE_SOURCE_DIR}/${METAL_FILE}) + + # Include header files as dependencies + set(ALL_DEPENDENCIES ${CMAKE_CURRENT_SOURCE_DIR}/${METAL_FILE}) foreach(HEADER_FILE ${HEADER_FILES}) - list(APPEND ALL_DEPENDENCIES ${CMAKE_SOURCE_DIR}/${HEADER_FILE}) + list(APPEND ALL_DEPENDENCIES ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FILE}) endforeach() - - if(USE_DIRECT_TOOLS) - add_custom_command( - OUTPUT ${AIR_FILE} - COMMAND ${METAL_TOOL} ${METAL_FLAGS} - -c ${CMAKE_SOURCE_DIR}/${METAL_FILE} - -o ${AIR_FILE} - DEPENDS ${ALL_DEPENDENCIES} - COMMENT "Compiling Metal shader ${METAL_FILE} to ${AIR_FILE}" - VERBATIM - ) - else() - add_custom_command( - OUTPUT ${AIR_FILE} - COMMAND ${USE_XCRUN} -sdk macosx metal ${METAL_FLAGS} - -c ${CMAKE_SOURCE_DIR}/${METAL_FILE} - -o ${AIR_FILE} - DEPENDS ${ALL_DEPENDENCIES} - COMMENT "Compiling Metal shader ${METAL_FILE} to ${AIR_FILE}" - VERBATIM - ) - endif() - list(APPEND AIR_FILES ${AIR_FILE}) - endforeach() - - # Link .air → .metallib - set(METALLIB_FILE "${METALLIB_OUTPUT_DIR}/${TARGET_NAME}.metallib") - if(USE_DIRECT_TOOLS) - add_custom_command( - OUTPUT ${METALLIB_FILE} - COMMAND ${METALLIB_TOOL} ${AIR_FILES} -o ${METALLIB_FILE} - DEPENDS ${AIR_FILES} - COMMENT "Linking Metal library ${METALLIB_FILE}" - VERBATIM - ) - else() + add_custom_command( - OUTPUT ${METALLIB_FILE} - COMMAND ${USE_XCRUN} -sdk macosx metallib ${AIR_FILES} -o ${METALLIB_FILE} - DEPENDS ${AIR_FILES} - COMMENT "Linking Metal library ${METALLIB_FILE}" + OUTPUT ${AIR_FILE} + COMMAND ${METAL_COMPILER} -sdk macosx metal ${METAL_FLAGS} + -c ${CMAKE_CURRENT_SOURCE_DIR}/${METAL_FILE} + -o ${AIR_FILE} + DEPENDS ${ALL_DEPENDENCIES} + COMMENT "Compiling Metal shader ${METAL_FILE} to ${AIR_FILE}" VERBATIM ) - endif() - - # Embed metallib + + list(APPEND AIR_FILES ${AIR_FILE}) + endforeach() + + # Link all .air files into a single .metallib + set(METALLIB_FILE "${METALLIB_OUTPUT_DIR}/${TARGET_NAME}.metallib") + add_custom_command( + OUTPUT ${METALLIB_FILE} + COMMAND ${METAL_COMPILER} -sdk macosx metallib ${AIR_FILES} + -o ${METALLIB_FILE} + DEPENDS ${AIR_FILES} + COMMENT "Linking Metal library ${METALLIB_FILE}" + VERBATIM + ) + + # Generate C++ header with embedded metallib data set(METALLIB_HEADER "${CMAKE_BINARY_DIR}/${TARGET_NAME}_metallib.h") set(METALLIB_TO_HEADER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/cmake/metallib_to_header.py") + add_custom_command( OUTPUT ${METALLIB_HEADER} COMMAND ${Python_EXECUTABLE} ${METALLIB_TO_HEADER_SCRIPT} ${METALLIB_FILE} ${METALLIB_HEADER} ${TARGET_NAME} @@ -125,10 +78,18 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) COMMENT "Generating embedded Metal library header ${METALLIB_HEADER}" VERBATIM ) + + # Create a custom target for the metallib add_custom_target(${TARGET_NAME}_metallib ALL DEPENDS ${METALLIB_FILE} ${METALLIB_HEADER}) + + # Add dependency to main target add_dependencies(${TARGET_NAME} ${TARGET_NAME}_metallib) + + # Add the generated header to include directories target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_BINARY_DIR}) - target_compile_definitions(${TARGET_NAME} PRIVATE + + # Pass the metallib header and namespace as compile definitions + target_compile_definitions(${TARGET_NAME} PRIVATE EMBEDDED_METALLIB_HEADER="${TARGET_NAME}_metallib.h" EMBEDDED_METALLIB_NAMESPACE=${TARGET_NAME}_metal ) From b6d1326858e853f433f29b592925a36b650c6675 Mon Sep 17 00:00:00 2001 From: medmekk Date: Sat, 1 Nov 2025 11:34:31 +0000 Subject: [PATCH 04/10] force developer dir --- .../src/templates/metal/compile-metal.cmake | 82 ++++++++++++------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/build2cmake/src/templates/metal/compile-metal.cmake b/build2cmake/src/templates/metal/compile-metal.cmake index 8a83bf1f..8774e4a6 100644 --- a/build2cmake/src/templates/metal/compile-metal.cmake +++ b/build2cmake/src/templates/metal/compile-metal.cmake @@ -1,30 +1,63 @@ # Metal shader compilation function function(compile_metal_shaders TARGET_NAME METAL_SOURCES) - # Find the Metal compiler + # Find the Metal launcher (we'll force DEVELOPER_DIR per call) find_program(METAL_COMPILER xcrun REQUIRED) - - # Set Metal compiler flags + + # --- Auto-detect DEVELOPER_DIR --- + set(METAL_DEVELOPER_DIR "") + + # 1) Prefer xcode-select + execute_process( + COMMAND /usr/bin/xcode-select -p + OUTPUT_VARIABLE _XCODE_DEV + RESULT_VARIABLE _XCODE_RC + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if(_XCODE_RC EQUAL 0 AND EXISTS "${_XCODE_DEV}") + set(METAL_DEVELOPER_DIR "${_XCODE_DEV}") + endif() + + # 2) If it points to CommandLineTools or is empty, try Xcode apps (pick newest) + if(NOT METAL_DEVELOPER_DIR OR METAL_DEVELOPER_DIR MATCHES "CommandLineTools") + file(GLOB _XCODE_CANDIDATES "/Applications/Xcode*.app/Contents/Developer") + list(SORT _XCODE_CANDIDATES DESCENDING) + foreach(_cand ${_XCODE_CANDIDATES}) + if(EXISTS "${_cand}/Toolchains/XcodeDefault.xctoolchain/usr/bin/metal") + set(METAL_DEVELOPER_DIR "${_cand}") + break() + endif() + endforeach() + endif() + + # 3) Fallback to the standard Xcode path + if(NOT METAL_DEVELOPER_DIR) + set(METAL_DEVELOPER_DIR "/Applications/Xcode.app/Contents/Developer") + endif() + + message(STATUS "Detected DEVELOPER_DIR for Metal: ${METAL_DEVELOPER_DIR}") + + # Metal flags set(METAL_FLAGS "-std=metal3.2" "-O2") - + # Output directory for compiled metallib set(METALLIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/metallib") file(MAKE_DIRECTORY ${METALLIB_OUTPUT_DIR}) - + + # Include dirs for shaders set(METAL_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/gptoss_kernels/source/include" "${CMAKE_SOURCE_DIR}/gptoss_kernels/include" "${CMAKE_SOURCE_DIR}/." ) - foreach(INC ${METAL_INCLUDE_DIRS}) list(APPEND METAL_FLAGS "-I${INC}") endforeach() - # Separate .metal files from .h files and compile .metal files to .air + # Separate .metal files set(AIR_FILES) set(METAL_FILES) set(HEADER_FILES) - foreach(SOURCE_FILE ${METAL_SOURCES}) if(SOURCE_FILE MATCHES "\\.metal$") list(APPEND METAL_FILES ${SOURCE_FILE}) @@ -32,45 +65,44 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) list(APPEND HEADER_FILES ${SOURCE_FILE}) endif() endforeach() - + foreach(METAL_FILE ${METAL_FILES}) get_filename_component(METAL_NAME ${METAL_FILE} NAME_WE) set(AIR_FILE "${CMAKE_BINARY_DIR}/${METAL_NAME}.air") - - # Include header files as dependencies + set(ALL_DEPENDENCIES ${CMAKE_CURRENT_SOURCE_DIR}/${METAL_FILE}) foreach(HEADER_FILE ${HEADER_FILES}) list(APPEND ALL_DEPENDENCIES ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FILE}) endforeach() - + add_custom_command( OUTPUT ${AIR_FILE} - COMMAND ${METAL_COMPILER} -sdk macosx metal ${METAL_FLAGS} + COMMAND ${CMAKE_COMMAND} -E env DEVELOPER_DIR=${METAL_DEVELOPER_DIR} + ${METAL_COMPILER} -sdk macosx metal ${METAL_FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/${METAL_FILE} -o ${AIR_FILE} DEPENDS ${ALL_DEPENDENCIES} COMMENT "Compiling Metal shader ${METAL_FILE} to ${AIR_FILE}" VERBATIM ) - list(APPEND AIR_FILES ${AIR_FILE}) endforeach() - - # Link all .air files into a single .metallib + + # Link .air → .metallib set(METALLIB_FILE "${METALLIB_OUTPUT_DIR}/${TARGET_NAME}.metallib") add_custom_command( OUTPUT ${METALLIB_FILE} - COMMAND ${METAL_COMPILER} -sdk macosx metallib ${AIR_FILES} + COMMAND ${CMAKE_COMMAND} -E env DEVELOPER_DIR=${METAL_DEVELOPER_DIR} + ${METAL_COMPILER} -sdk macosx metallib ${AIR_FILES} -o ${METALLIB_FILE} DEPENDS ${AIR_FILES} COMMENT "Linking Metal library ${METALLIB_FILE}" VERBATIM ) - - # Generate C++ header with embedded metallib data + + # Embed metallib header (unchanged) set(METALLIB_HEADER "${CMAKE_BINARY_DIR}/${TARGET_NAME}_metallib.h") set(METALLIB_TO_HEADER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/cmake/metallib_to_header.py") - add_custom_command( OUTPUT ${METALLIB_HEADER} COMMAND ${Python_EXECUTABLE} ${METALLIB_TO_HEADER_SCRIPT} ${METALLIB_FILE} ${METALLIB_HEADER} ${TARGET_NAME} @@ -78,18 +110,10 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) COMMENT "Generating embedded Metal library header ${METALLIB_HEADER}" VERBATIM ) - - # Create a custom target for the metallib add_custom_target(${TARGET_NAME}_metallib ALL DEPENDS ${METALLIB_FILE} ${METALLIB_HEADER}) - - # Add dependency to main target add_dependencies(${TARGET_NAME} ${TARGET_NAME}_metallib) - - # Add the generated header to include directories target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_BINARY_DIR}) - - # Pass the metallib header and namespace as compile definitions - target_compile_definitions(${TARGET_NAME} PRIVATE + target_compile_definitions(${TARGET_NAME} PRIVATE EMBEDDED_METALLIB_HEADER="${TARGET_NAME}_metallib.h" EMBEDDED_METALLIB_NAMESPACE=${TARGET_NAME}_metal ) From 916d61f34f766d5a1511cca519b93e6c41e6dbb6 Mon Sep 17 00:00:00 2001 From: medmekk Date: Sat, 1 Nov 2025 11:40:47 +0000 Subject: [PATCH 05/10] change xcode-select --- build2cmake/src/templates/metal/compile-metal.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build2cmake/src/templates/metal/compile-metal.cmake b/build2cmake/src/templates/metal/compile-metal.cmake index 8774e4a6..ff787421 100644 --- a/build2cmake/src/templates/metal/compile-metal.cmake +++ b/build2cmake/src/templates/metal/compile-metal.cmake @@ -2,13 +2,13 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) # Find the Metal launcher (we'll force DEVELOPER_DIR per call) find_program(METAL_COMPILER xcrun REQUIRED) - + find_program(XCODE_SELECT xcode-select REQUIRED) # --- Auto-detect DEVELOPER_DIR --- set(METAL_DEVELOPER_DIR "") # 1) Prefer xcode-select execute_process( - COMMAND /usr/bin/xcode-select -p + COMMAND ${XCODE_SELECT} -p OUTPUT_VARIABLE _XCODE_DEV RESULT_VARIABLE _XCODE_RC OUTPUT_STRIP_TRAILING_WHITESPACE From 8bc05e9d6f2ded0d6f17f115b10ac7237fbaa640 Mon Sep 17 00:00:00 2001 From: medmekk Date: Sat, 1 Nov 2025 11:42:17 +0000 Subject: [PATCH 06/10] revert --- build2cmake/src/templates/metal/compile-metal.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build2cmake/src/templates/metal/compile-metal.cmake b/build2cmake/src/templates/metal/compile-metal.cmake index ff787421..8774e4a6 100644 --- a/build2cmake/src/templates/metal/compile-metal.cmake +++ b/build2cmake/src/templates/metal/compile-metal.cmake @@ -2,13 +2,13 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) # Find the Metal launcher (we'll force DEVELOPER_DIR per call) find_program(METAL_COMPILER xcrun REQUIRED) - find_program(XCODE_SELECT xcode-select REQUIRED) + # --- Auto-detect DEVELOPER_DIR --- set(METAL_DEVELOPER_DIR "") # 1) Prefer xcode-select execute_process( - COMMAND ${XCODE_SELECT} -p + COMMAND /usr/bin/xcode-select -p OUTPUT_VARIABLE _XCODE_DEV RESULT_VARIABLE _XCODE_RC OUTPUT_STRIP_TRAILING_WHITESPACE From 5e32fcc99f565f0b5bf0cd1e3a29250f9d1a8828 Mon Sep 17 00:00:00 2001 From: medmekk Date: Sat, 1 Nov 2025 11:44:37 +0000 Subject: [PATCH 07/10] fix order --- build2cmake/src/templates/metal/compile-metal.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build2cmake/src/templates/metal/compile-metal.cmake b/build2cmake/src/templates/metal/compile-metal.cmake index 8774e4a6..eda220ab 100644 --- a/build2cmake/src/templates/metal/compile-metal.cmake +++ b/build2cmake/src/templates/metal/compile-metal.cmake @@ -21,7 +21,8 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) # 2) If it points to CommandLineTools or is empty, try Xcode apps (pick newest) if(NOT METAL_DEVELOPER_DIR OR METAL_DEVELOPER_DIR MATCHES "CommandLineTools") file(GLOB _XCODE_CANDIDATES "/Applications/Xcode*.app/Contents/Developer") - list(SORT _XCODE_CANDIDATES DESCENDING) + list(SORT _XCODE_CANDIDATES) + list(REVERSE _XCODE_CANDIDATES) foreach(_cand ${_XCODE_CANDIDATES}) if(EXISTS "${_cand}/Toolchains/XcodeDefault.xctoolchain/usr/bin/metal") set(METAL_DEVELOPER_DIR "${_cand}") From 25ea190b1dca356f8bec2ec7cb92507b11ca62a1 Mon Sep 17 00:00:00 2001 From: medmekk Date: Sat, 1 Nov 2025 12:00:55 +0000 Subject: [PATCH 08/10] rm developer_dir --- .../src/templates/metal/compile-metal.cmake | 83 +++++++------------ 1 file changed, 29 insertions(+), 54 deletions(-) diff --git a/build2cmake/src/templates/metal/compile-metal.cmake b/build2cmake/src/templates/metal/compile-metal.cmake index eda220ab..8a83bf1f 100644 --- a/build2cmake/src/templates/metal/compile-metal.cmake +++ b/build2cmake/src/templates/metal/compile-metal.cmake @@ -1,64 +1,30 @@ # Metal shader compilation function function(compile_metal_shaders TARGET_NAME METAL_SOURCES) - # Find the Metal launcher (we'll force DEVELOPER_DIR per call) + # Find the Metal compiler find_program(METAL_COMPILER xcrun REQUIRED) - - # --- Auto-detect DEVELOPER_DIR --- - set(METAL_DEVELOPER_DIR "") - - # 1) Prefer xcode-select - execute_process( - COMMAND /usr/bin/xcode-select -p - OUTPUT_VARIABLE _XCODE_DEV - RESULT_VARIABLE _XCODE_RC - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - ) - if(_XCODE_RC EQUAL 0 AND EXISTS "${_XCODE_DEV}") - set(METAL_DEVELOPER_DIR "${_XCODE_DEV}") - endif() - - # 2) If it points to CommandLineTools or is empty, try Xcode apps (pick newest) - if(NOT METAL_DEVELOPER_DIR OR METAL_DEVELOPER_DIR MATCHES "CommandLineTools") - file(GLOB _XCODE_CANDIDATES "/Applications/Xcode*.app/Contents/Developer") - list(SORT _XCODE_CANDIDATES) - list(REVERSE _XCODE_CANDIDATES) - foreach(_cand ${_XCODE_CANDIDATES}) - if(EXISTS "${_cand}/Toolchains/XcodeDefault.xctoolchain/usr/bin/metal") - set(METAL_DEVELOPER_DIR "${_cand}") - break() - endif() - endforeach() - endif() - - # 3) Fallback to the standard Xcode path - if(NOT METAL_DEVELOPER_DIR) - set(METAL_DEVELOPER_DIR "/Applications/Xcode.app/Contents/Developer") - endif() - - message(STATUS "Detected DEVELOPER_DIR for Metal: ${METAL_DEVELOPER_DIR}") - - # Metal flags + + # Set Metal compiler flags set(METAL_FLAGS "-std=metal3.2" "-O2") - + # Output directory for compiled metallib set(METALLIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/metallib") file(MAKE_DIRECTORY ${METALLIB_OUTPUT_DIR}) - - # Include dirs for shaders + set(METAL_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/gptoss_kernels/source/include" "${CMAKE_SOURCE_DIR}/gptoss_kernels/include" "${CMAKE_SOURCE_DIR}/." ) + foreach(INC ${METAL_INCLUDE_DIRS}) list(APPEND METAL_FLAGS "-I${INC}") endforeach() - # Separate .metal files + # Separate .metal files from .h files and compile .metal files to .air set(AIR_FILES) set(METAL_FILES) set(HEADER_FILES) + foreach(SOURCE_FILE ${METAL_SOURCES}) if(SOURCE_FILE MATCHES "\\.metal$") list(APPEND METAL_FILES ${SOURCE_FILE}) @@ -66,44 +32,45 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) list(APPEND HEADER_FILES ${SOURCE_FILE}) endif() endforeach() - + foreach(METAL_FILE ${METAL_FILES}) get_filename_component(METAL_NAME ${METAL_FILE} NAME_WE) set(AIR_FILE "${CMAKE_BINARY_DIR}/${METAL_NAME}.air") - + + # Include header files as dependencies set(ALL_DEPENDENCIES ${CMAKE_CURRENT_SOURCE_DIR}/${METAL_FILE}) foreach(HEADER_FILE ${HEADER_FILES}) list(APPEND ALL_DEPENDENCIES ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FILE}) endforeach() - + add_custom_command( OUTPUT ${AIR_FILE} - COMMAND ${CMAKE_COMMAND} -E env DEVELOPER_DIR=${METAL_DEVELOPER_DIR} - ${METAL_COMPILER} -sdk macosx metal ${METAL_FLAGS} + COMMAND ${METAL_COMPILER} -sdk macosx metal ${METAL_FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/${METAL_FILE} -o ${AIR_FILE} DEPENDS ${ALL_DEPENDENCIES} COMMENT "Compiling Metal shader ${METAL_FILE} to ${AIR_FILE}" VERBATIM ) + list(APPEND AIR_FILES ${AIR_FILE}) endforeach() - - # Link .air → .metallib + + # Link all .air files into a single .metallib set(METALLIB_FILE "${METALLIB_OUTPUT_DIR}/${TARGET_NAME}.metallib") add_custom_command( OUTPUT ${METALLIB_FILE} - COMMAND ${CMAKE_COMMAND} -E env DEVELOPER_DIR=${METAL_DEVELOPER_DIR} - ${METAL_COMPILER} -sdk macosx metallib ${AIR_FILES} + COMMAND ${METAL_COMPILER} -sdk macosx metallib ${AIR_FILES} -o ${METALLIB_FILE} DEPENDS ${AIR_FILES} COMMENT "Linking Metal library ${METALLIB_FILE}" VERBATIM ) - - # Embed metallib header (unchanged) + + # Generate C++ header with embedded metallib data set(METALLIB_HEADER "${CMAKE_BINARY_DIR}/${TARGET_NAME}_metallib.h") set(METALLIB_TO_HEADER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/cmake/metallib_to_header.py") + add_custom_command( OUTPUT ${METALLIB_HEADER} COMMAND ${Python_EXECUTABLE} ${METALLIB_TO_HEADER_SCRIPT} ${METALLIB_FILE} ${METALLIB_HEADER} ${TARGET_NAME} @@ -111,10 +78,18 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) COMMENT "Generating embedded Metal library header ${METALLIB_HEADER}" VERBATIM ) + + # Create a custom target for the metallib add_custom_target(${TARGET_NAME}_metallib ALL DEPENDS ${METALLIB_FILE} ${METALLIB_HEADER}) + + # Add dependency to main target add_dependencies(${TARGET_NAME} ${TARGET_NAME}_metallib) + + # Add the generated header to include directories target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_BINARY_DIR}) - target_compile_definitions(${TARGET_NAME} PRIVATE + + # Pass the metallib header and namespace as compile definitions + target_compile_definitions(${TARGET_NAME} PRIVATE EMBEDDED_METALLIB_HEADER="${TARGET_NAME}_metallib.h" EMBEDDED_METALLIB_NAMESPACE=${TARGET_NAME}_metal ) From b5dd401726a6b6023785e688eaf7796796c6cda0 Mon Sep 17 00:00:00 2001 From: medmekk Date: Sat, 1 Nov 2025 16:53:45 +0000 Subject: [PATCH 09/10] rm includes --- build2cmake/src/templates/metal/compile-metal.cmake | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/build2cmake/src/templates/metal/compile-metal.cmake b/build2cmake/src/templates/metal/compile-metal.cmake index 8a83bf1f..43b2eb8f 100644 --- a/build2cmake/src/templates/metal/compile-metal.cmake +++ b/build2cmake/src/templates/metal/compile-metal.cmake @@ -9,16 +9,6 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) # Output directory for compiled metallib set(METALLIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/metallib") file(MAKE_DIRECTORY ${METALLIB_OUTPUT_DIR}) - - set(METAL_INCLUDE_DIRS - "${CMAKE_SOURCE_DIR}/gptoss_kernels/source/include" - "${CMAKE_SOURCE_DIR}/gptoss_kernels/include" - "${CMAKE_SOURCE_DIR}/." - ) - - foreach(INC ${METAL_INCLUDE_DIRS}) - list(APPEND METAL_FLAGS "-I${INC}") - endforeach() # Separate .metal files from .h files and compile .metal files to .air set(AIR_FILES) From 64417e893b6aae48edf47a788a5560116708de08 Mon Sep 17 00:00:00 2001 From: medmekk Date: Sat, 1 Nov 2025 17:11:05 +0000 Subject: [PATCH 10/10] adding includes --- build2cmake/src/templates/metal/compile-metal.cmake | 6 +++++- build2cmake/src/templates/metal/kernel.cmake | 7 +++++++ build2cmake/src/templates/metal/torch-extension.cmake | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/build2cmake/src/templates/metal/compile-metal.cmake b/build2cmake/src/templates/metal/compile-metal.cmake index 43b2eb8f..f82874f0 100644 --- a/build2cmake/src/templates/metal/compile-metal.cmake +++ b/build2cmake/src/templates/metal/compile-metal.cmake @@ -1,5 +1,5 @@ # Metal shader compilation function -function(compile_metal_shaders TARGET_NAME METAL_SOURCES) +function(compile_metal_shaders TARGET_NAME METAL_SOURCES EXTRA_INCLUDE_DIRS) # Find the Metal compiler find_program(METAL_COMPILER xcrun REQUIRED) @@ -10,6 +10,10 @@ function(compile_metal_shaders TARGET_NAME METAL_SOURCES) set(METALLIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/metallib") file(MAKE_DIRECTORY ${METALLIB_OUTPUT_DIR}) + foreach(INC ${EXTRA_INCLUDE_DIRS}) + list(APPEND METAL_FLAGS "-I${INC}") + endforeach() + # Separate .metal files from .h files and compile .metal files to .air set(AIR_FILES) set(METAL_FILES) diff --git a/build2cmake/src/templates/metal/kernel.cmake b/build2cmake/src/templates/metal/kernel.cmake index 0ff280b9..ae399ba6 100644 --- a/build2cmake/src/templates/metal/kernel.cmake +++ b/build2cmake/src/templates/metal/kernel.cmake @@ -39,3 +39,10 @@ list(APPEND SRC {{'"${' + kernel_name + '_CPP_SRC}"'}}) if({{kernel_name}}_METAL_SRC) list(APPEND ALL_METAL_SOURCES {{'"${' + kernel_name + '_METAL_SRC}"'}}) endif() + +{% if includes %} +# Keep the includes directory for the Metal sources +if({{kernel_name}}_METAL_SRC) + list(APPEND METAL_INCLUDE_DIRS {{ includes }}) +endif() +{% endif %} \ No newline at end of file diff --git a/build2cmake/src/templates/metal/torch-extension.cmake b/build2cmake/src/templates/metal/torch-extension.cmake index 3f81df03..9e9fa7aa 100644 --- a/build2cmake/src/templates/metal/torch-extension.cmake +++ b/build2cmake/src/templates/metal/torch-extension.cmake @@ -13,5 +13,5 @@ define_gpu_extension_target( # Compile Metal shaders if any were found if(ALL_METAL_SOURCES) - compile_metal_shaders({{ ops_name }} "${ALL_METAL_SOURCES}") + compile_metal_shaders({{ ops_name }} "${ALL_METAL_SOURCES}" "${METAL_INCLUDE_DIRS}") endif() \ No newline at end of file