MinGW环境下CMake调用sed修改文件失败问题求助
问题:MinGW环境下CMake调用sed替换文件内容失败
场景与代码
在MinGW环境中,尝试通过CMake的execute_process调用sed命令,将Boost相关cmake文件中的"mgw131替换为"mgw13,原CMake代码如下:
if(WIN32 OR MINGW) # set Boost_COMPILER to mgw13, to avoid (mgw131, detected mgw13, set Boost_COMPILER to override) error with boost_random message(STATUS "[build_cots.cmake]: set 'mgw13' value to Boost_COMPILER and BOOST_DETECTED_TOOLSET for Windows") set(Boost_COMPILER "mgw13") set(BOOST_DETECTED_TOOLSET "mgw13") # change cmake mgw version from mgw131 to mgw13 to make it work execute_process(COMMAND echo Before sed COMMAND sed -i 's/"mgw131/"mgw13/g' libboost_random-variant-mgw131-mt-d-x64-1_70-static.cmake COMMAND echo After sed WORKING_DIRECTORY "/builds/sdo/drama_oscar/attitude_simulator/ExternalProject/Install/Boost/lib/cmake/boost_random-1.70.0" COMMAND_ECHO STDOUT COMMAND_ERROR_IS_FATAL ANY) endif()
错误日志
执行后出现如下错误:
[100%] Built target Boost -- [build_cots.cmake]: set 'mgw13' value to Boost_COMPILER and BOOST_DETECTED_TOOLSET for Windows 'echo' 'Before' 'sed' 'sed' '-i' ''s/"mgw131/"mgw13/g'' 'libboost_random-variant-mgw131-mt-d-x64-1_70-static.cmake' 'echo' 'After' 'sed' After sed sed: -e expression #1, char 1: unknown command: `'' CMake Error at cots/build_cots.cmake:77 (execute_process): execute_process failed command indexes: 2: "Child return code: 1" Call Stack (most recent call first): CMakeLists.txt:53 (include) -- Configuring incomplete, errors occurred!
错误原因
从日志可见,CMake对sed命令的参数解析出了问题:替换表达式被错误添加了额外的单引号,变成''s/"mgw131/"mgw13/g'',导致sed无法识别合法的替换命令。这是CMake处理带引号的外部命令参数时的转义冲突问题。
解决思路
方案1:修正sed命令的参数写法
调整CMake中sed命令的引号使用,避免参数被错误拆分:
execute_process(COMMAND echo Before sed COMMAND sh -c "sed -i 's/\"mgw131/\"mgw13/g' libboost_random-variant-mgw131-mt-d-x64-1_70-static.cmake" COMMAND echo After sed WORKING_DIRECTORY "/builds/sdo/drama_oscar/attitude_simulator/ExternalProject/Install/Boost/lib/cmake/boost_random-1.70.0" COMMAND_ECHO STDOUT COMMAND_ERROR_IS_FATAL ANY)
通过sh -c将整个sed命令作为单个字符串传递,让shell来解析参数,避免CMake的拆分错误。
方案2:使用CMake原生命令替换(推荐)
完全避免依赖外部sed工具,用CMake内置的file和string命令完成替换,跨平台更可靠:
if(WIN32 OR MINGW) # set Boost_COMPILER to mgw13, to avoid (mgw131, detected mgw13, set Boost_COMPILER to override) error with boost_random message(STATUS "[build_cots.cmake]: set 'mgw13' value to Boost_COMPILER and BOOST_DETECTED_TOOLSET for Windows") set(Boost_COMPILER "mgw13") set(BOOST_DETECTED_TOOLSET "mgw13") # 用CMake原生命令替换字符串 set(BOOST_RANDOM_CMAKE_FILE "/builds/sdo/drama_oscar/attitude_simulator/ExternalProject/Install/Boost/lib/cmake/boost_random-1.70.0/libboost_random-variant-mgw131-mt-d-x64-1_70-static.cmake") file(READ "${BOOST_RANDOM_CMAKE_FILE}" FILE_CONTENT) string(REPLACE "\"mgw131" "\"mgw13" FILE_CONTENT "${FILE_CONTENT}") file(WRITE "${BOOST_RANDOM_CMAKE_FILE}" "${FILE_CONTENT}") endif()
该方法不依赖任何外部工具,完全由CMake处理,不会出现平台间工具差异或参数解析问题。
内容的提问来源于stack exchange,提问作者RUBEN IÑIGO TEJEDOR
相关产品推荐
相关产品推荐

