室友打了一把王者我学会了CMake的使用(初学者必备)

CMake

    • CMake介绍
    • CMake安装以及简单的使用
    • 利用CMake生成动静态库
    • 链接动静态库

CMake介绍

CMake是开源、跨平台的构建工具,可以让我们通过编写简单的配置文件去生成本地的Makefile,这个配置文件是独立于运行平台和编译器的,这样就不用亲自去编写Makefile了,而且配置文件可以直接拿到其它平台上使用,无需修改,非常方便。本文的目的主要是入门CMake并不会涉及复杂的CMake的使用,第二个目的就是用来复习的

CMake安装以及简单的使用

1.安装CMake,在Centons当中我们可以使用sudo yum install cmake

sudo yum install cmake

安装完成之后我们可以使用cmake --version命令查看我们当前cmake的版本信息

室友打了一把王者我学会了CMake的使用(初学者必备)_第1张图片

下面我们来演示一下CMake的简单使用,先从最简单的看起一起来感受一下CMake的使用吧,下面我们来编写一个main.cc

#include
using namespace std;
int main()
{
    cout<<"hello word"<<endl;
    return 0;
}

然后了我们在main.cc相同的目录下创建一个CMakeLists.txt文件,编写的内容如下:

cmake_minimum_required(VERSION 2.8)

project(demo)

add_executable(main main.cc)

解释:

  • 其中第一行的意思是要求cmake的最低版本要求是2.8,注意这一句必须放在第一句否则有可能会报错
  • 第二行表示工程信息,此处表示我们的这个工程的名字叫做demo.
  • 第三行也是最关键的,这里表示生成的可执行程序的名字叫做main,使用的源文件叫做main.cc

下面我们在终端上输入cmake . 会有如下信息出来:

室友打了一把王者我学会了CMake的使用(初学者必备)_第2张图片

此时我们可以看到目录下有一个Makefile文件,还有一些cmake允许之后产生的文件,此时我们在在终端上输入make:

室友打了一把王者我学会了CMake的使用(初学者必备)_第3张图片

我们发现整个目录下生成了main这个可执行文件了,我们可以运行他了:

室友打了一把王者我学会了CMake的使用(初学者必备)_第4张图片

我们看此时运行成功,如果我们看到了运行的结果。此时我们发现当我们使用cmake之后会产生很多的文件这些文件在一定程度上影响了我们的源文件因此我们可以在当前目录创建一个build目录:

室友打了一把王者我学会了CMake的使用(初学者必备)_第5张图片

我们进入到build这个目录当中来然后再输入cmake … :
室友打了一把王者我学会了CMake的使用(初学者必备)_第6张图片
此时我们发现之前生成的一堆文件现在就来到了build这个目录下来了,此时不会影响我们的源文件所在的目录。
在这里很多老铁可能就要说了要这么麻烦吗直接g++一行不就行了,下面我们来看一下比较复杂的目录结果此时cmake就比g++要舒服的多了
室友打了一把王者我学会了CMake的使用(初学者必备)_第7张图片
对应add.h当中的代码:

#pragma once
int add(int a,int b);

对应add.c代码:

int add(int a,int b){
    return a+b;
}

对应main.cc代码:

#include
#include"add.h"
using namespace std;
int main()
{
   cout<<add(10,20)<<endl;
}

下面我们来看看此时这个CMakeLists.txt改如何书写

cmake_minimum_required(VERSION 2.8)
project(demo)
include_directories(./include)
set(SRC_LIST ./src/add.cc ./src/main.cc)
add_executable(main ${SRC_LIST})

下面解释一下上面的书写:

  • 其中第一行和第二行之前以及说过了在这里不在重复说明
  • 由于我们main.cc当中包含了add.h所有我们需要指明头文件在哪里找,在这里include_directories 用来包含头文件目录
  • set 用来显示定义变量,可以有多个以也可以有一个,多个可以空格分隔。如果我们想要取变量当中的值我们想要使用${}。在这里说明一下参数和变量是大小写无关的
  • 最后一行在前面以及说明过了,${SRC_LIST}是用来取出SRC_LIST变量当中的值

下面我们进入到build目的当中输入cmake …
室友打了一把王者我学会了CMake的使用(初学者必备)_第8张图片
发现运行成功当然我们也可以在main.cc当中指定add.h这个头文件在哪里.在上面如果源文件有100多个这要敲到猴年马月此时我们就可以使用aux_source_directory(dir var)。第一个参数代表的是目录,第二个参数var是用来存放源文件列表的。此时我们也可以将上面的CMakeLists.txt改为:

cmake_minimum_required(VERSION 2.8)
project(demo)
include_directories(./include)
aux_source_directory(./src SRC_LIST)
add_executable(main ${SRC_LIST})

但是aux_source_directory()也是有弊端的,他会将指定目录下所有的源文件都加入进来,如果在一个目录下有一些源文件我们不想加入进来此时aux_source_directory就不太合适了。此时我们用set定义变量指定特定的源文件即可.

一般的话我们不会这么干,一般我们会将可执行文件放到一个bin目录下,这样会让结构更加的清晰下面我们在把目录结构调整一下:
室友打了一把王者我学会了CMake的使用(初学者必备)_第9张图片
这时候我们需要修改一下最外层的CMakeLists.txt.内容如下:

cmake_minimum_required(VERSION 2.8)
project(demo)
add_subdirectory(./src)

