如何配置CMake命令复制符号链接而不解析原文件?
解决CMake复制符号链接时保留链接而非原文件的问题
这个场景我太熟悉了——CMake 默认处理文件复制时会自动解析符号链接,把指向的原文件拷贝过去,而不是保留链接本身。要实现直接复制符号链接,分两种情况来处理最稳妥:
方法一:CMake 3.14 及以上版本(推荐)
从CMake 3.14开始,file(COPY)和install(FILES)命令都新增了NO_FOLLOW_SYMLINKS选项,专门用来保留符号链接,不用再折腾系统命令。
复制到构建目录
file(COPY ${source_file} DESTINATION ${destination_dir} NO_FOLLOW_SYMLINKS)
安装时保留符号链接
如果是要在install阶段保留符号链接,写法类似:
install(FILES ${source_file} DESTINATION ${install_dir} NO_FOLLOW_SYMLINKS)
这个选项的作用很直接:告诉CMake不要追踪符号链接的目标,直接复制链接文件本身,跨平台兼容性也很好,不用区分Windows/Unix。
方法二:CMake 3.14 以下版本(兼容方案)
如果你的项目还需要支持旧版本CMake,就得借助系统自带的命令来实现,分平台处理:
类Unix系统(Linux/macOS)
用cp -P命令(-P参数表示保留符号链接),配合add_custom_command来触发复制:
add_custom_command( OUTPUT "${destination_dir}/$<TARGET_FILE_NAME:${source_file}>" COMMAND cp -P "${source_file}" "${destination_dir}" DEPENDS "${source_file}" COMMENT "Copying symlink ${source_file} to ${destination_dir}" )
Windows系统
Windows下用mklink命令创建符号链接,注意需要管理员权限(如果是创建目录符号链接的话),可以加个判断先确认原文件是符号链接:
if(WIN32) # 检查目标是否为符号链接 execute_process(COMMAND cmd /c dir "${source_file}" | findstr "<SYMLINK>" OUTPUT_VARIABLE IS_SYMLINK OUTPUT_QUIET) if(IS_SYMLINK) add_custom_command( OUTPUT "${destination_dir}/$<TARGET_FILE_NAME:${source_file}>" COMMAND cmd /c mklink "${destination_dir}/$<TARGET_FILE_NAME:${source_file}>" "${source_file}" DEPENDS "${source_file}" COMMENT "Creating symlink for ${source_file} in ${destination_dir}" ) endif() endif()
注意事项
- 如果你用的是
configure_file命令,它默认会解析符号链接,这个命令没有类似的选项,所以这种情况只能用上面的自定义命令方案。 - Windows下创建符号链接可能需要管理员权限,如果你是普通用户运行CMake,可能会失败,这种情况可以考虑用硬链接或者调整权限。
内容的提问来源于stack exchange,提问作者Humam Helfawi
相关产品推荐
相关产品推荐

