【CMake】CMakeLists.txt的超详细教程,带你进入第一个项目

       用了几次CMakeLists进行编译,下一次再用还是感觉乱乱的,这一次,把思路整理一下,认真学习一下CMakeLists应如何编写。 

1、CMakeLists的作用

将一个.c或.cpp文件编译成目标文件时,CMakeLists定制整个编译流程,当编译涉及多个文件时,用来安排文件编译的先后顺序。

2、如何编写CMakeLists,一些基本语法

需要先了解一些基础的语法(只列出了一些用过的,其他的之后用过再补充呀~)

指令1cmake_minimum_required

基本格式:cmake_minimum_required(VERSION <min>[...<max>])

说明:该指令指明了项目编译时要求的cmake的最低或最高版本。

例如:cmake_minimum_required(VERSION 3.17) #要求cmake的最低版本是3.17,编译时环境中的cmake版本要高于3.17才可顺利进行编译。

如果环境中的cmake版本为3.16.3,低于要求的最低版本3.17,编译时就会出现如下错误:

备注:也可以使用“...”(三个点)来连接cmake的最低版本和最高版本,例如cmake_minimum_required(VERSION 3.2...3.17)表示要求cmake版本在3.2和3.17之间。

指令2project

基本格式:project(ProjectName)

说明:指明编译项目的名称,其中ProjectName表示项目名称,设置好后,后面可用变量PROJECT_NAME来指代项目名称。

例如:project(demo)  创建的项目名称为demo .

指令3add_compile_options

基本格式:add_compile_options(<option> ...)

说明:为当前路径和下层路径的目标增加编译器命令行选项。需要注意的是,这个命令是针对所有类型编译器的,这里添加的选项会在所有的编译器中运用,比如-std=c++11是针对C++的编译器参数,也会被运用在C语言编译器中,可能会产生一些警告。可以使用其他命令单独设置某一编译器的编译选项。

例如:add_compile_options(-std=c++11)表示为所有编译器添加c++11支持。

指令4include_directories

基本格式:include_directories([AFTER | BEFORE] [SYSTEM] dir1 [dir2…])

说明:用于在构建build中设置包含目录,主要是将指定目录添加到编译器的头文件搜索目录。默认情况下,该指令会将目录添加到列表最后(AFTER选项),可以使用AFTER或BEFORE选项来指定将目录添加到列表的前面还是后面。如果使用SYSTEM选项,会把指定目录当成系统的搜索目录,作用范围只在当前的CMakeLists.txt。

例如:include_directories(/usr/include/abc /usr/include/xxx)是将“/usr/include/abc”和“/usr/include/xxx”这两个目录添加至编译器的头文件搜索目录(两个目录用空格分隔)。

指令5aux_source_directory

基本格式:aux_source_directory(<dir> < variable >)

说明:用于查找目录中的所有源文件(编译的就是源文件~)。收集dir目录中的所有源文件名称,并将列表存储在variable中,之后使用$ {variable}指代目录中的所有源文件

例如:aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/demo DIR_SRCS)是指查找CMakeLists.txt所在目录下,demo目录中的所有源文件,将名称保存在DIR_SRCS变量中,后面需要源文件时,可以使用${DIR_SRCS}.

指令6link_directories

基本格式:link_directories(directory1 [directory2 ...])

说明:用于添加库文件目录,在编译项目时依赖了某些库文件,使用本命令添加搜索目录(对应着directory1,directory2 …),就会在目录中搜索库文件。

备注:此命令尽可能避免使用,防止搜索库路径本地化而不准确,可使用target_link_directories来提供搜索路径或添加链接库。

指令7target_link_directories

基本格式:target_link_directories(<target>  <INTERFACE | PUBLIC | PRIVATE> [item1] [<INTERFACE | PUBLIC | PRIVATE> [item2...] ...])

说明:为特定的目标(target)添加链接库目录, INTERFACE、PUBLIC、PRIVATE是可选范围参数,比如target1 PUBLIC链接/map/bin/文件夹,该文件夹中有一些头文件,若target2链接了target1,就会链接到/map/bin/下的头文件(头文件传播)。该目标必须是已经通过add_executable()add_library()等命令创建出来的目标,所以该命令应该放在add_executable()add_library()这两个命令之后。