在这里出现了一个新的命令add_subdirectory(),这个命令可以向当前工程添加存放源文件的子目录,并且可以指定中间二进制和目标二进制存放的位置。在这里指定的src目录下存放了源文件,当cmake执行到这里的时候,会进入src目录下去找CMakeLists.txt.所有我们需要在src目录下建立一个CMakeLists.txt。内容如下:

cmake_minimum_required(VERSION 2.8)
aux_source_directory(./ SRCLIST) #把当前目录下的源文件加载进来
include_directories(../include) #指定头文件
add_executable(main ${SRCLIST})
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

在这里使用set来定义变量。EXECUTABLE_OUTPUT_PATH和PROJEXT_SOURCE_DIR是CMake自带的预定义变量和PROJEXT_SOURCE_DIR变量相对应的还有一个叫做PROJECT_BINARY_DIR.
下面我们来解释一下:

1.EXECUTABLE_OUTPUT_PATH:目标二进制可执行文件存放的位置
2.PROJECT_SOURCE_DIR:代表的工程的路径
3.PROJECT_BINARY_DIR:代表编译的是编译的路径

在这里使用set的意思是将生成的可执行程序放到工程所在路径的bin目录下,下面我们进入build目录在终端上输入cmake …
室友打了一把王者我学会了CMake的使用(初学者必备)_第10张图片
运行是ok的下我们我们进入到上级目录的bin目录下
室友打了一把王者我学会了CMake的使用(初学者必备)_第11张图片

利用CMake生成动静态库

之前博主写过利用makefile制作动静态库在这里使用CMake来演示一下生成动静态库相比makefile真的好用多了,下面我们来调整一下啊目录结构
室友打了一把王者我学会了CMake的使用(初学者必备)_第12张图片
下面我们调整一下最外层的CMakeLists.txt,其内容如下:

cmake_minimum_required(VERSION 2.8)
project(demo)
add_subdirectory(add)

下面我们一起来看看add目录下的CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
aux_source_directory(./ SRC_LIST)
add_library(add_shared SHARED ${SRC_LIST})
add_library(add_static STATIC ${SRC_LIST})
set_target_properties(add_shared PROPERTIES OUTPUT_NAME "add")
set_target_properties(add_static PROPERTIES OUTPUT_NAME "add")
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

在这里我们解释一下一些新的命令和遇定变量:

1.add_library:

  • 第一个参数代表的动静态库的名字
  • 第二个参数代表的是你想生成的是动态库还是静态库,如果我们没有写默认为静态库.
  • 第三个指的是生成动静态库的源文件

2.set_target_properties
这个是用来设置输出名称还有设置库的版本号等

3.LIBARARY_OUT_PATH:库文件默认的输出路径,这里设置为工程目录下的lib目录下

下面我们进入到build目录下cmake …然后在make在进入到lib当中
室友打了一把王者我学会了CMake的使用(初学者必备)_第13张图片
注意:我们在前面使用了set_target_properties重新设定了库文件的名字。其实也可以不使用那么库的名字就是add_library里面定义的名字但是动态库和静态库的名字不能相同。此时我们可以使用set_target_properties把名字设置为相同,只是后缀不同而已这样相对起来好看一些

总结:

室友打了一把王者我学会了CMake的使用(初学者必备)_第14张图片

链接动静态库

上面我们以及生成好了动态库和静态库下面我们来看如何使用他们,首先我们将build文件当中的所有文件都区别删掉。下面我们需要修改一下目录结构:
室友打了一把王者我学会了CMake的使用(初学者必备)_第15张图片
src目录下main.cc的内容如下:

#include
using namespace std;
#include"add.h"
int main()
{
    cout<<add(10,20);
    return 0;
}

修改当前工程目录下的CMakeLists.txt如下:

cmake_minimum_required(VERSION 2.8)
project(demo)
add_subdirectory(src)

src目录下CMakeLists.txt如下:

aux_source_directory(. SRC_LIST)
include_directories(../add)
link_directories(${PROJECT_SOURCE_DIR}/lib)
add_executable(main ${SRC_LIST})
target_link_libraries(main add.so)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

在这里又出现了2个新的命令link_directories和target_link_libraries,下面来解释一下:

1.link_directories:添加非标准共享库的搜索路径
target_link_libraries:一个库当中可能有多个动太库你要告诉它你要链接的是那个

然后我们在回到build目录下在终端上敲上cmake … 然后再进入到bin目录下:
室友打了一把王者我学会了CMake的使用(初学者必备)_第16张图片
在lib目录下有两个库一个是动态库一个是静态库如果我们不指明后缀默认链接的是动态库,如果lib目录下只有静态库就只会去链接静态库。

扩展:有时候了我们希望在编译代码的时候想要添加一些编译选项,如:-std=c++11,-Wall等等
我们此时就可以使用add_compile_options来进行操作。由于这个比较简单在这里就不做演示了。

以上就是我学习CMake的一些记录,举的列子都比较的简单旨在帮助大家快速入门CMake,同时也是问了自己后面复习使用。CMake的知识比较的多更多的可以去官网学习或者在一个完善的项目当中学习,CMake可以不用让我们去编写复杂的Makefile并且是跨平台的是一个非常强大的工具。如果有错误的话请各位老铁指正谢谢阅读

你可能感兴趣的:(c++,c#,开发语言,linux)