本文转载自:http://www.cppblog.com/Roger/archive/2011/11/17/160368.html

Cmake的介绍和使用 Cmake实践

Cmake优点:

1.       开发源代码,实用类BSD许可发布。

2.       跨平台,并可以生成native编译配置文件,在linux/unix平台,生成makefile,在mac平台可以生成xcode,在windows平台可以生成msvc工程的配置文件。

3.       能够管理大型项目

4.       简化编译构建过程和编译过程,只需要cmake+make就可以

5.       高效率

6.       可扩展,可以为cmake编写特定功能的模块,扩充cmake功能

如何安装cmake

1.       Cmake的安装可以使用autotools进行安装,点击cmake-2.8.6.tar.gz 链接,可以对软件进行下载。

2.       ./configure

3.       make

4.       sudo make install

Cmake的原理

Helloworld cmake

//main.cpp

#include<cstdio>

int main()

{

printf("hello world from main\n");

return 0;

}

创建CMakeLists.txt(注意大小写一个字母都不能错)

向该文件中加入以下几行(稍后会做解释)

PROJECT (HELLO)

SET(SRC_LIST main.cpp)

MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})

MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})

ADD_EXECUTABLE(hello ${SRC_LIST})

运行以下命令:

cmake . (别忘记加上这个点,表示当前目录)

注意执行完这句话之后会生成几个文件如下:

CMakeFiles, CMakeCache.txt, cmake_install.cmake等文件,并且生成了Makefile

然后执行make 就可以生成可执行文件hello

这是当前目录下就会生成可执行文件如下图:

对例子的解释:

CMakeLists.txt的内容如下:

PROJECT (HELLO)

SET(SRC_LIST main.cpp)

MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})

MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})

ADD_EXECUTABLE(hello ${SRC_LIST})

Project的指令的语法是:

PROJECT(projectname [CXX] [C] [JAVA])

这个执行是用来定义工程的名称的和定义工程支持的语言。这个指令也隐式的定义了两个cmake变量:<projectname>_BINARY_DIR以及<projectname>_BINARY_DIR,这里就是HELLO_BINARY_DIR和HELLO_SOURCE_DIR,两个变量指的都是当前工程的路径。

SET指令的语法:

SET(VAR[VALUE] [CACHE TYPE DOCSTRING [FORCE]])

Set指令是用来显式的定义变量的,我们之前用到的是SET(SRC_LIST main.cpp)如果有多个源文件,也可以定义成SET(SRC_LIST main.cpp t1.cpp t2.cpp)。

MESSAGE指令的语法是:

MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)

这个指令用于向终端输出用户信息,包含三种类型:

SEND_ERROR,产生错误,生成过程被跳过。

SATUS,输出前缀为-的信息。

FATAL_ERROR,立即终止所有cmake过程。

我们在这里使用的是STATUS信息输出,显示了由PROJECT指令顶一顶两个饮食变量HELLO_BINARY_DIR和HELLO_SOURCE_DIR。

ADD_EXECUTABLE(hello ${SRC_LIST})

定义了这个工程会生成一个文件名为hello的可执行文件,相关的源文件是SRC_LIST中定义的源文件列表,本例中你可以直接写成ADD_EXECUTABLE(hello main.c)。

将本例改写成一个最简化的CMakeLists.txt:

PROJECT(HELLO)

ADD_EXECUTABLE(hello main.c)

下面我们介绍一个比较实用的例子,即包含生成静态库又包含引入外部头文件和链接库的cmake demo。

先按照工程规范建立工程目录,并编写代码,以下面的工程目录为例进行解释这个例子,工程的目录结构为:

编译工程要实现的目标:

1. 添加子目录doc,用以放置这个工程的文档hello.txt

2. 生成hello的静态库,并在main可执行程序链接hello静态库

3. 在这个工程中添加COPYRIGHT,README

4. 在工程目录中添加一个run.sh的脚本,用以调用生成的二进制可执行文件

5. 将生成的二进制文件生成到bin子目录中

6. 编写安装程序

1. 编写CMakeLists.txt

由于一个工程目录中包含多个项目,其中在此项目中包含util项目和main项目,其中util项目是用以生成main程序需要的静态库,main是用以生成可执行文件。

