CMake入门教程(二)

CMake入门(二)

最后更新日期:2014-04-25 by kagula

阅读前提:《CMake入门(一)》、Linux的基本操作

环境: Windows 8.1 64bit英文版,Visual Studio 203 Update1英文版,CMake 2.8.12.2、 Cent OS 6.5。

 

内容简介

         介绍在VisualStudio上现有的项目如何移植到Linux上。本文通过列出两个最简单、也是最常用的例子来介绍Linux下CMake的使用。

 

CentOS 上安装CMake 2.8.12.2

         虽然在Cent OS 上直接可以使用“yuminstall cmake”命令来安装,但是版本太低,我们需要在www.cmake.org上直接下载最新的CMake源代码来安装。从官网下载cmake-2.8.12.2.tar.gz到“/usr/local”路径下,输入“tar -zxvf cmake-2.8.12.2.tar.gz”命令在当前位置解压缩,现在“/usr/local”路径下新建了“cmake-2.8.12.2”目录,进入目录。

安装C语言和C++语言编译器

#yum install gcc  gcc-c++  

配置

#./configure

编译与链接

#make

安装

#make install

CMake会把程序安装到/local/host/bin下

运行下面的命令查看CMake的当前版本,可以看到已经是2.8版本了。

#cmake --version

 

在Linux上使用CMake的第一个例子

         在VisualStudio上新建项目CMake_Tutorial2,具体步骤如下 [Visual Studio]->[Visual C++]->[Win32]->[Win32 Project]打开向导窗口,选择[Applicationtype]为console application,选择[Additional options]为Empty project后[Finish]。

         新建Source.cpp源文件清单如下:

[cpp]  view plain  copy
  1. #include   
  2.   
  3. extern void HelloWorld();  
  4.   
  5. int main(int args, wchar_t* argv[])  
  6. {  
  7.     HelloWorld();  
  8.     getchar();  
  9.   
  10.     return 0;  
  11. }  
新建MyLib.cpp源文件清单如下:

[cpp]  view plain  copy
  1. #include   
  2.   
  3. using namespace std;  
  4.   
  5. void HelloWorld()  
  6. {  
  7. #ifdef WIN32  
  8.     wcout << L"Hello,World From Windows!" << endl;  
  9. #else  
  10.     wcout << L"Hello,World From Cent OS!" << endl;  
  11. #endif   
  12. }  

添加CMakeLists.txt文件,源文件内容如下:

[sql]  view plain  copy
  1. #设置项目名称  
  2. project(CMake_Tutorial2)  
  3.   
  4. #要求CMake的最低版本为2.8  
  5. cmake_minimum_required(VERSION 2.8)  
  6.   
  7. #用于将当前目录下的所有源文件的名字保存在变量 DIR_SRCS 中  
  8. aux_source_directory(. DIR_SRCS)  
  9.   
  10. #用于指定从一组源文件 source1 source2 … sourceN(在变量DIR_SRCS中定义)   
  11. #编译出一个可执行文件且命名为CMake_Tutorial1  
  12. add_executable(CMake_Tutorial2 ${DIR_SRCS})  

这次需要的三个文件都齐备了。Source.cpp是我们的主文件,MyLib.cpp文件模拟主文件所需要的函数实现在另一个文件,毕竟再小的项目也很少只有一个cpp文件组成,CMakeLists.txt文件写好后是给Cent OS上的CMake工具使用的。

         现在按[F5],程序在Windows上正确执行。

进入项目的文件夹中(...\CMake_Tutorial2\CMake_Tutorial2\)我们可以看到

CMAKE_TUTORIAL2

│  CMakeLists.txt

│  CMake_Tutorial2.vcxproj

│ CMake_Tutorial2.vcxproj.filters

│  CMake_Tutorial2.vcxproj.user

│  MyLib.cpp

│  Source.cpp

└─Debug

六个文件一个Debug文件夹,其中只有CMakeLists.txtMyLib.cppSource.cpp三个文件才是我们在Linux上编译出可执行程序所需要的,但是为了方便我们把“CMake_Tutorial2”整个文件夹上传到linux系统上。

         [S1]我把目录上传到CentOS操作系统的/home/kagula/Downloads目录下,[S2]在控制台下输入“cd  CMake_Tutorial2”命令,在当前目录我们可以看到原来在Windows系统下的六个文件和一个Debug文件夹。

        

