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_FLAGS
或CMAKE_C_FLAGS
。 这里是其中一种方法设置了编译选项。使用这两种方式在有的情况下效果是一样的,但请注意它们还是有区别的: add_compile_options
命令添加的编译选项是针对所有编译器的(包括c和c++编译器)
set命令设置CMAKE_C_FLAGS
或CMAKE_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文件夹。