CMake编译工具快速入门

1、CMake简介

CMake管理一个程序项目,实际上就是在源码根目录中建立一个CMakeLists.txt文件作为根节点,再通过add_subdirectory(subdir)包含其下级源码子目录,而下级源码目录中的CMakeLists.txt进一步通过add_subdirectory(subdir)包含其下级源码目录,最终把所有源码都串接在一起,同时所有的CMakeLists.txt文件也都串接在一起。

另外,每一个CMakeLists.txt都要求通过include_directories来为当前文件夹下的源码设置头文件搜索路径。对于多个源码子目录(多个CMakeLists.txt)的项目,任意指定其中一个源码目配置为编译成可执行文件,其他源码目录配置为编译成静态lib,并在任意一个CMakeLists.txt中,通过target_link_libraries将可执行文件跟所有的库(包括静态或动态库)连接在一起。

CMake vs Autotools:

首先,拿他们对比本身没有太多的意义,他们都是产生makefile文件的工程编译管理工具。CMake产生的晚,解决了很多autotools工具的问题。

autotools是一个工具集具有强大的灵活性,但是因为步骤太多,配置繁琐,产生了很多的替代方案,cmake是其中最优秀的之一。

早期没有那么多选项,大量的开源项目都是采用autotools管理工程。

2、CMakeLists.txt

项目的每个源码目录下都要配置一个CMakeLists.txt文件,头文件目录下不需要。

如果项目根目录下没有源码,但是有多个源码子目录,那么项目根目录下也需要配置一个CMakeLists.txt,以便将所有源码子目录串接起来。

CMakeLists.txt常用指令以及变量:

  • 指令 project(project_name)

设置项目名称。这条指令一定要放在最顶层的CMakeLists.txt中,千万不要在下级CMakeLists.txt中再次使用project指令,否则会导致PROJECT_SOURCE_DIR变量错乱。

  • 变量 PROJECT_SOURCE_DIR

指向最顶层CMakeLists.txt所在目录。

  • 指令 cmake_minimum_required

cmake最低版本需求,不加入此行会受到警告信息。

只在根节点CMakeLists.txt中设置即可。

  • 指令 include_directories (include_path)

设置当前目录下的源码在编译时,对头文件的搜索路径,多个路径用空格隔开。

每个CMakeLists.txt都需要设置当前目录下源码对头文件的搜索路径。

  • 指令 link_directories (lib_path)          

设置当前目录下的源码在编译时,对库文件的搜索路径,多个路径用空格隔开。

官方不推荐这条指令,取代方案是find_library。

例如:

find_library(libpath_jsoncpp  libjsoncpp.so  ${PROJECT_SOURCE_DIR}/lib)

首先从系统库路径搜索libjsoncpp.so,然后从自定义指定路径搜索,一旦匹配成功即返回路径到变量libpath_jsoncpp。

  • 指令 set(des src)

变量复制,目标变量不存在则自动创建。

例如:

set(lib_path "hello")  //赋值变量lib_path为字符串"hello"
message("lib_path=${lib_path}") 输出变量内容

3、实例1

flat项目,所有源码都在同一个文件夹下。

demo文件夹下,有三个文件,main.c, test.c, test.h:

demo/
   |– main.c
   |– test.c
   |– test.h

在demo文件夹下建立CMakeLists.txt文件,编辑内容如下:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ cmake_minimum_required (VERSION 2.6)          #cmake最低版本需求,不加入此行会受到警告信息
┃ project(hello)                                #设置项目名(不是指最终编译出的可执行文件名)
┃ aux_source_directory( .  src_list)            #把当前目录(.)下所有源代码文件和头文件路径赋值给变量src_list;
┃ set (EXECUTABLE_OUTPUT_PATH   ${PROJECT_SOURCE_DIR}/bin ) #设置应用程序输出路径
┃ add_executable(demo ${src_list})                          #将目标源码编译成可执行文件demo
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

在demo目录下执行cmake <根节点CMakeLists.txt路径>,就会将在当前目录下生成Makefile以及其他相关配置文件,然后在执行make命令即可调用Makefile进行编译。

为了避免在代码目录下生成一大堆目标文件,可以在项目根目录下创建一个子目录,如build,然后进入子目录,并运行cmake ..命令,哲理的..表示根节点CMakeLists.txt路径在上级目录。

执行完cmake ..,所有的配置信息文件包括Makefile都会生成在当前目录(build)下,然后再执行make命令,就会在build目录下生成目标文件。若要清理目标文件,直接删除build文件夹即可。

注:

  1. EXECUTABLE_OUTPUT_PATH为CMake的系统变量,用于设定应用程序的数据路径;
  2. PROJECT_SOURCE_DIR为包含project(项目名)的最近一个CMakeLists.txt文件所在的文件夹,通常project(...)只要在根CMakeLists.txt文件中定义一次就可以了,所以PROJECT_SOURCE_DIR通常指向项目根目录。

4、实例2

层次化结构:

demo/
  ┣main.c
  ┣include/
      ┣test1.h
      ┣test2.h
  ┣src/
     ┣test1.c
     ┣test2.c

