Xcode: Metal shaders are not added to Target Membership, resulting in their exclusion from the build.
When adding Metal shader files via add_executable
, the shaders are not added to the Xcode target membership. This means that when compiling the target, the metal shaders are excluded, which causes Metal calls to load shaders to fail (return nil). Below is a minimal example which reproduces the issue (also attached as a zip at the bottom of this report).
CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(bug_report)
# enable obj-c++ for the sample code
add_definitions("-x objective-c++")
# add an executable with the obj-c++ file and a metal shader
add_executable(${PROJECT_NAME} main.mm shader.metal)
set_target_properties(${PROJECT_NAME} PROPERTIES
MACOSX_BUNDLE TRUE
)
# link to metal for sample code
find_library(METAL_LIB Metal REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE ${METAL_LIB})
main.mm
#include <iostream>
#include <stdexcept>
#import <Metal/Metal.h>
int main(){
auto device = MTLCreateSystemDefaultDevice();
auto library = [device newDefaultLibrary];
if (library == nullptr){
std::cerr << "ERROR: Could not create default library - shader.metal was probably not included in the target membership." << std::endl;
return 1;
}
std::cout << "Loaded default library" << std::endl;
auto shader = [library newFunctionWithName:@"shaderfunc"];
if (shader == nullptr){
std::cerr << "ERROR: Could not create function - shader.metal was probably not included in the target membership." << std::endl;
return 1;
}
std::cout << "SUCCESS: Loaded shader and library!" << std::endl;
return 0;
}
shader.metal
vertex void shaderfunc(){
}
When using cmake -G "Xcode" ..
, main.mm
is added to the bug_report
target:
However, shader.metal
is not included in the target membership:
When bug_report
is compiled and ran, it produces the following output:
ERROR: Could not create default library - shader.metal was probably not included in the target membership.
If I manually enable target membership for shader.metal
in the sidebar, then compile and run bug_report
, it produces the following output:
Loaded default library
SUCCESS: Loaded shader and library!
I think CMake should add .metal
files to the Target Membership automatically, since at present every time a CMake configure is run the shaders lose their target membership. In addition, one cannot easily enable the target membership manually for headless CI builds.
I have attached a zip file containing everything needed to reproduce the issue. bug_repro.zip