在工程项目中的父目录向有一个CMakeLists.txt是用以声明定义工程需要的Cmake设置还定义了子目录src,用以递归的调用src中的MakeLists.txt。其中工程目录的CMakeLists.txt内容定义如下:

PROJECT(HELLO)

ADD_SUBDIRECTORY(src)

在src里面的CMakeLists.txt是用以定义src目录包含的两个工程的依赖关系分别进行编译。

util目录里面的CMakeLists.txt是用以定义生成util静态库的规则,其中内容如下:

SET(LIBRARY_OUTPUT_PATH ${HELLO_SOURCE_DIR}/lib)

SET(CMAKE_C_COMPILER g++)

SET(SRC_LIST hello.c)

INCLUDE_DIRECTORIES(${HELLO_SOURCE_DIR}/include)

ADD_LIBRARY(util STATIC ${SRC_LIST})

其中SET(LIBRARY_OUTPUT_PATH ${HELLO_SOURCE_DIR}/lib)定义了库生成的路径,LIBRARY_OUTPUT_PATH是一个内部变量,存放库生成路径。

SET(SRC_LIST hello.c)是用来定义库文件需要的源文件。

INCLUDE_DIRECTORIES(${HELLO_SOURCE_DIR}/include)是用来定义非标准库头文件要搜索的路径。其中INCLUDE_DIRECTORIES命令的格式为:

INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

ADD_LIBRARY(util STATIC ${SRC_LIST})是用来定义生成的库的名字,以及生成库的类型和生成库需要的源文件,其中ADD_LIBRARY命令格式为:

ADD_LIBRARY(libname    [SHARED|STATIC|MODULE]

[EXCLUDE_FROM_ALL]

source1 source2 ... sourceN)

SET(CMAKE_C_COMPILER g++)是用来定义c的编译器为g++,防止出现C和C++代码在不指定C编译器的情况下默认使用gcc,导致系统编译混乱。

在main目录中的CMakeLists.txt是用来定义可执行程序编译和链接时所需要的一些命令或环境。内容如下:

SET(EXECUTABLE_OUTPUT_PATH ${HELLO_SOURCE_DIR}/bin)

SET(SRC_LIST main.cpp)

INCLUDE_DIRECTORIES(${HELLO_SOURCE_DIR}/include)

LINK_DIRECTORIES(${HELLO_SOURCE_DIR}/lib)

ADD_EXECUTABLE(hello ${SRC_LIST})

TARGET_LINK_LIBRARIES(hello util)

INCLUDE_DIRECTORIES命令是定义工程的include文件夹,其中存放使用到的库的头文件,LINK_DIRECTORIES是定义工程的库文件,其中存放着库文件,ADD_EXECUTABLE是定义生成的可执行文件,TARGET_LINK_LIBRARIES用以定义链接时需要的库文件。

2.在工程目录下创建build目录,并采用out-of-source方式编译项目。执行命令make ..,执行结果如下:

执行make,这时在build目录下生成了中间编译文件:

执行make命令,结果如下:

可以看到工程创建和编译成功了。

2. 安装

在工程目录下添加COPYRIGHT、README、和run.sh,重新编辑工程目录下的CMakeLists.txt。在CMakeLists.txt中添加如下命令:

INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake_demo)

INSTALL(PROGRAMS run.sh DESTINATION bin)

INSTALL(PROGRAMS bin/hello DESTINATION bin)

INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake_demo)

这些命令表示在执行make install命令时,安装程序会拷贝相应的文件、目录或程序到指定的前缀开始的目录中,cmake执行命令如下:

cmake -DCMAKE_INSTALL_PREFIX=~/data/cmake_demo ..这时将工程目录安装到~/data/cmake_demo目录下。执行结果如下:

其中cmake编译c、c++工程完毕。

