CMake、CMakeLists.txt


2022-06-02,今天开始研究cmake。不间断更新。
在这里插入图片描述

一、说明

0.官方文档网址:www.cmake.org

1.cmake的定义:高级编译配置工具
当多个人用不同的语言或者编译器开发一个项目,最终要输出一个可执行文件或者共享库(dll、so),这时候就出现了神器CMake! 所有的操作都是通过编译CMakeLists.txt来完成的。
学习CMake的目的,是为将来处理大型的C/C++/JAVA项目做准备。

2.安装

sudo apt-get install cmake

二、使用步骤

1.构建CMakeLists.txt
CMake 构建脚本是一个纯文本文件,您必须将其命名为 CMakeLists.txt,并在其中包含 CMake 构建您的 C/C++ 库时需要使用的命令。如果您的原生源代码文件还没有 CMake 构建脚本,您需要自行创建一个,并在其中包含适当的 CMake 命令。

2.在包含CMakeLists.txt的目录下使用cmake

cmake 放置CMakeList.txt路径

1)构建放在当前目录下(内部构建):cmake . 即在当前目录cmake,在当前目录build。
2)在当前目录下创建build文件夹存放构建文件(外部构建),build内输入cmake ..。即在上级目录cmake,在该目录下build。
结果:生成4个东西:CMakeFiles文件夹、cmake_install.cmake、CMakeCache.txt、Makefile

只要产生Makefile文件,就说明cmake成功了

3.在包含Makefile的目录下使用make
直接在build出4个东西的目录下(命令针对的是Makefile)输入make

make

4.生成可执行文件。 输入./文件名运行



举例1:
1)先编写main.cpp

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

2)编写CMakeLists.txt

PROJECT(HELLO)            #工程名为HEELO

SET(SRC_LIST main.cpp)    #变量SRC_LIST包含main.cpp

MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})

MESSAGE(STATUS "This is SOURCE dir " ${HELLO_SOURCE_DIR})

ADD_EXECUTABLE(hello ${SRC_LIST}) #生成可执行程序文件名为hello,源文件读取变量SRC_LIST中内容

3)cmake

cmake .

生成了4个东西:CMakeFiles文件夹、cmake_install.cmake、CMakeCache.txt、Makefile

4)make

make

生成了可执行文件hello

5)执行

./hello

显示"hello,world"


三、如何编写CMakeLists.txt,语法详解

PROJECT关键字 ※

可以用来指定工程的名字和支持的语言,默认支持所有语言
PROJECT(HELLO) 指定了工程的名字为HELLO,且支持所有语言(建议这样做)
PROJECT(HELLO CXX)指定了工程的名字为HELLO,仅支持C++语言
PROJECT(HELLO C CXX)指定了工程的名字为HELLO,仅支持C和C++语言

该指定隐式地定义了两个CMake变了
<projectname>_BINARY_DIR
<projectname>_SOURCE_DIR
本例中是HELLO_BINARY_DIR、HELLO_SOURCE_DIR
MESSAGE关键字就可以直接使用这两个变量。当前都指向当前的工作目录

SET关键字

SET用来显式的指定变量,可以为多个
SET(SRC_LIST main.cpp) 意为SRC_LIST变量包含了main.cpp
SET(SRC_LIST main.cpp test1.cpp test2.cpp) 意为SRC_LIST变量包含了main.cpp、test1.cpp、test2.cpp

MESSAGE关键字

向终端输出用户自定义的信息,主要包含三种:

  • SEND_ERROR:产生错误,生成过程被跳过
  • STATUS:输出前缀为- -的信息
  • FATAL_ERROR:立即终止所有cmake过程

ADD_EXECUTABLE关键字 ※

生成可执行文件
ADD_EXECUTABLE(hello $(SRC_LIST)),生成的可执行文件名为hello,源文件读取变量SRC_LIST中的内容
也可直接写为 ADD_EXECUTABLE(hello main.cpp)

注意:工程名的HELLO和生成的可执行文件hello是没有任何关系的

所以,上例中的5行CMakeLists.txt可以简化为2行:

PROJECT(HELLO)
ADD_EXECUTABLE(hello main.cpp)

ADD_SUBDIRECTORY关键字

①有子目录时,要用ADD_SUBDIRECTORY关键字包含所有需要访问的子文件夹。除了工程目录外,每个被访问的子目录里也都需要有一个CMakeLists.txt说明
将目标文件放入构建目录的bin子目录ADD_SUBDIRECTOR(子目录名 bin):自动在子目录下新建一个名为bin的子目录,存放中间二进制文件、目标二进制文件、库文件。

注意:文件就是file。目录(文件夹)就是directory。

语法基本原则

1.变量取值 ${ }
2.分隔多个文件:空格或者分号
3.大小写:指令大小写不敏感,参数和变量对大小写敏感

