【CMake】CMake 语法及基本操作【不定时更新】

我为什么用CMake( Cross Platform Make 跨平台编译)(还有一些无关感想)

自从在接触了Linux操作系统后发现Linux的编程环境与Windows有很大的不同,很多在Window下的程序往往不能在Ubuntu下直接运行,反之亦然。而个人又极不情愿在Ubuntu上配置各种编译,操作环境(大概率是懒且笨且懒)(我坦言,编译环境有点挫伤了我的积极性,我花了大量的时间在这上面,但对于学习人工智能来说一定是必经的)。

但由于最近偶然发现在VS2019上可以配置CMake工程,(Ubuntu上编译C++基本依赖CMake)于是就萌生了在Windows下使用CMake调试Linux程序的想法(不知道我以后会不会打消这个念头)。

而且使用CMake添加一些C++库文件(OpenCV,Eigen,Sophus,Ceres等)或许挺方便的,也方便我们以后对这些库的了解。

再说说我对编程一开始的见解:那时候对编程的思维还是线性的,觉得编写一个程序,只要一条道走到黑,最终只要实现了目的,别人也不会多看你的代码一眼。但随着程序目的的复杂化,代码量的增加,曾经想到哪写到哪的思维,慢慢变得不可靠了许多,并且最近在学习数据结构,对代码封装,库的建立与调用有了一定的意识,在这种情况下,CMake无疑给了我们一个很好的选择,况且还可以不依赖IDE直接在终端执行编译操作。

CMake最基本语法:

值得一提的是,CMake语句虽然不区分大小写,但我们常常使用大写来与其他语言加以区分,具体因人而异,当然小写也行(这里使用小写)。

CMake将要执行的编译操作统一写在CMakeLists.txt中。

CMake使用#表示注释。

#CMake最低版本号要求

#若低于所给版本将报错。

cmake_minimum_required (VERSION 2.8)
#声明一个CMake工程

#“demo”项目名,CMakeLists.txt与项目文件在同一文件夹下,一般写文件夹名。

project (demo) #工程名
#添加一个可执行程序

#Ubuntu下生成可执行文件为demo,Windows下则为demo.exe。

#main.cpp为包含主函数的那个项。

add_executable(main main.cpp) #程序名 源代码文件名
#调用一个自己写的库。

#Linux上库文件常存放的地点为/lib或/usr/lib,库对应的头文件一般存放在/usr/include中。

#静态库(Linux下为.a文件,Windows下为.lib文件)

add_library(xxx libxxx.cpp)
#在生成可执行程序后记得添加(将主函数链接到库上):
target_link_libraries(main xxx)  #程序名 库名

#共享库/动态库(Linux下为.so文件,Windows下为.dll文件)

add_library(xxx_shared SHARED libxxx.cpp)
... ...
target_link_libraries(main xxx_shared)  

值得一提的是,我们一般有选择地使用静态库/动态库。(理解)

·静态库被链接后就直接嵌入可执行文件中了,在程序规模庞大的情况下就会带来两个问题。

1.浪费系统空间。如果多个程序链接了同一个库,则每一个生成的可执行文件就都会有一个库的副本,必然会浪费系统空间。

2.一旦发现了库中有bug,就必须一一把链接该库的程序找出来,然后重新编译。(当然重新cmake make也行,不过速度慢)

·而动态库的出现正弥补了静态库的以上弊端。因为动态库是在程序运行时被链接的,所以磁盘上只须保留一份副本,因此节约了空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉就行了。

然而实际操作过程中,假如你用OpenCV库写了一个程序,用动态库链接,给别人运行,若那人没有安装OpenCV,则运行过程中是会报错的;如果使用静态库链接,由于编译过程中库被嵌在可执行程序上了,因此不会有这个问题。

*一个超容易理解的操作实例:

#主函数(main.cpp):

#include "head.h"

int main()
{
    
    
	Display();
	return 0;
}

#库(func.cpp):

#include<iostream>
using namespace std;

void Display()
{
    
    
	cout << "Such Is Basic CMake"<<endl;
	cout << "So You Happy?"<<endl;
}

#头(head.h):

void Display();

#CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)

project(hello)

add_library (hello SHARED function1.cpp)

add_executable(main main.cpp)

target_link_libraries(main hello)

终端:

Such Is Basic CMake
So You Happy?

在VS上只需对CMakeLists.txt进行保存即可自动编译生成exe文件省去了终端上:

mkdir build

cd build

cmake . .

make

的操作。

#设置编译模式
set( CMAKE_BUILD_TYPE "Debug" )
#set( CMAKE_BUILD_TYPE "Release" )

debug和release两个版本区别:

1、版本不同Debug通常称为调试版本,编译的结果通常包含调试信息,而且不做任何优化,以为开发人员提供强大的应用程序调试能力。而Release通常称为发布版本,是为用户使用的,一般客户不允许在发布版本上进行调试(不能调试)。

2、运行效果不同debug程序通常比release程序要慢,尤其是处理视频方便release要比debug快很多。

3、算法不同debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc, 而release的赋值近似于随机。

#设置编译器版本
 set(CMAKE_CXX_FLAGS "-std=c++11") #c++11支持
 #add_compile_options(-std=c++11)
 #set( CMAKE_CXX_FLAGS "-O3" ) #设置优化选项

其中:

add_compile_options命令添加的编译选项是针对所有编译器的(包括c和c++编译器),而set命令设置
CMAKE_C_FLAGS或CMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器。

gcc 中-O1 -O2 -O3 优化的原理:
这里

如有不足,欢迎指出!

猜你喜欢

转载自blog.csdn.net/SESESssss/article/details/104809034