关于Cmake的入门学习(一)

1、Cmake编译原理

CMake是一种跨平台编译工具,比make更为高级,使用起来要方便得多。CMake主要是编写CMakeLists.txt文件,然后用cmake命令将CMakeLists.txt文件转化为make所需要的makefile文件,最后用make命令编译源码生成可执行程序或共享库(so(shared object))。

2、一个cmakelists的例子详解

#.指定项目的名称,一般和项目文件夹名称对应,sln的名称
project(HXT) 

#指定Cmake版本,最低版本要求
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
#在指定域中设置一个命名属性
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDER ON)
#使用set设置CMAKE_CXX_FLAGS变量
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

#添加编译选项
ADD_DEFINITIONS(-D UNICODE)
#设置需要用到的opencv模块,添加opencv库
find_package(OpenCV REQUIRED)
#指定头文件的搜索路径
INCLUDE_DIRECTORIES(.)
 #指定include文件所在的路径
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/Algorithm)

#开始作用子文件夹下的CMakeLists,先Algorithm再Example(包含子目录)
add_subdirectory(Algorithm)
add_subdirectory(Example)

3、上述代码的扩展

(1)、SET_PROPERTY(GLOBAL PROPERTY USE_FOLDER ON)

set_property:在指定域中设置一个命名属性

set_property(<GLOBAL                            |
                DIRECTORY [dir]                   |
                TARGET    [target1 [target2 ...]] |
                SOURCE    [src1 [src2 ...]]       |
                TEST      [test1 [test2 ...]]     |
                CACHE     [entry1 [entry2 ...]]>
               [APPEND][APPEND_STRING]
               PROPERTY <name>[value1 [value2 ...]])

在某个域中对零个或多个对象设置一个属性。第一个参数决定该属性设置所在的域。它必须为下面中的其中之一:

GLOBAL域是唯一的,并且不接特殊的任何名字(本文使用的语句)。

DIRECTORY域默认为当前目录,但也可以用全路径或相对路径指定其他的目录(前提是该目录已经被CMake处理)。

TARGET域可命名零或多个已经存在的目标。

SOURCE域可命名零或多个源文件。注意:源文件属性只对在相同目录下的目标是可见的(CMakeLists.txt)。

TEST域可命名零或多个已存在的测试。

CACHE域必须命名零或多个已存在条目的cache.

必选项PROPERTY后面紧跟着要设置的属性的名字。

    结合2中的例子,SET_PROPERTY(GLOBAL PROPERTY USE_FOLDER ON),设置的是GLOBAL域,USE_FOLDER的属性,这个属性是用来分目录组织VC中的多个工程。但是这个是为了使得多个工程放在一个目录下,在这里只有一个HXT工程,显然这个语句是多余的。正确的使用:

SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
SET_PROPERTY(TARGET project1 PROPERTY FOLDER "Core")
SET_PROPERTY(TARGET project2 PROPERTY FOLDER "Core")

(2)、set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

这句是添加编译选项,有两种方法,可以用add_compile_options命令,也可以通过set命令修改CMAKE_CXX_FLAGSCMAKE_C_FLAGS。 这里是其中一种方法设置了编译选项。使用这两种方式在有的情况下效果是一样的,但请注意它们还是有区别的: 
add_compile_options命令添加的编译选项是针对所有编译器的(包括c和c++编译器)

set命令设置CMAKE_C_FLAGSCMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器的。

所以这里也可以修改成如下所示,是一样的作用。

add_compile_options(-std=c++11)

那么问题来了,c++11又是什么鬼?

接着扩:C++0x是C++最新标准标准化过程中的曾用名,在这一系列文章中我们将介绍最新标准添加的一系列新的语言特性。在2011年9月份,C++0x正式由官方发布并命名C++11,现在很多编译器已经支持了部分C++11特性。好像是一种标准,之前是C98,在小甲鱼的课中提到一嘴,其中一个特性是auto怎么怎么,也没太明白,那么,学习一下C++的auto吧顺便:

(链接)https://blog.csdn.net/xiaoquantouer/article/details/51647865

(3)、ADD_DEFINITIONS(-D UNICODE)

向C/C++编译器添加-D定义,添加编译参数,这里是添加UNICODE,为了让软件支持多国语言,也就是国际化吧,比如东亚语系cjk(中日韩),由于这些国家语言的每个字符都是以宽字符(wide character即两个字节)表示的,而unicode字符集(unicode character set)是一个宽字符集,所以自然的使用unicode就顺理成章了。这里附一个字符串的博文讲解:http://noshape.bokee.com/4749054.html

(4)、find_package(OpenCV REQUIRED)

首先,OpenCV一定要遵循该大小写。如果你有很多的opencv版本,尤其是一个是opencv2.x.x一个是opencv3.x.x,因为2和3在数据结构上有相对较大的变化,所以如果引入错误的版本可能导致程序的无法运行。因为find_package找默认路径下的OpenCV,但是很多时候安装多个版本的库的时候都会make install在opt目录下。、 
  安装在opt的文件中会有share文件夹,这里面就有咱们需要的OpenCV文件夹,所以如果要自己有选择的控制版本,则在find_package这句话前面去设置opencv的OpenCV文件夹在哪里,添加set(OpenCV_DIR /opt/opencv-2.4.11/share/OpenCV)这句话。因为我的opencv2.4.11版本install在/opt/opencv-2.4.11文件夹下。这个可以根据你install的位置去变化。

(5)、INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/Algorithm)和
INCLUDE_DIRECTORIES(.)

这是添加头文件路径,添加库路径,对应的函数叫LINK_DIRECTORIES,这里的头文件路径是${CMAKE_SOURCE_DIR}/Algorithm,猜一下应该是这个cmakelists文件目录下的Algorithm文件夹。

猜你喜欢

转载自blog.csdn.net/qq_41909317/article/details/82594781