Cmake的介绍和使用 Cmake实践【转】的更多相关文章

  1. Cmake的介绍和使用 Cmake实践

    Cmake的介绍和使用 Cmake实践http://www.cppblog.com/Roger/archive/2011/11/17/160368.html

  2. CMake 简单介绍 图

    http://tech.uc.cn/?p=914     CMake特点 CMake需要用户用CMake规范的语法编写CMake脚本,该语法简单易用,入门极其顺手 原生支持 C/C++/Fortran ...

  3. CMake 简单介绍

    CMake特点 CMake需要用户用CMake规范的语法编写CMake脚本,该语法简单易用,入门极其顺手 原生支持 C/C++/Fortran/Java 的相依性的自动分析功能,免除了程序员对代码依赖 ...

  4. CMake学习笔记三:cmake 常用指令

    1 基本指令 1,ADD_DEFINITIONS 向 C/C++编译器添加-D 定义,比如: DD_DEFINITIONS(-DENABLE_DEBUG -DABC),参数之间用空格分割. 如果你的代 ...

  5. 百度人脸识别集成错误:Build command failed. Error while executing process F:\dev\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments

    大概是这么个错误 Build command failed. Error while executing process F:\dev\Android\Sdk\cmake\3.6.4111459\bi ...

  6. Linux下CMake使用介绍

    CMake是一个跨平台的编译自己主动配置工具,它使用一个名为CMakeLists.txt的文件来描写叙述构建过程,能够产生标准的构建文件.它能够用简单的语句来描写叙述全部平台的安装(编译过程).它能够 ...

  7. CMake学习笔记二:cmake 常用变量和常用环境变量

    1 cmake 变量引用的方式 使用 ${} 进行变量的引用.在 IF 等语句中,是直接使用变量名而不通过 ${} 取值. 2 cmake 自定义变量的方式 主要有隐式定义和显式定义两种,举一个隐式定 ...

  8. Zsh安装CMake补全脚本进行CMake命令补全

    最近在尝试使用Zsh,发现其补全命令的功能相当厉害.但对CMake命令的补全在默认的5.0.5中好像没有看到,网上找了下关于配置Zsh补全的文章也没有多少.     于是自己动手,发现在Zsh安装目录 ...

  9. CMake安装grpc生成gRPCTargets.cmake文件

    以下是安装语句: cd grpc_folder git submodule update --init cmake .. make -j 4 sudo make install 然而编写依赖gRPC的 ...

随机推荐

  1. 简单的MVC 权限管理

    花了3天时间研究了下对于 NHibernate+MVC4+bootstrap+Redis(这个是选配只做了登陆测试)+T4 这些都是第一次使用.用着有些生硬权当鼓励下自己,记录下来有空就继续完善. 思 ...

  2. asp网页无法打开

    环境:Window 2003.IIS6.Framework1.1 .VS2003 一个WebForm项目里面包含一些asp网页  运行后发现asp页面无法访问 提示:无法找到该页 解决方案: 1. [ ...

  3. E题

    题目大意: 找到一个最小的l值,使得a到b-l+1中任取一个数开始前进l次,中间包含至少有k个素数,如果找不到,返回-1: 运用素数打表法和2分法便能简单搞定: 题目链接:http://codefor ...

  4. [luoguP1168]中位数(主席树+离散化)

    传送门 模板题一道,1A. ——代码 #include <cstdio> #include <algorithm> #define ls son[now][0], l, mid ...

  5. bzoj 2818 GCD 数论 欧拉函数

    bzoj[2818]Gcd Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. Input 一个整数N Output 如题 Samp ...

  6. iOS时钟,秒针扫秒样式

    昨天做一个时钟小demo,发现了一些问题. 描述能力有限,我封装好了一个时钟框架,朋友们可以参考      https://github.com/qianlishun/ClockView 点击这里可以 ...

  7. 普通平衡树(bzoj 3224)

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...

  8. 深入理解计算机操作系统——第11章:全球IP英特网

    全球IP英特网 (1)每台英特网主机都运行实现TCPIP协议的软件. (2)英特网的客户端和服务器混合使用套接字接口函数和Unix IO函数来进行通信. (3)套接字函数典型的是作为陷入内核的系统调用 ...

  9. Codeforces Round #294 (Div. 2) D. A and B and Interesting Substrings [dp 前缀和 ]

    传送门 D. A and B and Interesting Substrings time limit per test 2 seconds memory limit per test 256 me ...

  10. java基础 4 继承(1)抽象类与接口的区别

    抽象类: 是用来捕捉子类的通用特性的,至少包含一个抽象方法,该抽象方法必须在子类中实现,由于抽象类没有抽象方法的具体实现,因此不能对抽象类进行实例化. 接口: 定义了一组方法,是抽象方法的集合,但是接 ...