'How to create a metal-cpp project?

I am trying to learn metal and since I am already familiar with C++, I am trying to do it using metal-cpp. I am not an experienced macOS developer but I have worked in Xcode in the past in projects using OpenGL and C++ as the main language.

My question is how to set up a project in C++ and use Metal to render to a window or view. I have found some tutorials on how to do this in Swift or Objective-C but nothing in C++. A couple of years ago, I remember doing something similar with OpenGL and if I recall correctly, the view had to be set in Objective-C and then pass the OpenGL context to C++.

Would this be a good approach for this case (set up the view in Swift/Obj-C and then pass a device to C++)? I am also a bit lost with what type of project or other files I would need to do this (i.e. storyboards, etc.). As of now I just have a command-line tool project with the Foundation, Mmetal, MetalKit and QuartzCore frameworks linked; plus metal-cpp linked and compiling too.



Solution 1:[1]

I was doing various C++ projects on Mac and I personally would stick to using cmake instead of XCode, especially that I may generate XCode project out of the cmake one (but usually I use Ninja Multi-Config generators). The following example is a minimal cmake project which sets up metal-cpp unpacked to the main directory (containing the CMakeLists.txt file).

cmake_minimum_required (VERSION 3.20)
project (metal_cpp_rocks)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")

find_library(APPLE_FWK_FOUNDATION Foundation REQUIRED)
find_library(APPLE_FWK_QUARTZ_CORE QuartzCore REQUIRED)
find_library(APPLE_FWK_METAL Metal REQUIRED)

add_executable(metal_cpp_rocks
  main.cpp
)

target_include_directories(metal_cpp_rocks
  SYSTEM PUBLIC ${CMAKE_SOURCE_DIR}/metal-cpp
)

target_link_libraries(metal_cpp_rocks
  ${APPLE_FWK_FOUNDATION}
  ${APPLE_FWK_QUARTZ_CORE}
  ${APPLE_FWK_METAL}
)

and the minimal main.cpp

#define NS_PRIVATE_IMPLEMENTATION
#define CA_PRIVATE_IMPLEMENTATION
#define MTL_PRIVATE_IMPLEMENTATION

#include <Foundation/Foundation.hpp>
#include <Metal/Metal.hpp>
#include <QuartzCore/QuartzCore.hpp>

int main()
{
  MTL::Device* device = MTL::CreateSystemDefaultDevice();
  device->release();
  return 0;
}

Building and running (being in the main directory):

cmake -S . -B build -G "Ninja Multi-Config"
cmake --build build --config Release
./build/Release/metal_cpp_rocks

An example of how to generate an XCode project from the cmake one in order to use XCode as the IDE during development:

cmake -S . -B build_xcode -G "Xcode"

Now open the generated build_xcode/metal_cpp_rocks.xcodeproj from XCode and do everything in a usual way, but remember not to change the project itself in XCode - modify the cmake project and regenerate the XCode project instead.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tomaszmi