【整理】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; make; make install

【CMake的原理】 

准备main.cpp文件

?


1

2

3

4

5

6

7

8

9

//main.cpp

 

#include<cstdio>

 

int main()

{

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

    return 0;

}

a.创建 CMakeLists.txt(注意:此文件名大小写必须如此命名),向该文件中加入以下几行(内容中命令的大小写无所谓):

?


1

2

3

4

5

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})

b.运行以下命令(linux下):

?


1

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

执行完该命令后执行ls可以看到:

生成了CMakeFiles(目录)、CMakeCache.txt、cmake_install.cmake以及Makefile文件。
c.执行make。

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

【例子解释】:

上面CMakeLists.txt的内容重新列出如下: 

?


1

2

3

4

5

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>_SOURCE_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" ...) 

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

  1. SEND_ERROR,产生错误,生成过程被跳过。
  2. SATUS,输出前缀为-的信息。
  3. 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的最简化形式:

?


1

2

PROJECT(HELLO)

ADD_EXECUTABLE(hello main.c)

=== 我是分割线 ===

下面我们介绍一个比较实用的例子,既包含生成静态库又包含引入外部头文件和链接库的cmake demo。
先按照工程规范建立工程目录并编写代码,以下面的工程目录为例进行解释这个例子,工程的目录结构为:

 

编译工程要实现的目标:

  • 添加子目录doc,用以放置这个工程的文档hello.txt。
  • 生成hello的静态库,并在main可执行程序链接hello静态库。
  • 在这个工程中添加COPYRIGHT和README文件。
  • 在工程目录中添加一个run.sh的脚本,用以调用生成的二进制可执行文件。
  • 将生成的二进制文件生成到bin子目录中。
  • 编写安装程序。 

1. 编写CMakeLists.txt
      由于一个工程目录中包含多个项目,其中在此项目中包含util项目和main项目,其中util项目是用以生成main程序需要的静态库,main是用以生成可执行文件。
      在整个工程项目的根目录下的CMakeLists.txt是用来定义工程需要的CMake设置以及子目录src,用以递归调用src中的MakeLists.txt。该CMakeLists.txt的内容定义如下: 

?


1

2

PROJECT(HELLO)

ADD_SUBDIRECTORY(src)

      目录src中的CMakeLists.txt用以定义src目录下包含的两个工程(main和util)的依赖关系。
      目录util里面的CMakeLists.txt是用以定义生成util静态库的规则,其中内容如下:

?


1

2

3

4

5

6

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(CMAKE_C_COMPILER g++) -- 定义C的编译器为g++,防止出现C和C++代码在不指定C编译器的情况下默认使用gcc,导致系统编译混乱。 
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)

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

?


1

2

3

4

5

6

7

8

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(${HELLO_SOURCE_DIR}/include) -- 定义工程引用的include文件夹位置,其中存放使用到的库的头文件。
LINK_DIRECTORIES(${HELLO_SOURCE_DIR}/lib) -- 定义工程引用的库文件位置,其中存放着库文件。
ADD_EXECUTABLE(hello ${SRC_LIST}) -- 定义生成的可执行文件。
TARGET_LINK_LIBRARIES(hello util) -- 用以定义链接时需要的库文件。 

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

?


1

$ cmake ..

执行结果如下

 

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

?


1

$ tree .

执行make命令,结果如下:

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

3. 安装

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

?


1

2

3

4

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执行命令如下: 

?


1

cmake -DCMAKE_INSTALL_PREFIX=~/data/cmake_demo ..

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

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

原文地址:http://www.udpwork.com/item/6326.html

时间: 2024-09-29 04:14:04

【整理】CMake 介绍和 CMake 实践的相关文章

优化介绍及应用实践

云栖TechDay第33期,阿里巴巴iDST Staff Engineer杨森带来题为"优化介绍及应用实践"的演讲.本文主要从用户需求开始谈起,对婚姻配对算法进行了介绍,重点谈及了分配问题.路径规划和组合优化等问题,最后总结了优化的重要性.   以上是精彩内容整理: 用户需求 说起阿里巴巴,第一个标签肯定是电商平台.电商平台的核心问题就是如何关联用户.商品和卖家,是否成功的关键就是如何去高效率的匹配.如何高效率的匹配用户和商品,这直接影射出两个非常直观的问题: 首先我们要知道用户想要什

