学习linux之 cmake(1)

 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。

 

CMake是一个比make更高级的编译配置工具,它可以根据不同平台、不同的编译器,生成相应的Makefile或者vcproj项目。
通过编写CMakeLists.txt,可以控制生成的Makefile,从而控制编译过程。

Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。CMake自动生成的Makefile不仅可以通过make命令构建项目生成目标文件,还支持安装(make install)、测试安装的程序是否能正确执行(make test,或者ctest)、生成当前平台的安装包(make package)、生成源码包(make package_source)、产生Dashboard显示数据并上传等高级功能,只要在CMakeLists.txt中简单配置,就可以完成很多复杂的功能,包括写测试用例。
如果有嵌套目录,子目录下可以有自己的CMakeLists.txt。
总之,CMake是一个非常强大的编译自动配置工具,支持各种平台,KDE也是用它编译的,感兴趣的可以试用一下。

 


一个高级程序从编写到被执行会经历哪些过程呢?

这个很简单,了解编译原理的同学都知道,高级程序最终是要被转化成机器理解的机器代码的,这样才能被机器理解执行。

这个过程可以粗略的分为      源代码(编译)-->目标代码(链接)--->可执行程序


在IDE环境下开发软件,我们只需编写好源文件、头文件、告诉IDE我们依赖的第三方头文件路径、库文件全路径,然后剩下的就交给IDE来完成这个所谓的转化过程。

这个转化过程其实可以用语言描述实现,独立于IDE环境之外。比如可以直接在linux终端用指令编译代码,然后再链接。当工程很简单的时候这样做无妨,然而,当工程变的庞大后,几十个乃至上百个cpp。特别是调试时,修改一个地方,还得把代码链接一遍,靠指令一个个去编译源代码就不现实了。而cmakelist就省事多了。

一个简单的cmakelist的编写

作为入门cmakelist,我写了一个简单的测试代码。

 为了标准化,我采用out-of-source的方式来构建程序,使程序看起来清晰有条理。

   工程目录

            

~learn_cmake2/

                           +src/

                            |            |--cpp1.cpp


                           |            |--cpp2.cpp

                           |            |---main.cpp

                           +include/

                            |             |---cpp1.h

                            |             |---cpp2.h

                            +build/

                            +CMakeList


 

cpp1.h
#include<iostream>
using namespace std;
void print1();

 


cpp2.h
#include<iostream>
using namespace std;
void print2();

 

cpp1.cpp
#include"cpp1.h"
void print1()
{
cout<<"this is cpp1"<<endl;
}

 

cpp2.cpp
#include"cpp2.h"
void print2()
{
cout<<"this is cpp2"<<endl;
}

 

main.cpp
#include<iostream>
#include"opencv2/highgui/highgui.hpp"
#include"cpp1.h"
#include"cpp2.h"
using namespace std;
using namespace cv;
int main()
{
  Mat a=imread("cones.png",0);
print1();
print2();
  imshow("cones",a);
cvWaitKey(0);

}



至此,我们需要的几个简单的头文件和源文件已经编写好。

那么怎么描述本工程(learn_cmake)的编译过程呢?


---CMakeLists.txt           #注意,字母大小写不能写错
project(learn_cmake2)                                                              #工程名
find_package(OpenCV  2.4.8 REQUIRED)                  
 # find_package可以被用来在系统中自动查找配置构建工程所需的程序库                                                                                        
 # 其中REQUIRED表示如果没有找到,cmake会停止处理,并报告一个错误
 #找到opencv 2.4.8后,变量OpenCV_INCLUDE_DIRS中将包括指定OpenCV库头文件的查找路径.
 #变量OpenCV_LIBRARY_DIRS中将包含指定Opencv库的.a或.so文件的所在目录的路径
include_directories(                                                              #头文件目录
${PROJECT_SOURCE_DIR}/include    #PROJECT_SOURCE_DIR 是系统变量 ${PROJECT_SOURCE_DIR}是cmakelist所在工程的路径
${OpenCV_INCLUDE_DIRS}
) 
#一个工程有三种东西需要链接
#<1> 工程内除了maincpp以外的cpp生成的库
#<2>第三方的现有的库
#<3>maincpp生成可执行程序
set(src_list src/cpp1.cpp src/cpp2.cpp ) #设置变量 工程内除了maincpp以外的cpp  默认去工程目录下去寻找cpp
add_library(cpp ${src_list}) #把工程内除了main函数以外的cpp生成一个库
target_link_libraries(cpp ${OpenCV_LIBS}) #链接第三方的库
add_executable(main src/main.cpp) #把main函数生成可执行程序
target_link_libraries(main cpp) #main函数链接这些库
MESSAGE(success)  



通过这样一个文本就可以把编译链接过程描述清楚了。

 


那么,下面我们开始编译程序。

  step1   进入工程目录下的build文件夹下   然后

                         cmake ..                        注:cmake ..的意思是去上层目录寻找cmakelist

  step2  cmake 过后,你会看到build目录下生成makefile文件,那么现在你可以 执行这句话

                         make

  step3  make过后就会生成一个名字为main可执行程序,输入

                          ./main  

            便可以执行代码。

   



                          


 

posted on 2016-10-09 09:06  从小白做起  阅读(208)  评论(0编辑  收藏  举报