From 7cd66a3a6d897e292ec5612220569ddd07d3f1b1 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Tue, 6 Aug 2024 00:34:53 -0700 Subject: [PATCH] Allow building macOS client with Makefiles This removes the strict requirement to use the Xcode project generator, but still requires the Xcode build tools (and specifically the Metal compiler) to be installed. I expect that our official stance will always be that the Xcode project generator is the recommended and supported way to do macOS builds, but any day I don't have to launch Xcode is a good day. --- CMakeLists.txt | 4 +- Sources/Plasma/Apps/plClient/CMakeLists.txt | 16 ++-- .../FeatureLib/pfMetalPipeline/CMakeLists.txt | 73 ++++++++-------- cmake/CMakeDetermineMetalCompiler.cmake | 85 +++++++++++++++++++ cmake/CMakeMetalCompiler.cmake.in | 27 ++++++ cmake/CMakeMetalInformation.cmake | 85 +++++++++++++++++++ cmake/CMakeTestMetalCompiler.cmake | 78 +++++++++++++++++ cmake/Dependencies.cmake | 2 + cmake/MetalShaderSupport.cmake | 52 ++++++++++++ 9 files changed, 373 insertions(+), 49 deletions(-) create mode 100644 cmake/CMakeDetermineMetalCompiler.cmake create mode 100644 cmake/CMakeMetalCompiler.cmake.in create mode 100644 cmake/CMakeMetalInformation.cmake create mode 100644 cmake/CMakeTestMetalCompiler.cmake create mode 100644 cmake/MetalShaderSupport.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 44d0a471b5..82f3b2d393 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,8 +17,9 @@ if(POLICY CMP0127) endif() include(CMakeDependentOption) -include(FeatureSummary) include(Dependencies) +include(FeatureSummary) +include(MetalShaderSupport) include(VcpkgToolchain) project(Plasma) @@ -164,6 +165,7 @@ endif(PLASMA_PIPELINE_GL) if(PLASMA_PIPELINE_METAL) add_definitions(-DPLASMA_PIPELINE_METAL) + enable_language(Metal) endif(PLASMA_PIPELINE_METAL) # Allow us to disable certain parts of the build diff --git a/Sources/Plasma/Apps/plClient/CMakeLists.txt b/Sources/Plasma/Apps/plClient/CMakeLists.txt index 88508fd3f5..ed065b6251 100644 --- a/Sources/Plasma/Apps/plClient/CMakeLists.txt +++ b/Sources/Plasma/Apps/plClient/CMakeLists.txt @@ -116,10 +116,6 @@ elseif(APPLE) Mac-Cocoa/PLSLoginWindowController.xib Mac-Cocoa/PLSPatcherWindowController.xib ) - list(APPEND plClient_SHADERTARGETS - pfMetalPipelineShadersMSL21 - pfMetalPipelineShadersMSL23 - ) else() list(APPEND plClient_SOURCES main.cpp @@ -159,17 +155,12 @@ if(APPLE) XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "YES" XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES" XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER org.Huru.UruExplorer - XCODE_EMBED_RESOURCES "${plClient_SHADERTARGETS}" ) target_compile_options(plClient PRIVATE -fobjc-arc) target_sources(plClient PRIVATE Mac-Cocoa/Assets.xcassets) set_source_files_properties(Mac-Cocoa/Assets.xcassets ${RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) - - if(${CMAKE_VERSION} VERSION_LESS 3.28) - message(FATAL_ERROR "Cannot build Mac client without CMake 3.28") - endif() if(PLASMA_APPLE_DEVELOPMENT_TEAM_ID) set_target_properties(plClient PROPERTIES @@ -179,6 +170,13 @@ if(APPLE) endif() endif() +if(PLASMA_PIPELINE_METAL) + target_embed_metal_shader_libraries(plClient + pfMetalPipelineShadersMSL21 + pfMetalPipelineShadersMSL23 + ) +endif() + if(PLASMA_BUILD_RESOURCE_DAT) target_sources(plClient PRIVATE ${external_SCRIPTS} ${external_SOURCES} ${external_DAT}) endif() diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/CMakeLists.txt b/Sources/Plasma/FeatureLib/pfMetalPipeline/CMakeLists.txt index 53f4561f18..cac00a4ce5 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/CMakeLists.txt +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/CMakeLists.txt @@ -44,10 +44,27 @@ set(pfMetalPipeline_HEADERS pfMetalPipelineCreatable.h ) +set(pfMetalPipeline_SHADERS + ShaderSrc/FixedPipelineShaders.metal + ShaderSrc/PlateShaders.metal + ShaderSrc/BiasNormals.metal + ShaderSrc/CompCosines.metal + ShaderSrc/WaveSet7.metal + ShaderSrc/Grass.metal + ShaderSrc/WaveDecEnv.metal + ShaderSrc/Avatar.metal + ShaderSrc/WaveDec1Lay_7.metal + ShaderSrc/WaveRip.metal + ShaderSrc/Clear.metal + ShaderSrc/GammaCorrection.metal + ShaderSrc/TextFontShader.metal +) + plasma_library(pfMetalPipeline FOLDER FeatureLib SOURCES ${pfMetalPipeline_SOURCES} ${pfMetalPipeline_HEADERS} ) + target_link_libraries(pfMetalPipeline PUBLIC CoreLib @@ -73,49 +90,27 @@ source_group("Source Files" FILES ${pfMetalPipeline_SOURCES}) source_group("Header Files" FILES ${pfMetalPipeline_HEADERS}) # All supported Macs for Plasma/Metal support MSL 2.1 -add_library(pfMetalPipelineShadersMSL21 MODULE) -# Build a 2.3 varient for macOS 11 and/or Apple Silicon specific features -add_library(pfMetalPipelineShadersMSL23 MODULE) - -set(pfMetalPipeline_SHADERS - ShaderSrc/FixedPipelineShaders.metal - ShaderSrc/PlateShaders.metal - ShaderSrc/BiasNormals.metal - ShaderSrc/CompCosines.metal - ShaderSrc/WaveSet7.metal - ShaderSrc/Grass.metal - ShaderSrc/WaveDecEnv.metal - ShaderSrc/Avatar.metal - ShaderSrc/WaveDec1Lay_7.metal - ShaderSrc/WaveRip.metal - ShaderSrc/Clear.metal - ShaderSrc/GammaCorrection.metal - ShaderSrc/TextFontShader.metal +add_metal_shader_library(pfMetalPipelineShadersMSL21 + STANDARD macos-metal2.1 + ${pfMetalPipeline_SHADERS} +) +target_include_directories(pfMetalPipelineShadersMSL21 + PRIVATE + $ ) set_target_properties(pfMetalPipelineShadersMSL21 PROPERTIES - XCODE_PRODUCT_TYPE com.apple.product-type.metal-library - XCODE_ATTRIBUTE_MTL_LANGUAGE_REVISION Metal21 - XCODE_ATTRIBUTE_MTL_HEADER_SEARCH_PATHS "${Plasma_SOURCE_DIR}/Sources/Plasma/NucleusLib/inc/" - SUFFIX ".metallib" - PREFIX "" - XCODE_ATTRIBUTE_MTL_FAST_MATH "YES" - XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=Debug] "INCLUDE_SOURCE" - XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=RelWithDebInfo] "INCLUDE_SOURCE" FOLDER FeatureLib ) + +# Build a 2.3 varient for macOS 11 and/or Apple Silicon specific features +add_metal_shader_library(pfMetalPipelineShadersMSL23 + STANDARD macos-metal2.3 + ${pfMetalPipeline_SHADERS} +) +target_include_directories(pfMetalPipelineShadersMSL23 + PRIVATE + $ +) set_target_properties(pfMetalPipelineShadersMSL23 PROPERTIES - XCODE_PRODUCT_TYPE com.apple.product-type.metal-library - XCODE_ATTRIBUTE_MTL_LANGUAGE_REVISION Metal23 - XCODE_ATTRIBUTE_MTL_HEADER_SEARCH_PATHS "${Plasma_SOURCE_DIR}/Sources/Plasma/NucleusLib/inc/" - SUFFIX ".metallib" - PREFIX "" - XCODE_ATTRIBUTE_MTL_FAST_MATH "YES" - XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=Debug] "INCLUDE_SOURCE" - XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=RelWithDebInfo] "INCLUDE_SOURCE" FOLDER FeatureLib ) -set_source_files_properties(${pfMetalPipeline_SHADERS} TARGET_DIRECTORY pfMetalPipelineShadersMSL21 PROPERTIES LANGUAGE METAL) -set_source_files_properties(${pfMetalPipeline_SHADERS} TARGET_DIRECTORY pfMetalPipelineShadersMSL23 PROPERTIES LANGUAGE METAL) - -target_sources(pfMetalPipelineShadersMSL21 PRIVATE ${pfMetalPipeline_SHADERS}) -target_sources(pfMetalPipelineShadersMSL23 PRIVATE ${pfMetalPipeline_SHADERS}) diff --git a/cmake/CMakeDetermineMetalCompiler.cmake b/cmake/CMakeDetermineMetalCompiler.cmake new file mode 100644 index 0000000000..5ced536e0f --- /dev/null +++ b/cmake/CMakeDetermineMetalCompiler.cmake @@ -0,0 +1,85 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file LICENCE.txt or https://cmake.org/licensing for details. + +# CMakeDetermine(LANG)Compiler.cmake -> this should find the compiler for LANG and configure CMake(LANG)Compiler.cmake.in + +include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake) + +if(NOT CMAKE_Metal_COMPILER_NAMES) + set(CMAKE_Metal_COMPILER_NAMES metal) +endif() + +if("${CMAKE_GENERATOR}" STREQUAL "Xcode") + set(CMAKE_Metal_COMPILER_XCODE_TYPE sourcecode.metal) + + execute_process(COMMAND xcrun --find metal + OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_VARIABLE _xcrun_err RESULT_VARIABLE _xcrun_result + ) + + if(_xcrun_result EQUAL 0 AND EXISTS "${_xcrun_out}") + set(CMAKE_Metal_COMPILER "${_xcrun_out}") + else() + _cmake_find_compiler_path(Metal) + endif() +else() + if(CMAKE_Metal_COMPILER) + _cmake_find_compiler_path(Metal) + else() + set(CMAKE_Metal_COMPILER_INIT NOTFOUND) + + if(NOT $ENV{METALC} STREQUAL "") + get_filename_component(CMAKE_Metal_COMPILER_INIT $ENV{METALC} PROGRAM PROGRAM_ARGS CMAKE_Metal_FLAGS_ENV_INIT) + if(CMAKE_Metal_FLAGS_ENV_INIT) + set(CMAKE_Metal_COMPILER_ARG1 "${CMAKE_Metal_FLAGS_ENV_INIT}" CACHE STRING "Arguments to the Metal compiler") + endif() + if(NOT EXISTS ${CMAKE_Metal_COMPILER_INIT}) + message(FATAL_ERROR "Could not find compiler set in environment variable METALC\n$ENV{METALC}.\n${CMAKE_Metal_COMPILER_INIT}") + endif() + endif() + + if(NOT CMAKE_Metal_COMPILER_INIT) + set(CMAKE_Metal_COMPILER_LIST metal ${_CMAKE_TOOLCHAIN_PREFIX}metal) + endif() + + _cmake_find_compiler(Metal) + endif() + + mark_as_advanced(CMAKE_Metal_COMPILER) +endif() + +# For Metal we need to explicitly query the version. +if(CMAKE_Metal_COMPILER AND NOT CMAKE_Metal_COMPILER_VERSION) + execute_process( + COMMAND "${CMAKE_Metal_COMPILER}" --version + OUTPUT_VARIABLE output ERROR_VARIABLE output + RESULT_VARIABLE result + TIMEOUT 10 + ) + message(CONFIGURE_LOG + "Running the Metal compiler: \"${CMAKE_Metal_COMPILER}\" --version\n" + "${output}\n" + ) + + if(output MATCHES [[metal version ([0-9]+\.[0-9]+(\.[0-9]+)?)]]) + set(CMAKE_Metal_COMPILER_VERSION "${CMAKE_MATCH_1}") + if(NOT CMAKE_Metal_COMPILER_ID) + set(CMAKE_Metal_COMPILER_ID "Apple") + endif() + endif() +endif() + +if(NOT _CMAKE_TOOLCHAIN_LOCATION) + get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_Metal_COMPILER}" PATH) +endif () + +set(_CMAKE_PROCESSING_LANGUAGE "Metal") +include(CMakeFindBinUtils) +unset(_CMAKE_PROCESSING_LANGUAGE) + +configure_file( + ${CMAKE_CURRENT_LIST_DIR}/CMakeMetalCompiler.cmake.in + ${CMAKE_PLATFORM_INFO_DIR}/CMakeMetalCompiler.cmake +) + +set(CMAKE_Metal_COMPILER_ENV_VAR "METALC") diff --git a/cmake/CMakeMetalCompiler.cmake.in b/cmake/CMakeMetalCompiler.cmake.in new file mode 100644 index 0000000000..d636af4b7d --- /dev/null +++ b/cmake/CMakeMetalCompiler.cmake.in @@ -0,0 +1,27 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file LICENCE.txt or https://cmake.org/licensing for details. + +# CMake(LANG)Compiler.cmake.in -> used by CMakeDetermine(LANG)Compiler.cmake +# This file is used to store compiler information and is copied down into try +# compile directories so that try compiles do not need to re-determine and test +# the LANG + +set(CMAKE_Metal_COMPILER "@CMAKE_Metal_COMPILER@") +set(CMAKE_Metal_COMPILER_ID "@CMAKE_Metal_COMPILER_ID@") +set(CMAKE_Metal_COMPILER_VERSION "@CMAKE_Metal_COMPILER_VERSION@") + +set(CMAKE_Metal_COMPILER_LOADED 1) +set(CMAKE_Metal_COMPILER_WORKS "@CMAKE_Metal_COMPILER_WORKS@") + +set(CMAKE_Metal_COMPILER_ENV_VAR "METALC") + +set(CMAKE_Metal_COMPILER_ID_RUN "@CMAKE_Metal_COMPILER_ID_RUN@") +set(CMAKE_Metal_SOURCE_FILE_EXTENSIONS metal) +set(CMAKE_Metal_OUTPUT_EXTENSION ".air") +set(CMAKE_STATIC_LIBRARY_PREFIX_Metal "") +set(CMAKE_STATIC_LIBRARY_SUFFIX_Metal ".metal-ar") +set(CMAKE_SHARED_LIBRARY_PREFIX_Metal "") +set(CMAKE_SHARED_LIBRARY_SUFFIX_Metal ".metallib") +set(CMAKE_SHARED_MODULE_PREFIX_Metal "") +set(CMAKE_SHARED_MODULE_SUFFIX_Metal ".metallib") +set(CMAKE_EXECUTABLE_SUFFIX_Metal ".metallib") diff --git a/cmake/CMakeMetalInformation.cmake b/cmake/CMakeMetalInformation.cmake new file mode 100644 index 0000000000..7593895bed --- /dev/null +++ b/cmake/CMakeMetalInformation.cmake @@ -0,0 +1,85 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file LICENCE.txt or https://cmake.org/licensing for details. + +# CMake(LANG)Information.cmake -> set up rule variables for LANG : +# CMAKE_(LANG)_CREATE_SHARED_LIBRARY +# CMAKE_(LANG)_CREATE_SHARED_MODULE +# CMAKE_(LANG)_CREATE_STATIC_LIBRARY +# CMAKE_(LANG)_COMPILE_OBJECT +# CMAKE_(LANG)_LINK_EXECUTABLE + +include(CMakeCommonLanguageInclude) + +set(CMAKE_Metal_FLAGS_INIT "-ffast-math") +set(CMAKE_Metal_FLAGS_DEBUG_INIT "-gline-tables-only -frecord-sources") +set(CMAKE_Metal_FLAGS_RELWITHDEBINFO_INIT "-gline-tables-only -frecord-sources") + +cmake_initialize_per_config_variable(CMAKE_Metal_FLAGS "Flags used by the Metal compiler") + +set(CMAKE_INCLUDE_FLAG_Metal "-I ") +set(CMAKE_Metal_COMPILER_ARG1 "") +set(CMAKE_Metal_DEFINE_FLAG -D) +set(CMAKE_Metal_FRAMEWORK_SEARCH_FLAG "-F ") +set(CMAKE_Metal_LIBRARY_PATH_FLAG "-L ") +set(CMAKE_Metal_SYSROOT_FLAG "-isysroot") +set(CMAKE_Metal_COMPILE_OPTIONS_TARGET "-target ") +set(CMAKE_DEPFILE_FLAGS_Metal "-MMD -MT dependencies -MF ") + +if(CMAKE_GENERATOR MATCHES "Makefiles") + set(CMAKE_Metal_DEPFILE_FORMAT gcc) + set(CMAKE_Metal_DEPENDS_USE_COMPILER TRUE) +endif() + +set(CMAKE_Metal_COMPILER_PREDEFINES_COMMAND "${CMAKE_Metal_COMPILER}") +if(CMAKE_Metal_COMPILER_TARGET) + list(APPEND CMAKE_Metal_COMPILER_PREDEFINES_COMMAND "-target" "${CMAKE_Metal_COMPILER_TARGET}") +endif() + +# now define the following rule variables + +# CMAKE_Metal_CREATE_SHARED_LIBRARY +# CMAKE_Metal_CREATE_SHARED_MODULE +# CMAKE_Metal_COMPILE_OBJECT +# CMAKE_Metal_LINK_EXECUTABLE + +# variables supplied by the generator at use time +# +# the target without the suffix +# +# +# +# +# + +# Metal compiler information +# +# +# +# + +if(NOT CMAKE_Metal_COMPILE_OBJECT) + set(CMAKE_Metal_COMPILE_OBJECT + " -c -o " + ) +endif() + +if(NOT CMAKE_Metal_CREATE_SHARED_LIBRARY) + set(CMAKE_Metal_CREATE_SHARED_LIBRARY + " -o " + ) +endif() + +if(NOT CMAKE_Metal_CREATE_SHARED_MODULE) + set(CMAKE_Metal_CREATE_SHARED_MODULE + "${CMAKE_Metal_CREATE_SHARED_LIBRARY}" + ) +endif() + +if(NOT CMAKE_Metal_LINK_EXECUTABLE) + # Metal shaders don't really have "executables", but we need this for the try_compile to work properly, so we'll just have it output a metallib file + set(CMAKE_Metal_LINK_EXECUTABLE + " -o " + ) +endif() + +set(CMAKE_Metal_INFORMATION_LOADED 1) diff --git a/cmake/CMakeTestMetalCompiler.cmake b/cmake/CMakeTestMetalCompiler.cmake new file mode 100644 index 0000000000..0014553e55 --- /dev/null +++ b/cmake/CMakeTestMetalCompiler.cmake @@ -0,0 +1,78 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file LICENCE.txt or https://cmake.org/licensing for details. + +# CMakeTest(LANG)Compiler.cmake -> test the compiler and set: +# SET(CMAKE_(LANG)_COMPILER_WORKS 1 CACHE INTERNAL "") + +if(CMAKE_Metal_COMPILER_FORCED) + # The compiler configuration was forced by the user. + # Assume the user has configured all compiler information. + set(CMAKE_Metal_COMPILER_WORKS TRUE) + return() +endif() + +include(CMakeTestCompilerCommon) + +if("${CMAKE_GENERATOR}" STREQUAL "Xcode") + if(XCODE_VERSION VERSION_GREATER 7.0) + set(CMAKE_Metal_COMPILER_WORKS 1) + endif() +endif() + +# This file is used by EnableLanguage in cmGlobalGenerator to +# determine that that selected Metal compiler can actually compile +# and link the most basic of programs. If not, a fatal error +# is set and cmake stops processing commands and will not generate +# any makefiles or projects. +if(NOT CMAKE_Metal_COMPILER_WORKS) + PrintTestCompilerStatus("Metal") + __TestCompiler_setTryCompileTargetType() + + string(CONCAT __TestCompiler_testMetalCompilerSource + "#ifndef __METAL_VERSION__\n" + "# error \"The CMAKE_Metal_COMPILER is not a Metal compiler\"\n" + "#endif\n" + "#import \n" + "using namespace metal;\n" + ) + + # Clear result from normal variable. + unset(CMAKE_Metal_COMPILER_WORKS) + + # Puts test result in cache variable. + try_compile(CMAKE_Metal_COMPILER_WORKS + SOURCE_FROM_VAR testMetalCompiler.metal __TestCompiler_testMetalCompilerSource + OUTPUT_VARIABLE __CMAKE_Metal_COMPILER_OUTPUT + ) + unset(__TestCompiler_testMetalCompilerSource) + + # Move result from cache to normal variable. + set(CMAKE_Metal_COMPILER_WORKS ${CMAKE_Metal_COMPILER_WORKS}) + unset(CMAKE_Metal_COMPILER_WORKS CACHE) + __TestCompiler_restoreTryCompileTargetType() + set(METAL_TEST_WAS_RUN 1) +endif() + +if(NOT CMAKE_Metal_COMPILER_WORKS) + PrintTestCompilerResult(CHECK_FAIL "broken") + string(REPLACE "\n" "\n " _output "${__CMAKE_Metal_COMPILER_OUTPUT}") + message(FATAL_ERROR "The Metal compiler\n \"${CMAKE_Metal_COMPILER}\"\n" + "is not able to compile a simple test program.\nIt fails " + "with the following output:\n ${_output}\n\n" + "CMake will not be able to correctly generate this project." + ) +else() + if(METAL_TEST_WAS_RUN) + PrintTestCompilerResult(CHECK_PASS "works") + endif() + + # Re-configure to save learned information. + configure_file( + ${CMAKE_CURRENT_LIST_DIR}/CMakeMetalCompiler.cmake.in + ${CMAKE_PLATFORM_INFO_DIR}/CMakeMetalCompiler.cmake + @ONLY + ) + include(${CMAKE_PLATFORM_INFO_DIR}/CMakeMetalCompiler.cmake) +endif() + +unset(__CMAKE_Metal_COMPILER_OUTPUT) diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index c443cf5d22..433f506502 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -1,4 +1,6 @@ # List all dependency packages here. +include(FeatureSummary) + set_package_properties( 3dsm PROPERTIES URL "https://www.autodesk.com/" diff --git a/cmake/MetalShaderSupport.cmake b/cmake/MetalShaderSupport.cmake new file mode 100644 index 0000000000..bb214c1c0d --- /dev/null +++ b/cmake/MetalShaderSupport.cmake @@ -0,0 +1,52 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file LICENCE.txt or https://cmake.org/licensing for details. + +function(add_metal_shader_library TARGET) + cmake_parse_arguments(PARSE_ARGV 1 _amsl + "" + "STANDARD" + "" + ) + + add_library(${TARGET} MODULE ${_amsl_UNPARSED_ARGUMENTS}) + + set_target_properties(${TARGET} PROPERTIES + XCODE_PRODUCT_TYPE com.apple.product-type.metal-library + XCODE_ATTRIBUTE_MTL_FAST_MATH "YES" + XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=Debug] "INCLUDE_SOURCE" + XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=RelWithDebInfo] "INCLUDE_SOURCE" + XCODE_ATTRIBUTE_MTL_HEADER_SEARCH_PATHS "$(HEADER_SEARCH_PATHS)" + ) + + if(_amsl_STANDARD AND _amsl_STANDARD MATCHES "metal([0-9]+)\.([0-9]+)") + target_compile_options(${TARGET} + PRIVATE "-std=${_amsl_STANDARD}" + ) + + set_target_properties(${TARGET} PROPERTIES + XCODE_ATTRIBUTE_MTL_LANGUAGE_REVISION "Metal${CMAKE_MATCH_1}${CMAKE_MATCH_2}" + ) + endif() +endfunction() + +function(target_embed_metal_shader_libraries TARGET) + cmake_parse_arguments(PARSE_ARGV 1 _temsl + "" + "" + "" + ) + + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.28 AND ${CMAKE_GENERATOR} STREQUAL "Xcode") + set_target_properties(${TARGET} PROPERTIES + XCODE_EMBED_RESOURCES "${_temsl_UNPARSED_ARGUMENTS}" + ) + else() + foreach(SHADERLIB IN LISTS _temsl_UNPARSED_ARGUMENTS) + add_custom_command(TARGET ${TARGET} POST_BUILD + DEPENDS ${SHADERLIB} + COMMAND ${CMAKE_COMMAND} -E copy "$" "$/Resources/$" + VERBATIM + ) + endforeach() + endif() +endfunction()