cmake安装与基础语法学习3--之cmake编译构建
编译构建
通过cmake命令将CMakeLists.txt文件转化为make所需的Makefile文件
再用make命令编译源代码生成可执行程序或库文件
示例流程图如下:
1) 构建模式
CMake 支持两种构建模式,分别为 in-source build(源码中构建),out-of-source build(源码外构建),下面分别来介绍一下这两种模式。
1.1> in-source build 模式
在源文件目录下构建,产生的二进制文件将与源文件生成在一个文件夹里。想要执行就地构建,只需要在源码文件夹运行命令 cmake .,和之前说过的一样,CMake 只是生成了构建工具需要的文件,具体的目标构建还需要构建工具来做,因此还需要运行 cmake --build 执行构建。
2.2> out-of-source build 模式
单独创建一个比如 build 文件夹,在该文件夹下构建二进制文件,与源代码文件分开。执行源码外构建,需要运行如下命令。
mkdir build;
cd ./build
cmake ..
cmake --build
注: 一般使用源码外构建模式
2) 生成构建系统
基本构建语法:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/path
cmake --build build -j4
cmake --install build/linux
2.1> 构建
cmake -S . -B build
#Configuration 阶段,为不同的构建工具生成相应文件。
cmake 读取 CMakeLists.txt 同时收集环境及项目配置信息,写入 CMakeCache.txt 中。此时在build目录下会生成 Makefile 文件。
-S后接的位置是查找CMakeLists的位置,-S选项可以整体缺省,默认会使用当前目录
-B后接的位置是生成的构建系统存放的位置,也就是build子目录(如果不存在,则会自动创建)
-D 设置变量
2.2> 执行构建
cmake --build build
使用构建工具构建默认 target,在build子目录下执行构建,生成目标targets文件(如可执行文件、库等);或者可以进入build目录后,使用cmake --build .,效果一样。
–build 指定编译生成的文件存放目录,其中就包括可执行文件
-j4 在编译时,我们可以添加选项让它进行多核编译加速
可以添加-v 或–verbose显示编译细节
2.3> 安装文件
cmake --install build/linux
安装路径build/linux
cmake --install 是CMake工具的一个重要组成部分,它的主要功能是将构建的目标(如可执行文件、库等)和其他相关文件(如头文件、配置文件等)安装到指定的位置。这个过程是通过在CMakeLists.txt文件中使用install命令来实现的。
2.3.1 目标(Targets)
目标(Targets)是CMake Install的核心概念之一。在CMake中,目标主要指的是我们需要构建的项目,比如一个可执行文件、一个库等。我们可以通过add_executable或add_library命令来创建一个目标,然后通过target_link_libraries命令来为目标添加依赖。例如:CMakeLists.txt(2)文件中的:
2.3.2 安装路径(Install Paths)
安装路径(Install Paths)是指定目标安装的位置。在CMake中,我们可以通过CMAKE_INSTALL_PREFIX变量来设置安装路径的前缀,然后在install命令中通过DESTINATION参数来指定目标的具体安装位置。
3) 构建目标
以面向对象的思路来编写CMakeLists: 把生成的可执行文件,生成的静态动态库都统一成构建目标(target),围绕着target使用形如target_xxx的命令添加源文件,添加依赖关系,添加属性等等。
target大致有以下的类型:
3.1> 可执行文件target
使用源文件test.cpp编译得到可执行文件test
add_executable(test)
target_sources(test PRIVATE test.cpp)
# or
add_executable(test PRIVATE test.cpp)
3.2> 静态库target
使用源文件static_fun.cpp编译得到静态库static_fun
add_library(static_fun STATIC)
target_sources(static_fun PRIVATE static_fun.cpp)
# ${PROJECT_SOURCE_DIR}/include是编译时和使用时都需要使用的头文件搜索路径
target_include_directories(static_fun PUBLIC ${PROJECT_SOURCE_DIR}/include)
3.3> 动态库target
使用源文件shared_fun.cpp编译得到动态库shared_fun
add_library(shared_fun SHARED)
target_sources(shared_fun PRIVATE shared_fun.cpp)
# ${PROJECT_SOURCE_DIR}/include是编译时和使用时都需要使用的头文件搜索路径
target_include_directories(shared_fun PUBLIC ${PROJECT_SOURCE_DIR}/include)
3.4> 特殊的库
CMake还允许一些特殊的库,比如由.o文件组成的OBJECT库(主要为了节约编译时间),或者仅仅由头文件组成的INTERFACE库(header-only)
add_library(demo SHARED)
add_library(Demo::demo ALIAS demo)
注:
add_library可以缺省STATIC|SHARED参数,此时默认为STATIC全部生成静态库,但是也可以通过指定BUILD_SHARED_LIBS为真,修改默认值为SHARED全部生成动态库
动态库目标会默认启动代码与位置无关的选项(POSITION_INDEPENDENT_CODE),相当于GCC的-fPIC选项,对于静态库则不会自动启用
支持对目标起一个别名,这通常是为了增加命名空间前缀,在被链接时和导入的第三方依赖的命名风格保持一致。