Open4

Learn Metal with C++ を CMake を利用してビルドできるようにするまで

mtakagimtakagi

Apple の Metal CPP のサンプルプロジェクト Learn Metal with C++を Xcode, Make を使用せずに CMake 経由でビルドできるようにする

mtakagimtakagi

とりあえずサンプルプロジェクトにあった Makefile を Gemini で CMake に変換してもらってみたところ以下のような結果が出力された。

# CMakeLists.txt

# 1. CMakeの最低バージョンを指定
#    このプロジェクトはC++17を使用するため、それに必要な機能が使えるバージョンを指定します。
cmake_minimum_required(VERSION 3.14)

# 2. プロジェクトの定義
#    プロジェクト名を「LearnMetal」とし、使用する言語をC++に指定します。
project(LearnMetal LANGUAGES CXX)

# 3. C++の標準バージョンとコンパイラオプションの設定
#    MakefileのCFLAGSを再現します。
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_compile_options(-Wall -fno-objc-arc)

# 4. デバッグとAddress Sanitizerのフラグ設定
#    CMakeのビルドタイプによって自動で最適化・デバッグフラグを切り替えます。
#    Address Sanitizerは、cmake実行時に -DASAN=ON オプションを渡すことで有効になります。
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    add_compile_options(-g)
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
    add_compile_options(-O2)
endif()

option(ASAN "Enable AddressSanitizer" OFF)
if(ASAN)
    add_compile_options(-fsanitize=address)
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
endif()

# 5. すべてのサンプルアプリケーションのリストを定義
set(PROJECT_NAMES
    00-window
    01-primitive
    02-argbuffers
    03-animation
    04-instancing
    05-perspective
    06-lighting
    07-texturing
    08-compute
    09-compute-to-render
    10-frame-debugging
)

# 6. すべてのアプリケーションをループで定義
#    Makefileの個別のビルドルールをこのループで再現します。
foreach(APP IN LISTS PROJECT_NAMES)
    # ソースファイルのパスを定義
    set(SOURCE_FILE "learn-metal/${APP}/${APP}.cpp")

    # 実行可能ファイルを生成
    add_executable(${APP} "${SOURCE_FILE}")

    # ヘッダーファイルのインクルードパスを指定
    target_include_directories(${APP} PRIVATE "./metal-cpp" "./metal-cpp-extensions")

    # フレームワークのリンク
    target_link_libraries(${APP} PRIVATE
        -framework Metal
        -framework Foundation
        -framework Cocoa
        -framework CoreGraphics
        -framework MetalKit
    )
endforeach()

# 7. 特殊なビルドルールを持つプロジェクトの定義
#    Makefileの "10-frame-debugging" にあるplistファイルの埋め込みを再現
target_link_options(10-frame-debugging PRIVATE
    "-sectcreate" "__TEXT" "__info_plist"
    "${CMAKE_CURRENT_SOURCE_DIR}/learn-metal/10-frame-debugging/Info.plist"
)
mtakagimtakagi

とりあえずビルドできるか試したが、フレームワークが見付からずエラーになるようだ。

➜  LearnMetalCPP mkdir build
➜  LearnMetalCPP cd build 
➜  build cmake ../
-- The CXX compiler identification is AppleClang 17.0.0.17000013
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.4s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/mtakagi/Downloads/LearnMetalCPP/build
➜  build make
[  4%] Building CXX object CMakeFiles/00-window.dir/learn-metal/00-window/00-window.cpp.o
[  9%] Linking CXX executable 00-window
ld: warning: search path '/Users/mtakagi/lib/' not found
ld: warning: search path '/Users/mtakagi/lib/' not found
ld: library 'Metal' not found
c++: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [00-window] Error 1
make[1]: *** [CMakeFiles/00-window.dir/all] Error 2
make: *** [all] Error 2
➜  build 
mtakagimtakagi

リンクするフレームワークを""で囲めばビルドが通るようになった。ChatGPT に CMakeLists.txt を見せたらもっと良い方法があるようだがいまのところ未確認。

    # フレームワークのリンク
    target_link_libraries(${APP} PRIVATE
        "-framework Metal"
        "-framework Foundation"
        "-framework Cocoa"
        "-framework CoreGraphics"
        "-framework MetalKit"
    )