KK PROJEKT RED 勉強ブログ

ゲーム好き技術系大学生のメモのようなもの

AtomicGameEngine - CMake(4)

前回AtomicToolとToolsを飛ばしたので、今回はその2つと最後のAtomicEditorをすませる。

/Source/AtomicTool/CMakeLists.txt
set (ATOMIC_TOOL_SOURCES AtomicTool.cpp AtomicTool.h)

if (WIN32)
    add_definitions(-DATOMIC_WIN32_CONSOLE)
endif(WIN32)

add_executable(AtomicTool ${ATOMIC_TOOL_SOURCES})

target_link_libraries(AtomicTool ToolCore AtomicNETScript Poco Atomic)

if (WIN32)
    target_link_libraries(AtomicTool Iphlpapi Wldap32)
endif()
target_link_libraries(AtomicTool libcurl)

実行可能ファイルAtomicToolを用意して、ToolCore、AtomicNETScript、Poco、Atomic、libcurlをリンク

# Custom target which is always considered out of date, checks for zero size/missing script bindings and generates
add_custom_target( AtomicToolCheckScripts
                   WORKING_DIRECTORY "${ATOMIC_SOURCE_DIR}"
                   COMMAND "${CMAKE_COMMAND}" -E make_directory \"${ATOMIC_SOURCE_DIR}/Artifacts/Build/AtomicTool\"
                   COMMAND "${CMAKE_COMMAND}" -E copy_if_different \"$<TARGET_FILE:AtomicTool>\" \"${ATOMIC_SOURCE_DIR}/Artifacts/Build/AtomicTool/\"
                   COMMAND ${ATOMIC_NODE_JAKE};build:genscripts[false] )

add_custom_target()は生成を目的としない任意のターゲットを用意するやつ。COMMANDで、AtomicToolCheckScriptsが実行されたときに、呼び出すコマンドを設定できる。 前回スルーした、cmake -E make_directorycmake -E copy_if_differentはこんな感じ。 cmakeの-EオプションのUsageで出てきた。

copy_if_different <file>... destination  - copy files if it has changed
 
make_directory <dir>...   - create parent and <dir> directories

Artifacts/Build/AtoimToolディレクトリを作る。で copy_if_differenはファイルのコピーだけど、コピー先のファイルと違ってたり、コピー先に同一のファイルがない場合とかにコピーしてる。 $<TARGET_FILE:AtomicTool>こいつは、generator expressionってやつで、ターゲットプロパティだけで有効な式らしい。で、AtomicToolのソースファイル?を/Artifacts/Build/AtomicTool/にコピーしているんだと思われる。getnscriptsは/Build/Scripts/BuildCommon.jsにあるけど一旦無視。

add_dependencies (AtomicToolCheckScripts AtomicTool)

AtomicToolCheckScriptsをAtomicToolに依存させる。

# Copy AtomicTool to Artifacts
add_custom_command( TARGET AtomicTool POST_BUILD
                    COMMAND "${CMAKE_COMMAND}"
                    ARGS -E make_directory \"${ATOMIC_SOURCE_DIR}/Artifacts/Build/AtomicTool\"
                    COMMAND "${CMAKE_COMMAND}"
                    ARGS -E copy_if_different \"$<TARGET_FILE:AtomicTool>\" \"${ATOMIC_SOURCE_DIR}/Artifacts/Build/AtomicTool/\"
                    COMMENT "Copying AtomicTool to Build Artifacts" )

コメント通りAtomicToolをArtifactsにコピーしてるってことで

add_custom_target ( GenerateScriptBindings
                    WORKING_DIRECTORY "${ATOMIC_SOURCE_DIR}"
                    COMMAND ${ATOMIC_NODE_JAKE};build:genscripts[true];--trace
                    DEPENDS AtomicTool )

add_custom_target ( GenerateAtomicNET
                    WORKING_DIRECTORY "${ATOMIC_SOURCE_DIR}"
                    COMMAND ${ATOMIC_NODE_JAKE};build:genAtomicNET[desktop,$<$<CONFIG:debug>:"Debug">$<$<CONFIG:release>:"Release">];--trace
                    DEPENDS AtomicTool )

カスタムターゲットGenerateScriptBindings、GenerateAtomicNETを用意する。genscriptsgenAtomicNETはまた必要になったら内容見る。

/Source/Tools/CMakeLists.txt
add_subdirectory(PackageTool)

これ1行

/Source/Tools/PackageTool/CMakeLists.txt
add_executable(PackageTool PackageTool.cpp)

target_link_libraries(PackageTool Atomic)

実行可能ファイルPackageToolを用意して、Atomicをリンク

