CMake基础入门和使用

1.CMake是什么?
引用百度的话就是CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,简单的说它就是一个可以用根据不同平台生成对应的编译脚本的工具。

2.CMake怎么用?
CMake工具使用一个名为CMakeLists.txt 的文件来描述构建过程,可以产生标准的构建文件,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。文件 CMakeLists.txt 需要手工编写,也可以通过编写脚本进行半自动的生成。CMake 提供了比 autoconfig 更简洁的语法。在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:
1)编写 CmakeLists.txt。
2)执行命令“cmake PATH”或者“ccmake PATH”生成 Makefile ( PATH 是 CMakeLists.txt 所在的目录 )。
3)使用 make 命令进行编译。

3.CMake具体使用实例
 写到这,一道闪光,自己沉睡的记忆被唤醒了,欣慰啊,想起自己在安装opencv的时候用过CMake, 具体就以安装opencv为例。
1)从官网下载最新opencv源码
2)tar解压opencv
3)

cd ~/opencv-x.x.x
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
make
sudo make install

下面在opencv测试用例中继续使用CMake生成相应的Makefile并验证opencv安装成功。
1) 创建工作目录
mkdir ~/opencv-lena
cd ~/opencv-lena
vim DisplayImage.cpp

2) 拷贝如下代码到cpp中
include <stdio.h>
include <opencv2/opencv.hpp>
using namespace cv;
int main(int argc, char** argv )
{
    if ( argc != 2 )
    {
        printf("usage: DisplayImage.out <Image_Path>\n");
        return -1;
    }
    Mat image;
    image = imread( argv[1], 1 );
    if ( !image.data )
    {
        printf("No image data \n");
        return -1;
    }
    namedWindow("Display Image", WINDOW_AUTOSIZE );
    imshow("Display Image", image);
    waitKey(0);
    return 0;
}

3) 创建CMake编译文件
vim CMakeLists.txt
写入如下内容
cmake_minimum_required(VERSION 2.8)
project( DisplayImage )
find_package( OpenCV REQUIRED )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )

4) 编译
cd ~/opencv-lena
cmake .
make

5) 执行
此时opencv-lena文件夹中已经产生了可执行文件DisplayImage,下载lena.jpg放在opencv-lena下,运行./DisplayImage lena.jpg即可看到显示出lena的照片。

CMake使用过程中最核心的东西就是如何编写CMakeLists.txt,下面再具体分析CMakeLists.txt各种语法及语义。

单个源文件目录时编写CMakeLists.txt的方法

如果要系统学习CMake,最好还是参照官方文档,讲的很详细面面俱到,https://cmake.org/Wiki/CMake,因为我是在一个项目中用到CMake,所以最主要还是想快速学习如何编写CMakeList.txt以及一些具体命令的含义.
CMakeList.txt的语法比较简单,由命令、注释和空格组成,其中命令是不区分大小写的,符号”#”后面的内容被认为是注释。命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔。例如上节的例子:
cmake_minimum_required(VERSION 2.8)
project( DisplayImage )
find_package( OpenCV REQUIRED )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )

第一行代表CMake解析该脚本所要求的最低版本
第二行代表该项目名称
第三行find_package代表首先在默认Modules目录下搜索所有名为FindOpenCV.cmake的文件,如果这个文件未找到,它将会查找 OpenCVConfig.cmake 或 OpenCV-config.cmake 文件。这两个文件是库文件安装时自己安装的,将自己的路径硬编码到其中。在我的项目中,OpenCVConfig.cmake 在/usr/share/OpenCV下,前种查找成为module模式,后者查找成为config模式,REQUIRED选项表示如果报没有找到的话,cmake的过程会终止,并输出警告信息。
第四行代表要生成的可执行文件名以及需要编译的文件
第五行代表可执行文件需要链接相关的库文件。
-
多个源文件目录时编写CMakeLists.txt的方法

上面的例子由于只有一个源文件,所以比较简单,下面介绍下多个源文件目录时编写CMakeLists.txt的方法

CMake基础入门和使用

多个源文件目录

在项目根目录下创建一个CMakelists.txt文件,内容如下:
cmake_minimum_required(VERSION 2.8)
project( face_detection )
find_package( OpenCV REQUIRED )
message(STATUS "INC ${OpenCV_INCLUDE_DIRS} OK")

find_package(PkgConfig)
pkg_check_modules(LIBUV REQUIRED libuv)
message(STATUS " ${LIBUV_LIBRARY_DIRS} OK")

set(Root "${CMAKE_CURRENT_SOURCE_DIR}")
set(Base64 ${Root}/lib/libb64/src)

include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(${Root})
include_directories(${Root}/lib/libb64/include)
include_directories(${LIBUV_INCLUDE_DIRS})

link_directories(${LIBUV_LIBRARY_DIRS})

add_library(atlas_cv STATIC
            cv_atlas.cpp
            cv_atlas.h
            cv_tool.h
            cv_tool.cpp
            ${Base64}/cencode.c)

set_target_properties(
  atlas_cv
  PROPERTIES
  ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/bin")

其中命令 message 会将参数的内容输出到终端,如果打印变量,需加上${}。
set表示给Root Base64变量赋值
include_directories表示加入编译所需的相关头文件路径
link_directories表示需要链接的库文件路径
add_library表示要生成的库路径以及依赖的源文件名
set_target_properties表示设置库目标的属性,如输出名称和位置。

相关推荐