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源文件清单如下:

#include <stdio.h>

extern void HelloWorld();

int main(int args, wchar_t* argv[])
{
	HelloWorld();
	getchar();

	return 0;
}

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

#include <iostream>

using namespace std;

void HelloWorld()
{
#ifdef WIN32
	wcout << L"Hello,World From Windows!" << endl;
#else
	wcout << L"Hello,World From Cent OS!" << endl;
#endif
}

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

#设置项目名称
project(CMake_Tutorial2)

#要求CMake的最低版本为2.8
cmake_minimum_required(VERSION 2.8)

#用于将当前目录下的所有源文件的名字保存在变量 DIR_SRCS 中
aux_source_directory(. DIR_SRCS)

#用于指定从一组源文件 source1 source2 … sourceN(在变量DIR_SRCS中定义)
#编译出一个可执行文件且命名为CMake_Tutorial1
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.txt、MyLib.cpp、Source.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源文件清单

#指定可执行程序输出路径为运行cmake时路径的bin子路径
#默认是输出到运行cmake命令时的路径
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

#CMake运行时,打印路径
MESSAGE(${PROJECT_SOURCE_DIR}/MyLib1)
#添加头文件搜索路径
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/MyLib1)

#添加库文件搜索路径
LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/lib)

#用于将当前目录下的所有源文件的名字保存在变量 APP_SRC 中
AUX_SOURCE_DIRECTORY(. APP_SRC)

#如果调用"CMake -D DEBUG_MODE=ON .."
#则为C++源文件设置_DEBUG宏
IF(DEBUG_MODE)
  ADD_DEFINITIONS(-D_DEBUG)
ENDIF()

#用于指定从一组源文件 source1 source2 … sourceN(在变量APP_SRC中定义)
#编译出一个可执行文件且命名为CMake_Tutorial2_2
ADD_EXECUTABLE(CMake_Tutorial2_2 ${APP_SRC})

#添加编译可执行程序所需要的链接库、如果有多个中间用空格隔开
#第一个参数是可执行程序名称,第二个开始是依赖库
#在这里根据名字mylib1去寻找libmylib1.a文件(Linux下的C++静态库文件)
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源码清单

#ifndef _FROMMYLIB1_H_
#define _FROMMYLIB1_H_

void FromMyLib1Func();

#endif

FromMyLIb1.cpp源码清单

#include "FromMyLib1.h"
#include <iostream>

using namespace std;

void FromMyLib1Func()
{
	wcout << L"The function from MyLib1 directory!" << endl;
}

Source.cpp源码清单

#include <stdio.h>
#include <iostream>

#ifdef WIN32
#include "..\MyLib1\FromMyLib1.h"
#else
#include "../MyLib1/FromMyLib1.h"
#endif

using namespace std;

int main(int argc, wchar_t** argv)
{
#ifdef _DEBUG
	wcout << L"App in Debug Mode" << endl;
#else
	wcout << L"Release Mode" << endl;
#endif

	FromMyLib1Func();

	getchar();
	return 0;
}

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

清除生成的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

时间: 2024-08-04 18:52:40

CMake入门(二)的相关文章

[WebGL入门]二十,绘制立体模型(圆环体)

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正. 本次的demo的运行结果 立体的模型 这次稍微喘口气,开始绘制立体模型.这里说的[喘口气]是指本次的文章中没有出现任何新的技术知识点.只是利用到现在为止所介绍过的内容,来绘制一个立体的圆环体.到现在为止,只绘制了三角形和四边形,当然,在三维空间中绘制简单的多边形也没什么不对,但是缺点儿说服力.

kafka入门二:Kafka的设计思想、理念

本节主要从整体角度介绍Kafka的设计思想,其中的每个理念都可以深入研究,以后我可能会发专题文章做深入介绍,在这里只做较概括的描述以便大家更好的理解Kafka的独特之处.本节主要涉及到如下主要内容: Kafka设计基本思想 Kafka中的数据压缩 Kafka消息转运过程中的可靠性 Kafka集群镜像复制 Kafka 备份机制 一.kafka由来 由于对JMS日常管理的过度开支和传统JMS可扩展性方面的局限,LinkedIn(www.linkedin.com)开发了Kafka以满足他们对实时数据流

