diff --git a/BuildMacOS.command b/BuildMacOS.command index 121b70e878..5bdc33856a 100755 --- a/BuildMacOS.command +++ b/BuildMacOS.command @@ -118,28 +118,6 @@ OPTIONS=( -B "$OUTPUT_DIR" ) -# Compiles the Metal shaders for all examples into the default.metallib file -compile_example_metal_shaders() -{ - EXAMPLE_BASE_DIR=$OUTPUT_DIR/build - EXAMPLE_PROJECTS=($EXAMPLE_BASE_DIR/Example_*.app) - - for PROJECT in ${EXAMPLE_PROJECTS[@]}; do - SHADER_FILES=() - for FILE in $PROJECT/Contents/Resources/*.metal; do - if [ -f $FILE ]; then - SHADER_FILES+=($FILE) - fi - done - if [ ! -z "$SHADER_FILES" ]; then - if [ $VERBOSE -ne 0 ]; then - echo "Compile Metal shaders: ${SHADER_FILES[@]}" - fi - xcrun -sdk macosx metal ${SHADER_FILES[@]} -o "$PROJECT/Contents/Resources/default.metallib" - fi - done -} - if [ $PROJECT_ONLY -eq 0 ]; then if [ "$GENERATOR" = "" ]; then cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE ${OPTIONS[@]} # CMake default generator @@ -151,7 +129,12 @@ if [ $PROJECT_ONLY -eq 0 ]; then # Compile Metal shaders for all examples into the default.metallib. # This is done by Xcode automatically when built from within the IDE, # so we only do this when no project files are generated. - compile_example_metal_shaders + COMPILE_METAL_SCRIPT=$SOURCE_DIR/scripts/CompileMetalToMetallib.sh + if [ $VERBOSE -ne 0 ]; then + $COMPILE_METAL_SCRIPT macosx "$OUTPUT_DIR/build" -v + else + $COMPILE_METAL_SCRIPT macosx "$OUTPUT_DIR/build" + fi else if [ "$GENERATOR" = "" ]; then GENERATOR="Xcode" # Default to Xcode for project solution diff --git a/scripts/CompileMetalToMetallib.sh b/scripts/CompileMetalToMetallib.sh new file mode 100755 index 0000000000..ef91e2f405 --- /dev/null +++ b/scripts/CompileMetalToMetallib.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# Part of the LLGL project +# Written by L. Hermanns 9/9/2024 +# ------------------------------- +# Compiles Metal shaders to a single default.metallib file for app bundles. +# The input can either be a single Metal shader file, an app folder to compile all of its *.metal files, +# or a directory with multiple *.app/ subfolders for which a separate default.metallib is generated each. + +# Parse input parameters +METAL_SDK=$1 +INPUT_PATH=$2 +VERBOSE=0 + +if [ "$#" -eq 0 ]; then + echo "Usage: CompileMetalToMetallib.sh SDK INPUT [-v|--verbose]" + exit 1 +fi + +if [ "$#" -eq 3 ]; then + if [ "$3" = "-v" ] || [ "$3" = "--verbose" ]; then + VERBOSE=1 + fi +fi + +# Compiles input Metal shaders to a single default.metallib output. +# Example: compile_metal_shaders OUTPUT INPUT1 INPUT2 ... +compile_metal_shaders() +{ + OUTPUT_DIR=$1 + shift # get remaining arguments (compatible with sh) + INPUT_FILES=$@ + if [ ! -z "$INPUT_FILES" ]; then + if [ $VERBOSE -ne 0 ]; then + echo "Compile Metal shaders: ${INPUT_FILES[@]}" + fi + xcrun -sdk $METAL_SDK metal ${INPUT_FILES[@]} -o "$OUTPUT_DIR/default.metallib" + fi +} + +# Compiles all Metal shaders for the specified app folder. +# Example: compile_all_app_metal_shaders Example_HelloTriangle.app +compile_all_app_metal_shaders() +{ + APP_DIR=$1 + APP_RESOURCES_DIR="$APP_DIR/Contents/Resources" + SHADER_FILES=() + for FILE in $APP_RESOURCES_DIR/*.metal; do + if [ -f $FILE ]; then + SHADER_FILES+=($FILE) + fi + done + compile_metal_shaders "$APP_RESOURCES_DIR" ${SHADER_FILES[@]} +} + +if [ -f "$INPUT_PATH" ]; then + # Compile the specified input Metal shader + compile_metal_shaders $(dirname "$INPUT_PATH") "$INPUT_PATH" +elif [ -d "$INPUT_PATH/Contents/Resources" ]; then + # Compile all *.metal shaders for the specified app + compile_all_app_metal_shaders "$INPUT_PATH" +else + # Compile all *.metal shaders for all subdirectory apps + TARGET_APPS=($INPUT_PATH/*.app) + for APP_DIR in ${TARGET_APPS[@]}; do + compile_all_app_metal_shaders "$APP_DIR" + done +fi