基本操作流程为:

  1. $> cmake directory
  2. $> make

[S3]在当前目录下使用“mkdir build”命令建立build文件夹。

[S4]“cd build”,

[S5]“cmake ..”命令在当前目录(Build目录)生成Makefile文件,“..”参数指示CMake工具,CMakeLists.txt文件在父目录中。

[S6]输入“make”命令后,进行编译链接,在当前目录生成CMake_Tutorial2可执行程序,

[S7]输入“./CMake_Tutorial2”,程序运行并输出“Hello,WorldFrom Cent OS!”字符串,输入任意字符后敲回车,程序结束运行。

 

 

在Linux上使用CMake的第二个例子

这个例子相对于上面一个

[1]增加了分布在不同目录的源文件。

         现实世界中多个C++源文件会分布在不同的目录中,这个例子模拟了这种情况。

[2]宏的定义。

         在Win上跑的程序,不一定在Linux上也能顺利跑,所以有时候需要在程序中根据_DEBUG宏的定义输出程序运行状态。

这里的难点是CMakeLists.txt文件的编辑

在Visual Studio上建立Win32 控制台项目CMake_Tutorial2_2, 经调试可以运行后,再把CMake_Tutorial2_2整个工程目录上传到Cent OS上。在Cent OS上做测试的时候我把它放在了/home/kagula/Downloads/CMake_Tutorial2_2/中。

源文件目录结构如下,

CMAKE_TUTORIAL2_2

│ CMakeLists.txt

│ CMake_Tutorial2_2.vcxproj

│ CMake_Tutorial2_2.vcxproj.filters

├─Debug

│  │  CMake_Tutorial2_2.log

│  │  FromMyLib1.obj

│  │  FromMyLib2.obj

│  │  Source.obj

│  │  vc120.idb

│  │  vc120.pdb

│  │

│  └─CMake_Tu.3A7B3807.tlog

│         cl.command.1.tlog

│         CL.read.1.tlog

│         CL.write.1.tlog

│         CMake_Tutorial2_2.lastbuildstate

│         link.command.1.tlog

│         link.read.1.tlog

│         link.write.1.tlog

├─MyLib1

│     CMakeLists.txt

│     FromMyLib1.cpp

│     FromMyLib1.h

└─src

       CMakeLists.txt

       Source.cpp

可以看到每个含源代码的文件夹中必须有一个CMakeLists.txt文件,所以这里共有三个CMakeLists.txt文件。

根目录下的CMakeLists.txt源文件清单

[html]  view plain  copy
  1. #设置项目名称  
  2. PROJECT(CMake_Tutorial2_2)  
  3.   
  4. #要求CMake的最低版本为2.8  
  5. CMAKE_MINIMUM_REQUIRED(VERSION 2.8)  
  6.   
  7. #要显示执行构建过程中详细的信息(比如为了得到更详细的出错信息)  
  8. SET( CMAKE_VERBOSE_MAKEFILE ON )  
  9.   
  10. #添加子目录  
  11. ADD_SUBDIRECTORY(MyLib1)  
  12. ADD_SUBDIRECTORY(src)  


MyLib1目录下的CMakeLists.txt源文件清单

[html]  view plain  copy
  1. #用于将当前目录下的所有源文件的名字保存在变量 LIB1_SRC 中  
  2. AUX_SOURCE_DIRECTORY(. LIB_SRC)  
  3.   
  4. #输出静态库文(Archive)件,第一个参数指的是库的名字  
  5. ADD_LIBRARY(libFromMyLib1 ${LIB_SRC})  
  6.   
  7. #变量${PROJECT_BINARY_DIR}指向调用cmake时的文件夹  
  8. #所以编译出来的库文件会输出到这个文件夹下的lib子目录  
  9. SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)  
  10.   
  11. #库文件重名称为“mylib1”, 会输出“libmylib1.a”文件  
  12. #如果不重命名,库文件名字为“libFromMyLib1”。  
  13. SET_TARGET_PROPERTIES(libFromMyLib1 PROPERTIES OUTPUT_NAME mylib1)  


src子目录下的CMakeLists.txt源文件清单