四、内部构建与外部构建

内部构建:例1就是内部构建,产生的临时文件和源文件堆在一起,不方便清理。BINARY DIR和SOURCE DIR在同一个目录下。
外部构建:把生成的临时文件放在build目录下,方便清理(直接删除build整个文件夹)。BINARY DIR在build目录下,SOURCE DIR在CMakeLists.txt目录下(一般CMakeLists.txt是在build的上级目录,这样可以直接cmake …,然后make)。将build放在CMakeLists.txt同级目录下。推荐使用外部构建。
在这里插入图片描述

五、让Hello,World看起来更像一个工程

  • 为工程添加一个子目录src,用来放置工程源代码
  • 为工程添加一个子目录doc,用来放置工程的文档hello.txt
  • 为工程添加文本文件使用文档README版权COPYRIGHT
  • 在工程目录中添加一个runhello.sh脚本,用来调用hello二进制
  • 为工程添加一个子目录bin,用来放置生成的目标文件

举例2:
1)在工程目录下,先编写main.cpp。创建src子目录,将main.cpp放入其中

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

2)在工程目录下编写CMakeLists.txt,包含子目录版本

PROJECT(HELLO )            #工程名为HEELO
ADD_SUBDIRECTORY(src bin)  #源文件包含子目录src,目标文件放在构建文件的bin目录下

3)在源文件目录src下编写子目录的CMakeLists.txt

ADD_EXECUTABLE(hello main.cpp)

4)在工程目录下构建子目录build,并在build中进行cmake。出现Makefile后再进行make

mkdir build        
cd build
cmake ..  #出现5个东西:bin  CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile
make      #bin目录中出现了可执行文件hello

只进行到mkdir build时,对工程目录进行tree。效果(目录结构)应该是这样的:
.
├── build
├── CMakeLists.txt
└── src
 ├── CMakeLists.txt
 └── main.cpp

六、安装:INSTALL

(一) 安装文件

INSTALL(FILES 文件名 DESTINATION 目标地址)
举例3:
工程目录下的CMakeLists.txt添加一行:

INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake)   #会自动安装到/usr/local/share/doc/cmake下

DESTINATION后面:
1.写绝对路径
2.相对路径:
CMAKE_INSTALL_PREFIX 默认是在/usr/local/
若想要更改,可以手动设置

set(CMAKE_INSTALL_PREFIX "目标路径")

这时候再 DESTINATION ${CMAKE_INSTALL_PREFIX},就导出到目标路径上了。

(二)安装脚本

PROGRAMS:非目标文件的可执行程序安装(比如脚本之类)

INSTALL(PROGRAMS runhello.sh DESTINATION bin)    #实际安装到/usr/bin

(三)安装目录

安装doc中的hello.txt
方法一:通过在doc目录中建立CMakeLists.txt,通过install下的file
方法二:直接在工程目录中写入

INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake)

(四)可执行文件安装

在src的CMakeLists.txt里输入

INSTALL(TARGETS hello DESTINATION bin) 

(五)执行

cd build
cmake ..
make
make install

七、生成静态库和动态库

SET(变量 源文件名)
ADD_LIBRARY(库名 STATIC或SHARED ${变量})

(一)构建动态库(命令用SHARED) (构建静态库,命令用STATIC)

举例4:

SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})    #生成动态库libhello.so

1)构建目录树
.
├── build
├── CMakeLists.txt
└── src
├── CMakeLists.txt
├── hello.cpp
└── hello.h

2 directories, 4 files

2)编写CMakeLists.txt
①工程目录CMakeLists.txt内容为:

cmake_minimum_required(VERSION 3.13)
PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)

②lib目录CMakeLists.txt内容为:

SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

3)lib下源文件内容
①hello.h内容

#ifndef HELLO_H
#define HELLO_H

void HelloFunc();

#endif

②hello.cpp内容

#include "hello.h"
#include <iostream>

using namespace std;

void HelloFunc(){
        cout<<"Hello,world!"<<endl;
}

4)在build目录下进行cmake … 、make 。在build/bin下即出现了libhello.so

(二)同时构建静态库和动态库

SET_TARGET_PROPERTIES

3行命令。视频里补充

八、使用外部头文件和共享库

(一)添加头文件搜索路径:

INCLUDE_DIRECTORIES(路径)

(二)添加需要链接的共享库

TARGET_LINK_LIBRARIES(源文件名 库名)
TARGET_LINK_LIBRARIES(main libhello.so)    #链接动态库
TARGET_LINK_LIBRARIES(main libhello.a)     #链接静态库




本文参考:b站刘贝斯《从零开始介绍CMake》
转一篇参考:https://blog.csdn.net/wml00876/article/details/120965558

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员爱德华

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

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

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

打赏作者

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

抵扣说明:

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

余额充值