Netty入门二:开发第一个Netty应用程序

    既然是入门,那我们就在这里写一个简单的Demo,客户端发送一个字符串到服务器端,服务器端接收字符串后再发送回客户端. 2.1.配置开发环境 1.安装JDK 2.去官网下载jar包 (或者通过pom构建) 2.2.认识下Netty的Client和Server 一个Netty应用模型,如下图所示,但需要明白一点的是,我们写的Server会自动处理多客户端请求,理论上讲,处理并发的能力决定于我们的系统配置及JDK的极限. Client连接到Server端 建立链接发送/接收数据 Server端

Thinkphp入门 二 —空操作、空模块、模块分组、前置操作、后置操作、跨模块调用(46)

原文:Thinkphp入门 二 -空操作.空模块.模块分组.前置操作.后置操作.跨模块调用(46) [空操作处理] 看下列图: 实际情况:我们的User控制器没有hello()这个方法 一个对象去访问这个类不存在的方法,那么它会去访问”魔术方法__call()” 用户访问一个不存在的操作—>解决:给每个控制器都定义个_empty()方法来处理 第二个解决方法:定义一个空操作 [空模块处理] 我们使用一个类,但是现在这个类还没有被include进来. 我们可以通过自动加载机制处理__autoloa

转 Python爬虫入门二之爬虫基础了解

静觅 » Python爬虫入门二之爬虫基础了解 2.浏览网页的过程 在用户浏览网页的过程中,我们可能会看到许多好看的图片,比如 http://image.baidu.com/ ,我们会看到几张的图片以及百度搜索框,这个过程其实就是用户输入网址之后,经过DNS服务器,找到服务器主机,向服务器发出一个请求,服务器经过解析之后,发送给用户的浏览器 HTML.JS.CSS 等文件,浏览器解析出来,用户便可以看到形形色色的图片了. 因此,用户看到的网页实质是由 HTML 代码构成的,爬虫爬来的便是这些内容

Redbean:入门(二) - Find

<?php require_once 'rb.php'; $tableName = 'link'; //连接数据库 R::setup('mysql:host=localhost;dbname=hwibs_model','root',''); //链接表 R::dispense($tableName); //1.获取对象记录句柄,如果不存在id的情况下就无法使用load,那么可以使用find方法进行查找 $result = R::find($tableName,'id > 4');//普通使用

DevExpress XtraReports 入门二 创建 data-aware(数据感知) 报表

原文:DevExpress XtraReports 入门二 创建 data-aware(数据感知) 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用的,为了帮助更多的人不会像我这样浪费时间才写的这篇文章,高手不想的看请路过 本文内容来DevExpress XtraReports帮助文档,如看过类似的请略过. 废话少说 开始正事 一.创建应用程序并添加报表 启动 MS Visual Studio (2005.2008.或 2010). 在 Visua

MongooooooooooooooooooooDB入门二:基本概念介绍

前言 工欲善其事必先利其器.在学习MongoDB之前,需要对MongoDB的一些基本概念有系统的了解. 所以,本篇文章主要介绍MongoDB的一些基本概念,这些概念的定义均来自<MongoDB权威指南>,关于此书想要了解更多,请点击此处. 我尽量使用最简洁的语言来尽可能完整地描述这些基本概念,如有遗漏或不妥之处欢迎指正. 文档 文档是MongoDB的核心概念之一.多个键值对有序地放在一起便是文档.例如: {"name":"Jerry","sco

Flex入门(二)——Flex+BlazeDs+J2ee小实例

首先来简单介绍一下BlazeDS. BlaseDS的核心功能包括RPC Services(远程过程调用服务) 和Messaging Service(消息服务).BlazeDS是一个基于服务器的Java远程调用(remoting)和web消息传递(messaging)技术,使得后台的Java应用程序可以和运行在浏览器上的Flex应用程序能够互相通信.简单来说一个BlazeDS应用包括客户端(Flex或AIR应用程序)和一个服务端(J2EE程序).BlazeDS在期间起着承上启下的作用,Flex和B