【问题标题】:CMake : softlink resource ( such as GLSL shaders ) or copy each complilationCMake:软链接资源(如GLSL着色器)或复制每个编译
【发布时间】:2019-03-03 04:48:41
【问题描述】:

使用 CMake 将资源从源目录复制到构建目录的最简单方法是

file( COPY ${CMAKE_CURRENT_SOURCE_DIR}/resources DESTINATION ${CMAKE_CURRENT_BINARY_DIR} )

但是,这只有在我调用cmake 时才会更新构建目录中的资源。我需要更新资源的东西每次调用 make

例如现在我开发了一些 GLSL 着色器。我需要同时更改 C++ 代码和 GLSL 代码,并且我需要 每次点击时同步 compilerun 在我的 IDE 中(我将 CodeBlocks 与 CMake 生成的项目文件一起使用)

简单的解决方案是将 softlink 从源目录创建到构建目录。但我不想手动进行(它会绕过 CMake 并使项目更加脆弱)。 CMake 可以为我做吗?


为了完整性,这就是我的整个 CMakeList.txt 的样子

# ==== common header

cmake_minimum_required ( VERSION 2.8 )
project ( SimpleSimulationEngine )

if( UNIX )
    SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=gnu++0x" )
endif()

SET( AXULIARY_COMPILE_FLAGS "-w -O2")
SET( CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${AXULIARY_COMPILE_FLAGS}" )
SET( COMMON_SRCS "${CMAKE_SOURCE_DIR}/common" )
include_directories(
        ${COMMON_SRCS}
        ${COMMON_SRCS}/algorithms
        ${COMMON_SRCS}/math
        ${COMMON_SRCS}/SDL2OGL3
)

set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake_utils )

find_package( OpenGL REQUIRED )
find_package( GLEW   REQUIRED )
find_package( GLU    REQUIRED )
find_package( SDL2   REQUIRED )

# ==== Particular build target

add_executable       ( test_SphereShader test_SphereShader.cpp )
target_link_libraries( test_SphereShader ${OpenGL_LIBRARY} ${GLU_LIBRARY} ${GLEW_LIBRARY} ${SDL2_LIBRARY} )
file( COPY ${CMAKE_CURRENT_SOURCE_DIR}/shaders DESTINATION ${CMAKE_CURRENT_BINARY_DIR} )

【问题讨论】:

  • 你检查过this question吗?它的两个答案都适合您的目的。

标签: c++ cmake resources shader


【解决方案1】:

您可以提供一个自定义目标,然后将其转换为二进制文件test_SphereShader 的依赖项:

ADD_CUSTOM_TARGET(
        copy_shader_files
        ${CMAKE_COMMAND}
        -D SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
        -D DESTINATION_DIR=${CMAKE_CURRENT_BINARY_DIR} 
        -P CopyFile.cmake
        COMMENT "Copying Files for target: test_SphereShader" VERBATIM 
        )

ADD_DEPENDENCIES ( test_SphereShader copy_shader_files )

使用自定义目标调用一个新的 CMake 实例,其中包含一个脚本文件 CopyFile.cmake,其中包含您的复制命令:

file( COPY ${CMAKE_CURRENT_SOURCE_DIR}/shaders DESTINATION ${CMAKE_CURRENT_BINARY_DIR} )

这样每次调用makemake test_SphereShader 时都会复制文件。您甚至可以拨打make copy_shader_files 手动复制。

【讨论】:

  • 对不起,我试过后忘记接受答案了......效果很好
  • 在您的代码中,您没有使用 -D SOURCE_DIR= 。和 -D DESTINATION_DIR= ... 可以删除这些行。除非您想将 CopyFile.cmake 更改为更通用。
【解决方案2】:

我对接受的解决方案有一些问题。最大的问题是它没有将文件夹放在某些 IDE 的可执行文件目录中,例如 XCode。这是因为 XCode 中的 ${CMAKE_CURRENT_BINARY_DIR} 不是实际二进制文件所在的位置,它们通常是更深的一个目录,例如 /Debug/executable。要获取该目录,您可以使用 $ 但它似乎不适用于 cmake 脚本。

我还没有找到完美的解决方案,但我目前正在使用选项 1。如果我了解更多信息,我会更新它。如果有人知道如何解决选项 1 的缺点,我会非常高兴。

选项 1:add_custom_commandcopy_directory

add_custom_command(
         TARGET MY_TARGET POST_BUILD
         COMMAND ${CMAKE_COMMAND} -E copy_directory              
             ${CMAKE_SOURCE_DIR}/shaders $<TARGET_FILE_DIR:MY_TARGET>/shaders
         COMMENT "Copying shaders" VERBATIM
         )

MY_TARGET 更改为您使用 add_executable 或类似文件创建的目标。 还将 /shaders 更改为您的着色器目录的名称。 -E copy_directory 应该保持原样,因为它正在调用 cmake 中的 copy_directory 内置函数。

优点:

  • 单一命令,无需额外文件
  • 复制到更多IDE中包含二进制文件的目录
  • 每次重新构建目标时都会生成新副本。对于 Xcode,它也适用于仅更改着色器的情况。

缺点:

  • 使用make(至少在Mac 上)时,如果仅更改了着色器,则会跳过复制步骤。如果有人知道在这种情况下强制重建的正确方法,请告诉我。在 Xcode 中不会发生。

选项 2:add_custom_commandcreate_symlink

add_custom_command(
         TARGET MY_TARGET POST_BUILD
         COMMAND ${CMAKE_COMMAND} -E create_symlink              
             ${CMAKE_SOURCE_DIR}/shaders $<TARGET_FILE_DIR:MY_TARGET>/shaders
         COMMENT "Creating symlink to shader directory" VERBATIM
         )

MY_TARGET 更改为您使用 add_executable 或类似文件创建的目标。 还将 /shaders 更改为您的着色器目录的名称。 -E create_symlink 应该保持原样,因为它正在调用 cmake 中的 create_symlink 内置函数。

优点:

  • 基于单一目标的命令
  • 由于它创建了指向着色器/资产文件夹的符号链接,因此可以立即观察到着色器的任何更改,而无需重新构建。可能会将其移至其他仅在第一次 cmake 调用时执行的 cmake 命令

缺点:

  • 警告:这应该在 Windows 上不起作用
  • 虽然它适用于基于 unix 的开发,但请确保您最终不会尝试将带有符号链接的内容发送到用户没有的文件夹。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多