例如:add_executable(${PROJECT_NAME} ${DIR_SRCS})

           target_link_directories(${PROJECT_NAME} /home/workspace/)

使用add_executable指令生成可执行文件,如前文所述,${DIR_SRCS}指代目录中所有源文件,用这些源文件生成可执行文件,可执行文件名称为${PROJECT_NAME}(与项目名称同名,前文中设成了demo).这个生成的可执行文件就是target_link_directories命令中的target,我们为该target添加了库文件搜索目录/home/workspace/ .

指令8add_library

基本格式:add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] [source1] [source2] [...])

说明:该命令是将指定的源文件生成链接文件,然后添加到工程中去。其中,source1,source2…是源文件(通常是.cpp和.h等), name是生成的链接文件的名称,STATIC表示将源文件生成静态链接库,SHARED表示生成动态链接库。

例如:add_library(xlog STATIC xlog.cpp)是将xlog.cpp文件编译成静态链接库文件,名字设置成xlog(实际生成的静态链接库文件名称为libxlog.a)。

指令9add_executable

基本格式:add_executable(<name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] [source1][source2...])

说明:通过编译源文件来创建一个可执行文件,其中,name是生成的可执行文件的名称,source是创建可执行文件所需要的源文件。源文件可以使用aux_source_directory指令返回的变量(将源文件保存在这个变量中),也可以是指定的.cpp文件(注意路径)。

例如:add_executable(hello ${DIR_SRCS})使用aux_source_directory指令返回的变量DIR_SRCS,用变量内的源文件生成可执行文件,名称为hello.

指令10target_link_libraries

基本格式:target_link_libraries(<target> [item1] [item2] [...] [[debug|optimized|general] <item>] ...)

说明:将目标文件与库文件进行链接,当编译项目时,可能依赖一些动态库,指令9是将目标与库文件链接起来。其中target是通过add_executable()和add_library()指令生成已经创建的目标文件。而[item]表示库文件(没有后缀)。

例如:target_link_libraries(myProject hello) 中target是myProject,链接libhello.so库。

3、使用set设置一些变量

第一种:set直接设置变量的值

例如:set(ROOTDIR /home/workspace) #给变量ROOTDIR赋值为/home/workspace,后面使用${ ROOTDIR }就表示/home/workspace这个路径。

第二种:设置编译选项

例如:set(CMAKE_BUILD_TYPE “Release”)#设置构建类型,“Release”表示用于构建的库或可执行文件,没有调试符号;也可设成“Debug”,表示生成的库或可执行文件包含调试符号,通常用于开发和调试期间。需要注意,这一设置需要在添加target之前。

例如:set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")#针对C++编译器设置编译选项,无默认值。本例中给出的指令表示C++编译器添加c++11的支持。

4、有了语法基础,如何编译一个简单的项目?

Step1:创建一个文件夹,名称为hello,包含如下两个文件:

hello.cpp是想要编译的文件,代码内容为:

#include<iostream>
using namespace std;
int main(){
        std::cout << "hello world!!"<<std::endl;
}

接下来编写CMakeLists.txt编译该源文件,

cmake_minimum_required(VERSION 3.2)#设置cmake的最低版本,编译环境中的cmake要高于这个版本

project(hello)#设置项目名称

add_executable(hello hello.cpp)#生成可执行文件hello,使用的源文件是hello.cpp.

Step2:编译

mkdir build  #在hello文件夹下创建build文件夹

cd build     #进入到build文件夹

cmake ..     #该命令会使用CMakeLists.txt生成Makefile文件

make -j      #该命令会使用Makefile文件编译项目

step3:编译完成后,进入build文件夹,可以看到名为hello的可执行文件

执行如下命令:

./hello   #运行生成的可执行文件

输出如下:

这样就完成了一个简单的例子。一些复杂的情况可参考上述指令进行添加。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值