CMake:软链接资源(如 GLSL 着色器)或复制每个编译
CMake : softlink resource ( such as GLSL shaders ) or copy each complilation
使用 CMake 将资源从源目录复制到构建目录的最简单方法是
file( COPY ${CMAKE_CURRENT_SOURCE_DIR}/resources DESTINATION ${CMAKE_CURRENT_BINARY_DIR} )
但是,这仅在 我调用 cmake
时更新构建目录 中的资源。每次我调用 make
.
时,我都需要更新资源
例如现在我开发了一些 GLSL 着色器。我需要同时更改 C++ 代码和 GLSL 代码,并且我需要 每次我在我的 [=36= 中点击 compile
或 run
时一切都同步](我将 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} )
您可以提供自定义目标,将其转换为二进制文件的依赖项 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} )
这样,每次调用 make
或 make test_SphereShader
时都会复制文件。您甚至可以手动复制调用 make copy_shader_files
.
我对已接受的解决方案有一些疑问。最大的问题是它没有将文件夹放在某些 IDE 的可执行文件目录中,例如 XCode。这是因为 XCode 中的 ${CMAKE_CURRENT_BINARY_DIR}
不是实际二进制文件所在的位置,它们通常在 /Debug/executable
等更深的目录中。要获取该目录,您可以使用 $ 但它似乎不适用于 cmake 脚本。
我还没有找到完美的解决方案,但我目前正在使用选项 1。如果我了解更多,我会更新它。如果有人知道如何解决选项 1 的缺点,我会很高兴。
选项 1:add_custom_command
和 copy_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_command
和 create_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
内置函数。
优点:
- 基于单一目标的命令
- 因为它为 shader/asset 文件夹创建了一个 symlink ,所以对着色器的任何更改都会立即被观察到,根本不需要重建。可能会将其移动到其他仅在第一次调用 cmake 时执行的 cmake 命令
缺点:
- 警告: 这据说 不适用于 Windows
- 虽然它适用于基于 unix 的开发,但请确保您最终不会尝试将带有符号 link 的内容发送到您的用户不会拥有的文件夹中。
使用 CMake 将资源从源目录复制到构建目录的最简单方法是
file( COPY ${CMAKE_CURRENT_SOURCE_DIR}/resources DESTINATION ${CMAKE_CURRENT_BINARY_DIR} )
但是,这仅在 我调用 cmake
时更新构建目录 中的资源。每次我调用 make
.
例如现在我开发了一些 GLSL 着色器。我需要同时更改 C++ 代码和 GLSL 代码,并且我需要 每次我在我的 [=36= 中点击 compile
或 run
时一切都同步](我将 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} )
您可以提供自定义目标,将其转换为二进制文件的依赖项 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} )
这样,每次调用 make
或 make test_SphereShader
时都会复制文件。您甚至可以手动复制调用 make copy_shader_files
.
我对已接受的解决方案有一些疑问。最大的问题是它没有将文件夹放在某些 IDE 的可执行文件目录中,例如 XCode。这是因为 XCode 中的 ${CMAKE_CURRENT_BINARY_DIR}
不是实际二进制文件所在的位置,它们通常在 /Debug/executable
等更深的目录中。要获取该目录,您可以使用 $ 但它似乎不适用于 cmake 脚本。
我还没有找到完美的解决方案,但我目前正在使用选项 1。如果我了解更多,我会更新它。如果有人知道如何解决选项 1 的缺点,我会很高兴。
选项 1:add_custom_command
和 copy_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_command
和 create_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
内置函数。
优点:
- 基于单一目标的命令
- 因为它为 shader/asset 文件夹创建了一个 symlink ,所以对着色器的任何更改都会立即被观察到,根本不需要重建。可能会将其移动到其他仅在第一次调用 cmake 时执行的 cmake 命令
缺点:
- 警告: 这据说 不适用于 Windows
- 虽然它适用于基于 unix 的开发,但请确保您最终不会尝试将带有符号 link 的内容发送到您的用户不会拥有的文件夹中。