[plain]  view plain  copy
  1. #指定可执行程序输出路径为运行cmake时路径的bin子路径  
  2. #默认是输出到运行cmake命令时的路径  
  3. SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)  
  4.   
  5. #CMake运行时,打印路径  
  6. MESSAGE(${PROJECT_SOURCE_DIR}/MyLib1)  
  7. #添加头文件搜索路径  
  8. INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/MyLib1)  
  9.   
  10. #添加库文件搜索路径  
  11. LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/lib)  
  12.   
  13. #用于将当前目录下的所有源文件的名字保存在变量 APP_SRC 中  
  14. AUX_SOURCE_DIRECTORY(. APP_SRC)  
  15.   
  16. #如果调用"CMake -D DEBUG_MODE=ON .."  
  17. #则为C++源文件设置_DEBUG宏  
  18. IF(DEBUG_MODE)  
  19.   ADD_DEFINITIONS(-D_DEBUG)  
  20. ENDIF()  
  21.   
  22. #用于指定从一组源文件 source1 source2 … sourceN(在变量APP_SRC中定义)   
  23. #编译出一个可执行文件且命名为CMake_Tutorial2_2  
  24. ADD_EXECUTABLE(CMake_Tutorial2_2 ${APP_SRC})  
  25.   
  26. #添加编译可执行程序所需要的链接库、如果有多个中间用空格隔开  
  27. #第一个参数是可执行程序名称,第二个开始是依赖库  
  28. #在这里根据名字mylib1去寻找libmylib1.a文件(Linux下的C++静态库文件)  
  29. TARGET_LINK_LIBRARIES(CMake_Tutorial2_2 mylib1)  


现在进入到Cent OS系统下

使用下面的命令

$pwd

显示当前路径为“/home/kagula/Downloads/CMake_Tutorial2_2/”

$mkdir build

$cd build

$cmake ..

调用cmake处理上一级目录的CMakeLists.txt文件,生成Makefile文件。

$make

当前目录会生成lib子目录,存放libmylib1.a静态库文件,生成bin子目录存放CMake_Tutorial2_2可执行文件,进入bin子目录可直接运行CMake_Tutorial2_2可执行程序。

 

如果要启用_DEBUG宏

使用下面的命令代替“cmake  ..”

$cmake -D DEBUG_MODE=on  ..

 

下面给出当前实例用到的三个C++源文件清单

FromMyLIb1.h源码清单

[cpp]  view plain  copy
  1. #ifndef _FROMMYLIB1_H_  
  2. #define _FROMMYLIB1_H_  
  3.   
  4. void FromMyLib1Func();  
  5.   
  6. #endif  

FromMyLIb1.cpp源码清单

[cpp]  view plain  copy
  1. #include "FromMyLib1.h"  
  2. #include   
  3.   
  4. using namespace std;  
  5.   
  6. void FromMyLib1Func()  
  7. {  
  8.     wcout << L"The function from MyLib1 directory!" << endl;  
  9. }  

Source.cpp源码清单

[cpp]  view plain  copy
  1. #include   
  2. #include   
  3.   
  4. #ifdef WIN32  
  5. #include "..\MyLib1\FromMyLib1.h"  
  6. #else  
  7. #include "../MyLib1/FromMyLib1.h"  
  8. #endif  
  9.   
  10. using namespace std;  
  11.   
  12. int main(int argc, wchar_t** argv)  
  13. {  
  14. #ifdef _DEBUG  
  15.     wcout << L"App in Debug Mode" << endl;  
  16. #else  
  17.     wcout << L"Release Mode" << endl;  
  18. #endif  
  19.   
  20.     FromMyLib1Func();  
  21.   
  22.     getchar();  
  23.     return 0;  
  24. }  


如果,修改了项目的源代码

清除生成的2进制代码

$make clean

重新编译

$make

 

 

如果,修改了CMakeLists.txt文件

需要重新调用cmake命令

 

         boost库含有编写C++应用程序所需要的很多基本API。

         下一篇介绍含boost调用的Win32控制台项目,如何借助cmake工具把依赖boost的项目移植到Cent  OS系统上运行。   

参考资料

[1]《CMake使用入门》

http://jiyeqian.is-programmer.com/2011/7/4/cmake_tutorial.27813.html

[2]《makefile: CMAKE的使用》-介绍CMake使用过程中的常见问题

http://blog.chinaunix.net/uid-23381466-id-3826931.html


你可能感兴趣的:(linux系统)