CMAKE_COMMAND 变量详解
📖 什么是 CMAKE_COMMAND?
CMAKE_COMMAND是 CMake 的一个内置变量,它存储了当前使用的 CMake 可执行文件的完整路径。
🔍 基本概念
变量值
CMAKE_COMMAND的值通常是:
- Windows:
C:/Program Files/CMake/bin/cmake.exe或类似路径 - Linux/macOS:
/usr/bin/cmake或/usr/local/bin/cmake
查看变量值
你可以在 CMakeLists.txt 中查看它的值:
message(STATUS "CMAKE_COMMAND = ${CMAKE_COMMAND}")输出示例:
CMAKE_COMMAND = C:/Program Files/CMake/bin/cmake.exe🎯 为什么使用 CMAKE_COMMAND?
1. 跨平台兼容性
使用${CMAKE_COMMAND}可以确保命令在所有平台上都能正确执行,因为:
- 不需要硬编码 CMake 的路径
- CMake 会自动找到正确的可执行文件
- 支持不同的安装位置
2. 使用 CMake 的命令模式(-E 参数)
CMAKE_COMMAND最常用的方式是配合-E参数,执行 CMake 内置的跨平台命令。
📚 CMAKE_COMMAND -E 命令模式
语法
${CMAKE_COMMAND} -E <命令> [参数...]-E参数告诉 CMake 执行一个跨平台的文件操作命令。
常用命令
1. echo - 输出文本
${CMAKE_COMMAND} -E echo "Hello, World!"作用:跨平台输出文本(Windows 和 Unix 都支持)
等价命令:
- Windows:
echo Hello, World! - Linux:
echo Hello, World!
2. copy - 复制文件
${CMAKE_COMMAND} -E copy <源文件> <目标文件>示例:
${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/config.txt ${CMAKE_BINARY_DIR}/config.txt作用:跨平台复制文件
等价命令:
- Windows:
copy config.txt build\config.txt - Linux:
cp config.txt build/config.txt
3. copy_directory - 复制目录
${CMAKE_COMMAND} -E copy_directory <源目录> <目标目录>示例:
${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/resources ${CMAKE_BINARY_DIR}/resources4. make_directory - 创建目录
${CMAKE_COMMAND} -E make_directory <目录路径>示例:
${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/output作用:跨平台创建目录(包括父目录)
等价命令:
- Windows:
mkdir output或md output - Linux:
mkdir -p output
5. remove - 删除文件
${CMAKE_COMMAND} -E remove <文件路径>示例:
${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/temp.txt6. remove_directory - 删除目录
${CMAKE_COMMAND} -E remove_directory <目录路径>示例:
${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/output7. touch - 创建或更新时间戳
${CMAKE_COMMAND} -E touch <文件路径>示例:
${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/timestamp.txt8. tar - 打包/解包
# 打包 ${CMAKE_COMMAND} -E tar czf <压缩包> <文件或目录> # 解包 ${CMAKE_COMMAND} -E tar xzf <压缩包>示例:
# 创建压缩包 ${CMAKE_COMMAND} -E tar czf ${CMAKE_BINARY_DIR}/my_app.tar.gz $<TARGET_FILE:my_app> # 解压压缩包 ${CMAKE_COMMAND} -E tar xzf archive.tar.gz参数说明:
c= create(创建)x= extract(解压)z= gzip(压缩/解压)f= file(文件)
💡 实际应用示例
示例1:在自定义命令中使用
add_custom_command( TARGET my_app POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:my_app> ${CMAKE_BINARY_DIR}/bin/$<TARGET_FILE_NAME:my_app> COMMENT "复制可执行文件" )示例2:在自定义目标中使用
add_custom_target(setup COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/output COMMAND ${CMAKE_COMMAND} -E echo "设置完成" COMMENT "初始化构建环境" )示例3:链式命令
add_custom_command( TARGET my_app POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "构建完成!" COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/resources $<TARGET_FILE_DIR:my_app>/resources COMMAND ${CMAKE_COMMAND} -E echo "资源文件已复制" )⚠️ 注意事项
1. 不要使用平台特定命令
错误示例:
# Windows 特定(在 Linux 上会失败) COMMAND copy file1.txt file2.txt # Linux 特定(在 Windows 上会失败) COMMAND cp file1.txt file2.txt正确示例:
# 跨平台 COMMAND ${CMAKE_COMMAND} -E copy file1.txt file2.txt2. 路径分隔符
CMake 会自动处理路径分隔符,所以:
- Windows: 可以使用
/或\ - Linux: 使用
/
# 这些都可以工作 ${CMAKE_COMMAND} -E copy src/file.txt build/file.txt ${CMAKE_COMMAND} -E copy src\file.txt build\file.txt # Windows3. 变量展开
${CMAKE_COMMAND}会在配置阶段展开,所以:
- 不需要担心路径中的空格
- 不需要手动转义特殊字符
- CMake 会自动处理
🔍 查看所有可用命令
你可以运行以下命令查看所有可用的-E命令:
cmake-Ehelp输出示例:
CMake Error: No command specified Available commands: capabilities - Report capabilities built into cmake in JSON format chdir dir cmd [args...] - run command in a given directory compare_files file1 file2 - check if file1 is same as file2 copy <file>... destination - copy files to destination (either file or directory) copy_directory <dir>... <dest-dir> - copy content of <dir>... directories to <dest-dir> copy_if_different <file>... destination - copy files if it has changed echo [<string>...] - displays arguments as text echo_append [<string>...] - displays arguments as text but no new line env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]... - run command in a modified environment environment - display the current environment variables make_directory <dir>... - create directories md5sum <file>... - create MD5 checksum of files sha1sum <file>... - create SHA1 checksum of files sha224sum <file>... - create SHA224 checksum of files sha256sum <file>... - create SHA256 checksum of files sha384sum <file>... - create SHA384 checksum of files sha512sum <file>... - create SHA512 checksum of files remove [-f] <file>... - remove the file(s), use -f to force it remove_directory <dir>... - remove directories and their contents rename oldname newname - rename a file or directory (on one volume) server - start cmake in server mode sleep <number>... - sleep for given number of seconds tar [cxt][vf][zjJ] file.tar [file/dir ...] - create or extract a tar file time command [args...] - run command and display elapsed time touch <file>... - touch a file touch_nocreate <file>... - touch a file if it exists but do not create it true - do nothing with an exit code of 0📊 对比表
| 操作 | Windows 命令 | Linux 命令 | CMake 命令 |
|---|---|---|---|
| 复制文件 | copy file1.txt file2.txt | cp file1.txt file2.txt | ${CMAKE_COMMAND} -E copy file1.txt file2.txt |
| 创建目录 | mkdir dir | mkdir -p dir | ${CMAKE_COMMAND} -E make_directory dir |
| 删除文件 | del file.txt | rm file.txt | ${CMAKE_COMMAND} -E remove file.txt |
| 删除目录 | rmdir /s dir | rm -rf dir | ${CMAKE_COMMAND} -E remove_directory dir |
| 输出文本 | echo text | echo text | ${CMAKE_COMMAND} -E echo text |
🎯 总结
CMAKE_COMMAND= CMake 可执行文件的路径${CMAKE_COMMAND} -E= 使用 CMake 的跨平台命令模式优势:
- ✅ 跨平台兼容
- ✅ 自动处理路径
- ✅ 不需要硬编码路径
- ✅ 统一命令接口
最佳实践:
- 在自定义命令中优先使用
${CMAKE_COMMAND} -E - 避免使用平台特定的 shell 命令
- 利用 CMake 的跨平台能力
- 在自定义命令中优先使用
参考:
- CMake 官方文档 - Command-Line Tool
- CMake 官方文档 - CMAKE_COMMAND