首先,对于最简单的,把一个cpp文件编译成一个可执行文件,需要对CMakeLists.txt中写入如下三步内容:

#声明Cmake的最低版本
cmake_minimum_required( VERSION 3.0)

#声明一个cmake工程
project( Hello )

#添加一个可执行程序
add_executable( Hello hello.cpp)

所以最简单的就是三步,1.声明最低版本,2.声明cmake工程,3.添加可执行程序。


但是如果要使用库函数,那么就不是这么简单了。

首先我们先简述一下需要了解库的文件结构。

大部分库都是这样的结构,头文件和cpp文件同名,但是不互相用include关联。一个放函数的声明,一个放函数的具体定义。

举例来说:

有一个函数print_hello()的定义放在libhello.cpp中,print_hello()的声明放在libhello.h中,库的头文件和库的cpp文件没有互相关联。

这时候我想写一个主函数main.cpp,其中想调用print_hello()这个函数,该怎么办?

当然,得把库libhello.h给include进来。

这时候就有一个问题,主函数main.cpp虽然include了libhello.h,但是这个头文件里只是声明了一下void print_hello(),并没有介绍print_hello()到底是怎么运作的,具体怎么运作放在libhello.cpp文件中。而主函数并没有#include"libhello.cpp",因此,main.cpp编译成的可执行文件是缺东西的,一定不能正常工作(缺print_hello()的内容,目前只有一个声明)。

那么libhello.cpp和main.cpp如何建立联系呢?

这个建立联系的中介,就是可执行文件。

对于这个,有两种方式:

第一种比较简单和直观,直接在add_executable的时候,把两个cpp文件都add进来。

#声明Cmake的最低版本
cmake_minimum_required( VERSION 3.0)

#声明一个cmake工程
project( Hello )

#添加一个可执行程序
add_executable( Hello main.cpp libhello.cpp)

第二种,需要把libhello.cpp打包成一个library,然后把library链接到可执行文件上。

目前的脉络是这样:

windows 平台cmake编译android项目 cmake怎么编译_Cmake

 

所以这种情况下,应该这么写CMakeLists.txt:

cmake_minimum_required( VERSION 3.0)

project( Hello_project )

add_executable( Hello main.cpp )

add_library( hello_library libhello.cpp)

target_link_libraries( Hello hello_library)

因此有如下几点特点:

1.头文件不在cmakelist中出现

2.声明cmake版本,再声明工程

3.主函数做成执行文件

4.cpp文件做成library

5.library链接到执行文件上


除此之外,还有几点内容值得学习一下:

第一,头文件最好写成如下形式:

#ifndef __XXX_H
#define __XXX_H
头文件内容
#endif

其中,__XXX_H也是宏,它不是头文件名不过习惯上把这个宏定义成跟头文件名相似或一样。(不一样也是可以的!)
这个宏主要是用于编译的时候避免重复include同一头文件而出现一些额重复定义/声明的问题。

第二,正常来说,只有在add_library以后生成的hello_library,才能称它为“库”。再把库再链接到可执行文件上。我前面所述“库的头文件和库的cpp文件”主要是为了方便读者理解。

第三,在add_library的时候,有两种方式,一种是静态库,一种是动态库。静态库以.a为后缀,共享库以.so为后缀。

二者的差别在于:静态库每次调用会生成一个副本,共享库只有一个副本。

如果想用共享库,在add_library的语句中,库名 和 cpp文件 之间,加一个SHARED即可。

像这样:

add_library( hello_library SHARED libhello.cpp)

以上是第二种方式。


这一节的内容相当于是做了一个简单的实例,让人明白Cmake的基本用法。