如何在阻止CMake源码内构建后删除生成的文件?
解决CMake源码内构建检测后无法删除CMakeCache.txt的问题
问题描述
我在CMake项目中使用以下代码检测源码内构建:
cmake_minimum_required(VERSION 3.29) project( NoInSource ) function( NoInSourceBuilds ) if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} ) execute_process(COMMAND ${CMAKE_COMMAND} -E rm CMakeCache.txt) message(FATAL_ERROR "In-source builds are not allowed!") endif() endfunction() NoInSourceBuilds() message( "Won't get here")
执行命令cmake -B . -S .触发源码内构建时,代码可正确检测,但无法删除生成的CMakeCache.txt文件。需要找到在退出前删除生成文件的方法,且不能使用任何未文档化变量。
解决方案
核心原因是execute_process执行时,CMake已锁定CMakeCache.txt文件,导致删除失败。以下是两种合规的解决方式:
方法一:将检测逻辑提前到project命令之前
project命令会自动生成CMakeCache.txt并锁定文件,把检测逻辑移到project之前,此时缓存文件要么未生成,要么未被锁定,file(REMOVE)可以顺利执行:
cmake_minimum_required(VERSION 3.29) # 提前检测源码内构建 if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) # 删除缓存文件 file(REMOVE ${CMAKE_SOURCE_DIR}/CMakeCache.txt) # 清理自动生成的CMakeFiles目录 file(REMOVE_RECURSE ${CMAKE_SOURCE_DIR}/CMakeFiles) message(FATAL_ERROR "In-source builds are not allowed!") endif() project(NoInSource) message("Won't get here")
这种方式从根源避免了文件锁定问题,是最可靠的解决方案。
方法二:使用临时脚本延迟删除(备选)
如果必须在project之后检测,可以生成临时CMake脚本,通过cmake -P执行删除操作:
cmake_minimum_required(VERSION 3.29) project(NoInSource) function(NoInSourceBuilds) if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) # 生成清理脚本 file(WRITE ${CMAKE_BINARY_DIR}/cleanup.cmake " file(REMOVE ${CMAKE_BINARY_DIR}/CMakeCache.txt) file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/CMakeFiles) ") # 执行清理脚本 execute_process(COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cleanup.cmake) message(FATAL_ERROR "In-source builds are not allowed!") endif() endfunction() NoInSourceBuilds() message("Won't get here")
注意:这种方式仍可能因文件锁定导致删除失败,仅作为方法一的备选方案。
内容的提问来源于stack exchange,提问作者CodingFrog
相关产品推荐
相关产品推荐