Chrome浏览器标签页整理技巧介绍

Chrome浏览器标签页整理技巧介绍   操作技巧 在Chrome浏览器中我们是可以像Windows 文件管理器中管理文件.文件夹一样使用Shift进行连续多选或者Ctrl进行点选操作的. 在Chrome 浏览器中使用Shift进行快速选择连续标签页 选择一个标签页作为起始标签页,然后按住Shift键点击结束标签页,如下图,当选择的标签页变成区别于其他标签的白色时,表示成功选择; 此时松开Shift键,并用鼠标左键在任意被选择的标签页上"往外拖拽"即可将这些标签页在新的Chrome窗口

Docker 常用命令整理并介绍_docker

什么是Docker? Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机).bare metal.OpenStack 集群和其他的基础应用平台. Docker通常用于如下场景: web应用的自动化打包和发布: 自动化测试和持续集成.发布: 在服务型环境中部署和调整数据库或其他的后台应用: 从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的P

iOS常用加密算法介绍和代码实践_IOS

iOS系统库中定义了软件开发中常用的加解密算法,接口为C语言形式.具体包括了以下几个大类:  #include <CommonCrypto/CommonCryptor.h> //常用加解密算法 #include <CommonCrypto/CommonDigest.h> //摘要算法 #include <CommonCrypto/CommonHMAC.h> #include <CommonCrypto/CommonKeyDerivation.h> #incl

POP介绍与使用实践(快速上手动画)[转]

前言 动画在APP开发过程中 大家多多少少都会接触到 而且随着ios7的扁平化风格启用之后 越来越多的APP开始尝试加入各种绚丽的动画交互效果以增加APP的用户体验(当然 还是以国外的APP居多) 有过相关开发经验的同学肯定知道在iOS中 动画相关的部分都是基于Core Animation 但是今天我们不讨论Core Animation 今天的主角是POP -来自于Facebook的动画引擎(其实我不喜欢把POP定义为动画引擎 我愿意称它为函数发生器) 介绍 官方地址 https://githu

JSR 303 - Bean Validation 介绍及最佳实践

关于 Bean Validation 在任何时候,当需要处理一个应用程序的业务逻辑时,数据校验是您必须要考虑和面对的事情.应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的.在通常的情况下,应用程序是分层的,不同的层由不同的开发人员来完成.很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题,比如说语义的一致性等.为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定. Bean Validation 为 JavaBean 验证定义了相应的元数据

CMake 简单介绍

CMake特点 CMake需要用户用CMake规范的语法编写CMake脚本,该语法简单易用,入门极其顺手 原生支持 C/C++/Fortran/Java 的相依性的自动分析功能,免除了程序员对代码依赖的调整,对整个开发工作帮助很大 支持 SWIG.Qt.FLTK 开发框架 支持跨平台编译,这是CMake名字的来源 能够转换特殊平台的 IDE 项目文档,如xcode 与Dart.CTest 和 CPack 集成,可以组成自动化的构建系统 CMake vs GNU AutoTools 使用CMake

CMake初步(1)

转自:<你所不知的OSG>第一章:CMake初步(1)http://bbs.osgchina.org/forum.php?mod=viewthread&tid=1189&fromuid=3434 本章的主要目的并非介绍OpenSceneGraph的常用类和功能,而是介绍它的一个重要伙伴,抑或说,是一个被愈来愈多的开源软件所青睐的强劲的辅助开发工具--CMake. CMake的定义是:一个跨平台.开源.可扩展的软件编译生成系统,如果您熟悉与之同类的QMake(开源开发库Qt的自动

CMake初步(2)

转自:<你所不知的OSG>第一章:CMake初步(2) http://bbs.osgchina.org/forum.php?mod=viewthread&tid=1229&fromuid=3434   1.4 词法和语法 在开始本节的学习之前,我们先总结一下之前所了解到的CMake基本词法和命令. CMake命令通常使用如下的格式: COMMAND( ARG1 ARG2 - ) 复制代码 命令关键字之后使用括号来包含所有的参数:各个参数之间使用空格或者换行符分隔:而参数通常有以