在demo文件夹下建立CMakeLists.txt文件,编辑内容如下:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ cmake_minimum_required (VERSION 2.6)          #cmake最低版本需求,不加入此行会受到警告信息
┃ project(hello)                                #设置项目名(不是指最终编译出的可执行文件名)
┃        
┃ aux_source_directory( .  src_list)            #把当前目录(.)下所有源代码文件和头文件路径赋值给变量src_list;
┃ include_directories (include /usr/include)    #设置头文件搜索路径,多个路径用空格隔开,
┃                                               #若有相对路径则是基于当前CMakeLists.txt所在目录;
┃ add_subdirectory(src)                         #添加其他源码子目录
┃ set (EXECUTABLE_OUTPUT_PATH   ${PROJECT_SOURCE_DIR}/bin ) #设置应用程序输出路径
┃ add_executable(demo ${src_list})                          #将目标源码编译成可执行文件demo
┃ link_directories (${PROJECT_SOURCE_DIR}/lib)              #设置库文件搜索路径  
┃ target_link_libraries (demo libpthread.so libsqlite3.so libcurl.so libjsoncpp.so) #设置添加到目标程序中去的库(静态或动态)    
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

在src文件夹下建立CMakeLists.txt文件,编辑内容如下:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃aux_source_directory(. dir_sub_src)   #把当前目录(.)下所有源代码文件和头文件加入变量dir_sub_src
┃include_directories (../include)      #为当前目录下的源码文件设置头文件搜索路径,相对路径基于当前CMakeLists.txt所在目录。
┃add_library (testlib ${dir_sub_src})  #把当前目录源码编译成静态库testlib
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

5、实例3

层次化结构(多个源码子目录,但项目根目录下没源码文件的情况):

 demo/
  ┣include/
      ┣test1.h
      ┣test2.h
  ┣app/
      ┣main.c
  ┣src/
      ┣test1.c
      ┣test2.c

在demo文件夹下建立CMakeLists.txt根节点文件,编辑内容如下:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ cmake_minimum_required (VERSION 2.6)          #cmake最低版本需求,不加入此行会受到警告信息
┃ project(hello)                                #设置项目名(不是指最终编译出的可执行文件名)
┃ add_subdirectory(app)                         #添加源码子目录app(只允许添加子目录,而且一次只能添加一个子目录)
┃ add_subdirectory(src)                         #添加源码子目录src(只允许添加子目录,而且一次只能添加一个子目录)
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

在demo/app文件夹下建立CMakeLists.txt根节点文件,编辑内容如下:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ aux_source_directory(.  src_list)             #把当前目录(.)下所有源代码文件和头文件路径赋值给变量src_list;
┃ include_directories (../include)              #设置头文件搜索路径,多个路径用空格隔开
┃ set (EXECUTABLE_OUTPUT_PATH   ${PROJECT_SOURCE_DIR}/bin ) #设置应用程序输出路径
┃ add_executable(demo ${src_list})                    #将目标源码编译成可执行文件demo
┃ link_directories (${PROJECT_SOURCE_DIR}/lib)        #设置库文件搜索路径  
┃ target_link_libraries (demo testlib libpthread.so)  #设置添加到目标程序中去的库(静态或动态)  
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

注:

在调用add_executable指定输出可执行文件时,要在同一个CMakeLists.txt文件中通过set (EXECUTABLE_OUTPUT_PATH)设置应用程序输出路径。在调用target_link_libraries连接库文件时,要在同一个CMakeLists.txt文件中通过link_directoriesadd设置库文件搜索路径。

在demo/src文件夹下建立CMakeLists.txt文件,编辑内容如下:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃aux_source_directory(. dir_sub_src)   #把当前目录(.)下所有源代码文件和头文件路径赋值给变量dir_sub_src
┃include_directories (../include)      #为当前目录下的源码文件设置头文件搜索路径,相对路径基于当前CMakeLists.txt所在目录。
┃add_library (testlib ${dir_sub_src})  #把当前目录源码编译成静态库testlib
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

对于一些全局公共配置,只需要在根节点CMakeLists.txt中配置即可,例如下面这些公共配置:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ cmake_minimum_required (VERSION 2.6)          #cmake最低版本需求,不加入此行会受到警告信息
┃ project(hello)                                #设置项目名(不是指最终编译出的可执行文件名)
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
CMake是一个跨平台的开源构建工具,它能够自动生成各种不同平台的构建脚本,简化了项目的构建过程。下面是一个300字快速入门CMake的实战教程。 首先,安装CMake并确保它被正确添加到系统的环境变量中。 接下来,在你的项目根目录下创建一个CMakeLists.txt文件,这个文件是CMake的配置文件,用来指导CMake生成项目的构建脚本。在CMakeLists.txt文件中,首先指定项目的名称和最低版本要求,例如: ``` cmake_minimum_required(VERSION 3.10) project(MyProject) ``` 然后,添加你的项目的源文件和头文件,使用add_executable或add_library命令指定它们的路径,例如: ``` add_executable(MyApp main.cpp foo.cpp bar.cpp) ``` 接下来,你可以添加依赖库,使用target_link_libraries命令指定它们的路径,例如: ``` target_link_libraries(MyApp ${CMAKE_DL_LIBS}) ``` 此外,你还可以指定编译选项,例如: ``` set(CMAKE_CXX_FLAGS "-std=c++11 -Wall") ``` 最后,你可以通过命令行执行cmake命令来生成构建脚本,并执行构建过程,例如: ``` mkdir build cd build cmake .. make ``` 在build目录中,你会找到生成的构建脚本及其生成的可执行文件(或库文件)。 通过这个简单的实战教程,你可以快速入门CMake,并且开始使用它来管理你的项目的构建过程。当然,在实际应用中,你还可以进行更多高级配置,例如添加条件编译、安装目标等。希望这个简短的回答能够给你一个基本的CMake入门指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wespten

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值