Пользовательская команда CMake после сборки всегда выполняется - PullRequest
0 голосов
/ 27 марта 2020

Я сейчас пытаюсь скомпилировать шейдеры с помощью CMake, но только когда они меняются. Я подумал, что это можно сделать правильно, но я не очень разбираюсь в CMake, чтобы это произошло.

Структура моей папки:

Root
  + NetcodeClient
  |  + Shaders
  |  |  + CMakeLists.txt
  |  + CMakeLists.txt
  + CMakeLists.txt

Верхний уровень Root/CMakeLists.txt с вызовом project () внутри, я определил следующий макрос там (я буду включать только вершинные шейдеры, потому что остальное просто скопировать макароны):

macro(NETCODE_COMPILE_SHADER ownerTarget fileName shaderType entryPoint)
    get_filename_component(strippedFileName ${fileName} NAME_WE)
    add_custom_command(TARGET ${ownerTarget}
                       POST_BUILD
                       DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${fileName}
                       COMMAND ${FXC} /T \"${shaderType}\" /E\"${entryPoint}\" /Od /Zi /Fo \"${CMAKE_BINARY_DIR}/Shaders/${strippedFileName}.cso\" ${CMAKE_CURRENT_SOURCE_DIR}/${fileName}
                       BYPRODUCTS ${CMAKE_BINARY_DIR}/Shaders/${strippedFileName}.cso
                       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    )
endmacro()

macro(NETCODE_COMPILE_VS ownerTarget fileName)
    NETCODE_COMPILE_SHADER(${ownerTarget} ${fileName} "vs_5_0" "main")
endmacro()

[...]

add_subdirectory("NetcodeClient")

То, что я использую внутри цели Root/NetcodeClient/Shaders/CMakeLists.txt, выглядит следующим образом:

set(NETCODE_VS 
    "envMapPass_Vertex.hlsl"
    "gbufferPass_Vertex.hlsl"
    "lightingPass_Vertex.hlsl"
    "skinningPass_Vertex.hlsl"
    "sprite_Vertex.hlsl"
    "ssaoPass_Vertex.hlsl"
)

add_custom_target(NetcodeClientShaders DEPENDS ${NETCODE_VS})

foreach(var ${NETCODE_VS})
    NETCODE_COMPILE_VS(NetcodeClientShaders ${var})
endforeach(var)

И, наконец, в Root/NetcodeClient/CMakeLists.txt Я делаю следующее, просто чтобы соединить зависимости:

add_subdirectory(Shaders)
add_dependencies(NetcodeClient NetcodeClientShaders)

.cso файлы компилируются просто отлично, но они запускаются каждый раз, когда я нажимаю сборку, что не занимает слишком много времени, но я бы с удовольствием чтобы сократить это, если это возможно.

Я много раз консультировался с add_custom_command , и мне кажется, что я не могу добавить часть DEPENDS, когда определяется шаг сборки. Что по описанию именно то, что мне нужно здесь. Не могли бы вы помочь мне здесь, пожалуйста?

1 Ответ

1 голос
/ 27 марта 2020

Используйте add_custom_command для создания правил make, таких как GNU make, и соберите все выходные данные и используйте add_custom_target для создания цели CMake.

# generate shader output
function(netcode_compile_shader var_binary_path source_path shader_type entry_point)
  get_filename_component(source_filename ${source_path} NAME_WE)
  get_filename_component(source_path "${source_path}" ABSOLUTE)
  set(binary_path "${CMAKE_CURRENT_BINARY_DIR}/${source_filename}.cso")
  add_custom_command(OUTPUT ${binary_path}
    COMMENT "Generating ${binary_path}..."
    COMMAND ${FXC} /T \"${shader_type}\" /E\"${entry_point}\" /Od /Zi /Fo \"${binary_path}\" \"${source_path}\"
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    DEPENDS "${source_path}"
  )
  set(${var_binary_path} "${binary_path}" PARENT_SCOPE)
endfunction()

# generate vs shader output
macro(netcode_compile_vs var_binary_path source_path)
  netcode_compile_shader(${var_binary_path} ${source_path} "vs_5_0" "main")
endmacro()

# create shader compiling target
set(NETCODE_VS 
  "envMapPass_Vertex.hlsl"
  "gbufferPass_Vertex.hlsl"
  "lightingPass_Vertex.hlsl"
  "skinningPass_Vertex.hlsl"
  "sprite_Vertex.hlsl"
  "ssaoPass_Vertex.hlsl"
)
foreach(vs ${NETCODE_VS})
  netcode_compile_vs(vs_out ${vs})
  list(APPEND NETCODE_VS_OUT ${vs_out})
endforeach()
add_custom_target(NetcodeClientShaders DEPENDS ${NETCODE_VS_OUT})
...