Visual Studio中CMake构建后跨平台访问额外资源的解决方案咨询
嘿,我来帮你搞定这个跨平台资源访问的问题!你遇到的情况太常见了——用CMake在Visual Studio里搭好项目后,额外的资源目录没法被可执行文件找到,硬编码路径又没法在不同系统上跑,确实头疼。下面给你两种靠谱的CMake解决方案,全都是跨平台兼容的:
方法一:简单直接的实时复制法
如果追求快速落地,直接在项目目录的CMakeLists.txt里加这段代码就行:
# 把源码目录下的somefiles完整复制到可执行文件所在的构建目录 file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/somefiles DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
这里CMAKE_CURRENT_SOURCE_DIR是当前CMakeLists.txt所在的源码根目录,CMAKE_CURRENT_BINARY_DIR是CMake生成的构建目录(也就是你的可执行文件最终输出的地方)。CMake会自动处理Windows、Linux、macOS之间的路径分隔符差异,不用你手动适配斜杠或者系统命令。
加完这段后,每次构建时CMake都会把somefiles目录完整复制到可执行文件旁边,你在C++代码里直接用相对路径就能访问:
std::ifstream infile("./somefiles/test.txt");
方法二:高效的增量复制法(更推荐)
上面的方法每次构建都会复制一遍资源,哪怕资源根本没变化。如果你的somefiles里文件比较多或者经常修改,推荐用自定义命令和目标来实现增量复制——只有当资源文件更新时才会重新复制,能省不少构建时间:
# 定义复制资源的自定义命令 add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/somefiles COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/somefiles ${CMAKE_CURRENT_BINARY_DIR}/somefiles DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/somefiles COMMENT "正在复制资源文件到构建目录..." ) # 创建自定义目标,关联复制命令 add_custom_target(CopyResources ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/somefiles ) # 让可执行文件依赖这个目标,确保编译前先复制资源 add_dependencies(CMake_visual_studio_test CopyResources)
这里${CMAKE_COMMAND} -E copy_directory是CMake自带的跨平台目录复制工具,完全不用操心不同系统的复制命令差异。add_dependencies能保证,只要你构建可执行文件,就一定会先把资源复制好,不会出现“编译完找不到资源”的尴尬情况。
补充:代码里的路径写法
不管用哪种方法,你在C++代码里都直接用相对路径就行,比如上面的./somefiles/test.txt——因为资源目录和可执行文件在同一个层级下,这种写法跨平台都能识别。
如果你的资源特别大或者需要加密,还有一种方法是把资源嵌入到可执行文件里,但这种方法修改资源后必须重新编译,灵活性远不如复制目录,所以更推荐前面两种方法。
备注:内容来源于stack exchange,提问作者pavo