file (GLOB_RECURSE EDITORDATA_FILES ${ATOMIC_SOURCE_DIR}/Data/AtomicEditor/Resources/EditorData/*)
file (GLOB_RECURSE COREDATA_FILES ${ATOMIC_SOURCE_DIR}/Data/AtomicPlayer/Resources/CoreData/*)

if (ATOMIC_BUILD_PAK_FILES)

    set (EDITORDATA_PAK "${ATOMIC_SOURCE_DIR}/Bin/EditorData.pak")
    set (COREDATA_PAK "${ATOMIC_SOURCE_DIR}/Bin/CoreData.pak")

    if (WIN32)

        add_custom_command(OUTPUT "${EDITORDATA_PAK}"
                        COMMAND $<TARGET_FILE:PackageTool> "${ATOMIC_SOURCE_DIR}/Data/AtomicEditor/Resources/EditorData" "${EDITORDATA_PAK}" -c
                        COMMAND ${CMAKE_COMMAND}
                        ARGS -E copy \"${EDITORDATA_PAK}\" \"$<TARGET_FILE_DIR:AtomicEditor>/EditorData.pak\"
                        DEPENDS PackageTool ${EDITORDATA_FILES})

        add_custom_command(OUTPUT "${COREDATA_PAK}"
                        COMMAND $<TARGET_FILE:PackageTool> "${ATOMIC_SOURCE_DIR}/Data/AtomicPlayer/Resources/CoreData" "${COREDATA_PAK}" -c
                        COMMAND ${CMAKE_COMMAND}
                        ARGS -E copy \"${COREDATA_PAK}\" \"$<TARGET_FILE_DIR:AtomicEditor>/CoreData.pak\"
                        DEPENDS PackageTool ${COREDATA_FILES})

    elseif (APPLE)

        add_custom_command(OUTPUT "${EDITORDATA_PAK}"
                        COMMAND $<TARGET_FILE:PackageTool> "${ATOMIC_SOURCE_DIR}/Data/AtomicEditor/Resources/EditorData" "${EDITORDATA_PAK}" -c
                        COMMAND rsync -u "${EDITORDATA_PAK}" "$<TARGET_FILE_DIR:AtomicEditor>/../Resources/EditorData.pak"
                        DEPENDS PackageTool ${EDITORDATA_FILES})

        add_custom_command(OUTPUT "${COREDATA_PAK}"
                        COMMAND $<TARGET_FILE:PackageTool> "${ATOMIC_SOURCE_DIR}/Data/AtomicPlayer/Resources/CoreData" "${COREDATA_PAK}" -c
                        COMMAND rsync -u "${COREDATA_PAK}" "$<TARGET_FILE_DIR:AtomicEditor>/../Resources/CoreData.pak"
                        DEPENDS PackageTool ${COREDATA_FILES})

    elseif (LINUX)

        add_custom_command(OUTPUT "${EDITORDATA_PAK}"
                        COMMAND $<TARGET_FILE:PackageTool> "${ATOMIC_SOURCE_DIR}/Data/AtomicEditor/Resources/EditorData" "${EDITORDATA_PAK}" -c
                        COMMAND rsync -u "${EDITORDATA_PAK}" "$<TARGET_FILE_DIR:AtomicEditor>/EditorData.pak"
                        DEPENDS PackageTool ${EDITORDATA_FILES})

        add_custom_command(OUTPUT "${COREDATA_PAK}"
                        COMMAND $<TARGET_FILE:PackageTool> "${ATOMIC_SOURCE_DIR}/Data/AtomicPlayer/Resources/CoreData" "${COREDATA_PAK}" -c
                        COMMAND rsync -u "${COREDATA_PAK}" "$<TARGET_FILE_DIR:AtomicEditor>/CoreData.pak"
                        DEPENDS PackageTool ${COREDATA_FILES})

    endif()

    add_custom_target(BuildEditorFiles ALL DEPENDS AtomicEditor "${EDITORDATA_PAK}" "${COREDATA_PAK}")

endif()

実行されない

/Source/AtomicEditor/CMakeLists.txt

んー、実行可能ファイルのAtomicEditorを用意して、libcef_lib libcef_dll_wrapper ToolCore AtomicApp AtomicWebView AtomicJS AtomicPlayerJS ToolCoreJS AtomicNETScriptBindings AtomicNETScript Poco nativefiledialog Atomic libcurlをリンクしてる。何かCEF関係のこと。

で、まぁこれでcmakeは終了で、生成されたプロジェクトファイルにxcodebuildをして、実行ファイルができる感じっすな。

まとめ

ThirdParty製のライブラリをガンガン利用して、かつ、クロスプラットフォームで同じように動くものを生成するには、cmakeでもおそらくどんなビルドシステムでも、誰かしらが頑張って愚直に設定を書いてる。CLIツールのnodejsとかも使ってる。ソースコードを書いた人たちからしてみたら、ライブラリの依存関係とか十分理解してるから、cmake関係のソース作るのくらい作業でしかないのかもしれないが、まぁそれでもすげぇ。各OSのバージョンとかによってもビルドの仕方を変えな駄目。Windowsだったら、D3D9とかD3D11とかバージョンによって変えないといけない。ゲームエンジン作るグループはやっぱりほとんどプログラマなのかね。まぁそうだよね。いやー、現場を知りたいものだ。今までは、ほんとに少ない知識で似たようなロジック使いまわしてアウトプットばっかりしてきたから、この夏はプロ達のものをどんどんインプットしていきたい。