Skip to content

Commit

Permalink
Merge pull request #1611 from dpogue/cmake-metal
Browse files Browse the repository at this point in the history
Allow building macOS client with Makefiles/Ninja
  • Loading branch information
Hoikas authored Nov 3, 2024
2 parents d9ee8e9 + 7cd66a3 commit 97095e0
Show file tree
Hide file tree
Showing 9 changed files with 373 additions and 49 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ if(POLICY CMP0127)
endif()

include(CMakeDependentOption)
include(FeatureSummary)
include(Dependencies)
include(FeatureSummary)
include(MetalShaderSupport)
include(VcpkgToolchain)

project(Plasma)
Expand Down Expand Up @@ -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
Expand Down
16 changes: 7 additions & 9 deletions Sources/Plasma/Apps/plClient/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand Down
73 changes: 34 additions & 39 deletions Sources/Plasma/FeatureLib/pfMetalPipeline/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
$<TARGET_PROPERTY:pnNucleusInc,INTERFACE_INCLUDE_DIRECTORIES>
)
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
$<TARGET_PROPERTY:pnNucleusInc,INTERFACE_INCLUDE_DIRECTORIES>
)
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})
85 changes: 85 additions & 0 deletions cmake/CMakeDetermineMetalCompiler.cmake
Original file line number Diff line number Diff line change
@@ -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")
27 changes: 27 additions & 0 deletions cmake/CMakeMetalCompiler.cmake.in
Original file line number Diff line number Diff line change
@@ -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")
85 changes: 85 additions & 0 deletions cmake/CMakeMetalInformation.cmake
Original file line number Diff line number Diff line change
@@ -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 <DEP_FILE>")

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
# <TARGET>
# <TARGET_BASE> the target without the suffix
# <OBJECTS>
# <OBJECT>
# <LINK_LIBRARIES>
# <FLAGS>
# <LINK_FLAGS>

# Metal compiler information
# <CMAKE_Metal_COMPILER>
# <CMAKE_SHARED_LIBRARY_CREATE_Metal_FLAGS>
# <CMAKE_SHARED_MODULE_CREATE_Metal_FLAGS>
# <CMAKE_Metal_LINK_FLAGS>

if(NOT CMAKE_Metal_COMPILE_OBJECT)
set(CMAKE_Metal_COMPILE_OBJECT
"<CMAKE_Metal_COMPILER> -c <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>"
)
endif()

if(NOT CMAKE_Metal_CREATE_SHARED_LIBRARY)
set(CMAKE_Metal_CREATE_SHARED_LIBRARY
"<CMAKE_Metal_COMPILER> <CMAKE_SHARED_LIBRARY_Metal_FLAGS> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_Metal_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
)
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
"<CMAKE_Metal_COMPILER> <FLAGS> <CMAKE_Metal_LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
)
endif()

set(CMAKE_Metal_INFORMATION_LOADED 1)
Loading

0 comments on commit 97095e0

Please sign in to comment.