diff --git a/CMakeLists.txt b/CMakeLists.txt index deab6924ed..f52fbad346 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()