1、CMAKE_INSTALL_PREFIX:安装路径的设置与使用
1.1、什么是CMAKE_INSTALL_PREFIX
CMAKE_INSTALL_PREFIX 是 CMake 中用于指定项目安装路径的变量。当我们使用 make install 或 cmake --install 命令时,生成的文件(如可执行文件、库文件、头文件等)会被安装到 CMAKE_INSTALL_PREFIX 指定的目录中。
- 在 Linux/macOS 上,CMAKE_INSTALL_PREFIX 的默认值是 /usr/local
- 在 Windows 上,默认值通常是 C:/Program Files/${PROJECT_NAME}
1.2、如何设置CMAKE_INSTALL_PREFIX
- 在命令行中设置
cmake -B build -DCMAKE_INSTALL_PREFIX=/path/to/install
- 在CMakeLists.txt中设置
set(CMAKE_INSTALL_PREFIX "/path/to/install")
1.3、使用CMAKE_INSTALL_PREFIX
如果设置了CMAKE_INSTALL_PREFIX路径,
install(TARGETS my_target DESTINATION bin)
install(FILES my_header.h DESTINATION include)
上述代码会将 my_target 安装到 ${CMAKE_INSTALL_PREFIX}/bin,将 my_header.h 安装到 ${CMAKE_INSTALL_PREFIX}/include。
- CMAKE_INSTALL_PREFIX 的设置应尽量在配置阶段完成,避免在构建阶段修改。
- 如果未显式设置 CMAKE_INSTALL_PREFIX,CMake 会使用默认值。
2、option 定义变量时,不同级别 CMakeLists.txt 中的覆盖规则
option 是 CMake 中用于定义布尔变量的命令,通常用于控制编译选项或功能开关。在 CMake 项目中,可能存在多个 CMakeLists.txt 文件(例如,根目录和子目录中各有一个)。如果在不同级别的 CMakeLists.txt 中定义了同名的 option 变量,它们的值会如何覆盖呢?覆盖的规则如下:
- 父目录的 option 优先于子目录:如果在父目录的 CMakeLists.txt 中定义了 option,子目录中的同名 option 不会覆盖父目录的值。
# 父目录 CMakeLists.txt
option(ENABLE_FEATURE "Enable feature in parent" ON)# 子目录 CMakeLists.txt
option(ENABLE_FEATURE "Enable feature in child" OFF)
最终 ENABLE_FEATURE 的值是 ON,因为父目录的定义优先。
- 命令行参数可以覆盖所有 option:
如果在命令行中通过 -D 指定了 option 的值,它会覆盖所有 CMakeLists.txt 中的定义。
cmake -B build -DENABLE_FEATURE=OFF
无论 CMakeLists.txt 中如何定义 ENABLE_FEATURE,最终值都是 OFF。
- set 命令可以覆盖 option:
如果在 CMakeLists.txt 中使用 set 命令显式设置 option 变量,它会覆盖 option 的定义。
option(ENABLE_FEATURE "Enable feature" ON)
set(ENABLE_FEATURE OFF)
最终 ENABLE_FEATURE 的值是 OFF。
2.1、option使用示例
假设项目结构如下:
project/
├── CMakeLists.txt
└── subdir/└── CMakeLists.txt
- 父目录 CMakeLists.txt:
option(ENABLE_FEATURE "Enable feature in parent" ON)
- 子目录 CMakeLists.txt:
option(ENABLE_FEATURE "Enable feature in child" OFF)
- 命令行调用:
cmake -B build -DENABLE_FEATURE=ON
最终 ENABLE_FEATURE 的值是 ON,因为命令行参数优先级最高。
3、总结
- CMAKE_INSTALL_PREFIX 是 CMake 中用于指定安装路径的变量,可以通过命令行、CMakeLists.txt设置。合理使用它可以方便地管理项目的安装目录。
- option 变量的覆盖规则:父目录的 option 优先于子目录;命令行参数可以覆盖所有 CMakeLists.txt 中的 option;set 命令可以覆盖 option 的定义