`

cmake使用总结

阅读更多

由于编译项目的需要使用Cmake,但对这个工具不是很熟悉,所以转载这篇文章,以备查找

原文地址

cmake使用总结(1)

http://blog.csdn.net/keensword007/archive/2008/07/10/2635513.aspx

cmake使用总结(2)

http://blog.csdn.net/keensword007/archive/2008/07/16/2663235.aspx

 

 

Table of Contents

前言
入门篇
CMake语法介绍
命令
流程控制
小结
参考书目

前言

做第一个linux项目时,Makefile是一行行敲入的,第二个项目后,开始使用cmake。至于为何选择cmake,倒不是觉得它有什么好,仅仅是因为当时项目组中的一个linux前辈向我们推荐了这个。经过一番研究之后,并在项目中使用,现将使用经验总结一下,供大家参考。

入门篇

学习一项新知识的时候,最好是从sample开始。cmake官方网站就给出了一个简单的例子。在开始之前,还是先安装cmake程序,在ubuntu下非常简单,输入以下命令即可:

$sudo apt-get install cmake

 

下面来看看sample中的内容。sample包含一个主目录,下面两个子目录: Demo和Hello。其中Hello包含程序库代码,Demo中为可执行程序,需要连接Hello中的程序库。总共有三个CMakeLists.txt文件,每个目录下一个。主目录下的CMakeLists.txt文件内容为:

    # The name of our project is "HELLO".  CMakeLists files in this project can
    # refer to the root source directory of the project as ${HELLO_SOURCE_DIR} and
    # to the root binary directory of the project as ${HELLO_BINARY_DIR}.
    project (HELLO)
    # Recurse into the "Hello" and "Demo" subdirectories.  This does not actually
    # cause another cmake executable to run.  The same process will walk through
    # the project's entire directory structure.
    add_subdirectory (Hello)
    add_subdirectory (Demo)
            

Hello目录下的CMakeLists.txt文件为:

    # Create a library called "Hello" which includes the source file "hello.cxx".
    # The extension is already found.  Any number of sources could be listed here.
    add_library (Hello hello.cxx)
            

最后,Demo包含如下CMakeLists.txt文件:

    # Make sure the compiler can find include files from our Hello library.
    include_directories (${HELLO_SOURCE_DIR}/Hello)
    # Make sure the linker can find the Hello library once it is built.
    link_directories (${HELLO_BINARY_DIR}/Hello)
    # Add executable called "helloDemo" that is built from the source files
    # "demo.cxx" and "demo_b.cxx".  The extensions are automatically found.
    add_executable (helloDemo demo.cxx demo_b.cxx)
    # Link the executable to the Hello library.
    target_link_libraries (helloDemo Hello)
            

CMake在主目录执行时,会处理该目录下CMakeLists.txt文件,然后进入到子目录,处理子目录下的CMakeLists.txt.

从字面上看,我们差不多可以理解这三个文件的涵义。第一个CMakeLists.txt文件指定包含Hello和Demo两个子目录。第二个文件则指定生成Hello库文件,第三个文件则是生成一个可执行文件helloDemo,另外两个附加语句则用来指明头文件路径以及所要链接的库。

乍一看,为了编译一个程序,需要写三个CMakeLists.txt文件,相对于原来只需写一个Makefile文件,不是更复杂了吗?事实上不尽然,虽然要写三个CMakeLists文件,但每个文件都非常简单,总共算起来,并不比一个Makefile文件多多少。更重要的是,这其中隐含着linux哲学:分而治之。每个模块自行编写配置文件,只负责自己份内的事务,所以可扩展性好。在进行大型项目开发,就可以体现出优势了。

CMakeLists.txt相当于定义了一套生成Makefile文件的规则,下面就可以生成Makefile文件了,命令如下:

$cmake .

注:.表示当前目录,如果CMakeLists.txt不在当前目录,请在cmake后面指定。在主目录下和Demo、Hello子目录下均会生成一个Makefile文件,有了这个文件,我们就可以敲入make编译目标程序了。

总结起来,使用CMake编译应用程序的流程为:

CMake语法介绍

CMake语法非常简单,包含注释、命令和空格。以#开头的行为注释行,命令则由命令名、括号及以空格进行分隔的参数组成。命令可以是诸如add_library这样的内置命令,也可以是子定义的宏或者函数。CMake的输入是主目录下的CMakeLists.txt文件,该文件可以使用include或者add_directory命令添加其它的输入文件。

命令

命令的形式如下:

command (args ...)

其中<I>command</I>为命令名,<B>args</B>为空格分隔的参数列表,如果参数中包含空格,使用双引号引起来。命令不区分大小写。

lists and strings. CMake的基本数据类型为字符串,字符串又可以组成list类型,有两种方式:一种通过分号分隔,一种通过空格分隔。比如以下例子给VAR赋了同样的值:

    set(VAR a;b;c)    set(VAR a b c) 
    

字符串列表主要用于foreach进行迭代,有些命令也用于对list进行处理。

CMake支持字符串和list类型的简单变量,变量以${VAR}形式引用。多个参数可以用set命令组成一个list,命令将展开list,例如:

    set(Foo a b c)
    command(${Foo})

等价于

    command(a b c)

如果你希望将list当作一个参数传递给命令,就应该用双引号把list引起来,如command("${Foo}")等价于command("a b c")

流程控制

写CMakeLists.txt文件就象写一个简单的程序,CMake提供了三种流程控制结构:

  • 条件语句if
        # some_command will be called if the variable's value is not: 
        # empty, 0, N, NO, OFF, FALSE, NOTFOUND, or -NOTFOUND. 
        if(var)
            some_command(...)
        endif(var)
    
  • 循环结构
        set(VAR a b c) 
        # loop over a, b,c with the variable f 
        foreach(f ${VAR})
            some_command(${f})
        endforeach(f)
        
  • 宏和函数,函数在2.6及以上版本才支持,函数和宏的区别在于函数中可定义局部变量,而宏定义的变量都是全局变量。
        # define a macro hello  
        macro(hello MESSAGE)
           message(${MESSAGE})
        endmacro(hello) 
        # call the macro with the string "hello world"  
        hello("hello world")      
        
        # define a function hello  
        function(hello MESSAGE)
            message(${MESSAGE})  
        endfunction(hello)
        

 

小结

本文通过一个简单的工程示例,我们了解到要让CMake工作起来,需要编写CMakeLists.txt文件,CMake据此生成Makefile。然后简单的过了以下CMake的语法,有了这个基础,我们就可以自行编写CMakeLists.txt文件了。当然,对于一个大型的工程,仅仅掌握这些还不够,需要进一步掌握一些CMakeLists.txt文件的编写技巧,将在后续的文件中继续这个话题。

参考书目

Jan Engels. CMake Tutorial.

. CMake官方网站:www.cmake.org.

 

cmake使用总结(2)

Abstract

本文总结了CMake在linux嵌入式系统项目开发中的应用


前言

在前面一篇文章中,我们从一个sample入手,了解了CMake的基本用法和语法。但这个例子与实际开发还有一段距离,主要存在以下几点问题:

  • 生成的二进制程序和源程序混在一起
  • 使用gcc进程程序编译,而不是使用交叉编译工具
  • 为指定编译选项,通常会生成debug版本供调试用,release版本用于发布

在本章,我们将sample程序逐步改造,解决上述问题。

项目文件组织

一个项目,通常包含若干子模块。比如上一篇的sample,我们可以认为它包含两个子模块,Hello为程序库,Demo为主程序。很少有项目会把目标二进制文件和源程序放在一起的,通常会建立一个bin目录,存放生成的二进制文件,发布程序则放在release。根据我在项目开发中的习惯,将目录结构修改如下:

            CMakeSample
               |--- release
               |--- doc
               |--- lib
               |--- source
                      |--- include
                      |--- bin
                      |--- Hello
                      |--- Demo

其中,release存放程序发布相关文件,包括程序文件、脚本、参数等。doc包含项目开发中的相关文档,如设计说明以及通过doxgen等工具从代码中生成的文档。lib存放项目中使用的第三方库,项目中自己编写的库不放在此目录,应该作为项目的一个模块放在source目录下。include包含整个项目中使用的公共头文件,如果子模块中的头文件仅在该子模块类使用,不需放到include目录。bin目录存放编译后的调试版本代码。其它的子目录则为各模块的代码及头文件。

按照以上目录结构,将Hello下的hello.h移到include目录,因为这个头文件被Demo模块包含。这个sample中未使用第三方库,所以暂时为空。

常用的几个内置变量

从上文中我们知道,通过set语句可以自定义变量,然而,CMake还包含大量的内置变量,这些变量和自定义变量的用法没有区别,下面就列出一些常用的变量:

  • CMAKE_C_COMPILER

    指定C编译器,通常,CMake运行时能够自动检测C语言编译器。进行嵌入式系统开发时,通常需要设置此变量,指定交叉编译器。

  • CMAKE_CXX_COMPILER

    指定C++编译器

  • CMAKE_C_FLAGS

    指定编译C文件时编译选项,比如-g指定产生调试信息。也可以通过add_definitions命令添加编译选项。

  • EXECUTABLE_OUTPUT_PATH

    指定可执行文件存放的路径。

  • LIBRARY_OUTPUT_PATH

    指定库文件放置的路径

常用的命令

除了内置变量,我们还可以通过命令来修改编译选项,现将一些常用的命令列出来:

  • include_directories

    指定头文件的搜索路径,相当于指定gcc编译器的-I参数

  • link_directories

    动态链接库或静态链接库的搜索路径,相当于指>定gcc的-L参数

  • add_subdirectory

    包含子目录,当工程包含多个子目录时,此命令有用

  • add_definitions

    添加编译参数,比如add_definitions(-DDEBUG)将在gcc命令行添加DEBUG宏定义

  • add_executable

    编译可执行程序

  • target_link_libraries

    指定链接库,相同于指定-l参数

小结

本文经过修改目录结构,指定编译工具链,生成动态链接库等动作,将前文的sample修改成一个比较接近实际工程的嵌入式环境。当然这个sample仍然只是一个自娱自乐的小玩意,但对于说明CMake用法已经足够了,有了这些基本的CMake知识,在项目中使用CMake就成为可能了。当然不同的环境会遇到一些新问题,借助于互联网,没有什么解决不了的问题。赶快动手吧,抛弃手工编写Makefile的痛苦,加入CMake使用者行列吧。

参考书目

Jan Engels. CMake Tutorial.

. CMake官方网站:www.cmake.org.

分享到:
评论

相关推荐

    CMake使用总结.MWB日常笔记.目录搜索1

    CMake使用总结.MWB日常笔记.目录搜索1

    cmake学习总结.doc

    cmake学习总结.doc

    cmake使用示例与整理总结.步步为赢.博客频道.CSDN1

    声明CMake的版本要求向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制的存放位置EXCLUDE_FROM_ALL含义:将这个目录从编译过程中

    CMake实践.pdf

    CMake实践是大神总结的CMake的使用用法,涵盖了CMake的所有使用方式,本人更是进一步添加了书签,是你能够快速定位到你需要的知识,本PDF为高清版+书签,学习CMake的同学可以下载。 PS:非常好的学习资料,我看完...

    CMake学习手册

    本人学习Cmake的一个总结文档,讲述CMake工作原理+Cmake命令手册!

    CMake基本语法与应用.pptx

    这是本人自己结合很多资料、博客总结出的cmake基本语法,用于组内分享

    CMake项目构建总结 - yzlworld的专栏 - 博客频道 - CSDN1

    摘要视图订阅yzlworld的专栏登录 | 注册嵌入式开发相关(24)[plain] view plainprint01.[plain] view plainp

    CMake从入门到实战系列(二)-实例入手,讲解CMake的基本流程

    上一篇文章,我们对什么是CMake、CMake和Makefile优缺点、CMake安装方法进行了总结,本篇文章则开始对CMake的使用流程进行总结,以实例demo入手,以便读者阅读后能快速的上手去操作和运用。

    cmake笔记资料

    自己针对cmake的使用总结的文档,如有需要可以下载使用。

    VS2019中CMake项目的简单使用方法

    以下是博主使用CMake的一些总结,仅供参考。 1.建立CMake项目文件 在创建项目界面可直接搜索cmake找到创建项目。 为了方便使用可以选择将解决方案和项目放到同一个目录。 2.CMakeList的配置 在创建好项目后如果...

    CMake从入门到实战系列(六)-CMake自定义编译选项

    下面实例入手总结CMake的自定义编译选项:   考虑一个简单的C语言项目,我们想让用户决定是否启用一个名为FEATURE_X的自定义特性。如果启用,我们将编译带有特殊行为的代码;如果不启用,我们将编译默认行为的代码...

    OpenCV的Cmake扩展编译

    详细描述OpenCV3.4.0扩展编译的过程,总结其中踩过的雷,避免好多坑的首选方法。

    cmake常用代码

    本文档对cmake常用的语句进行了 总结,说明其含义,并列举了相应的例子。

    详解Android studio ndk配置cmake开发native C

    本文是参考Add C and C++ Code to Your Project 官方文档(需要翻墙),经过各种尝试之后的总结。 Android studio整合NDK开发,有两种模式,一种是ndk build,一种是cmake,如果是新项目官方推荐cmake。原来,ADT的...

    CMakeLists使用总结介绍.zip

    个人学习使用

    mysql-5.5.28源码安装过程中错误总结

    介绍一下关于mysql-5.5.28源码安装过程中几大错误总结,希望此文章对各位同学有所帮助。系统centOS 6.3 mini (没有任何编译环境)预编译环境首先装了众所周知的 cmake(yum install cmake -y) 代码如下:、./...

    与 PEST 模型优化软件一起使用的时间序列处理器_Fortran_代码_下载

    构建过程总结 在源目录结构之外创建一个构建目录并更改目录。如果您已克隆此存储库,那么您应该在“build”子目录中找到几个子目录,其中包含旨在在调用 CMake 之前设置环境变量和编译选项的脚本。CMake 获取这些...

    openal学习笔记

    一步步介绍了使用openal的步骤,是我学习过后的总结。附带完整的源代码。

    CGAL安装总结

    CGAL和VS2010和QT4或者QT3和Boost和CMake进行综合安装,总结的文档,其中遇到很多问题,最后安装了10天,装了卸卸了装,综合两台电脑,最后总结出来的经验,希望可以得到应用!

    linux下读写INI配置文件库

    这里特做了总结。希望能帮到各位开发中的朋友。 1.linux下INI配置文件读写操作库 ======================================================================== if(false) SET(CMAKE_SYSTEM_NAME Linux) set...

Global site tag (gtag.js) - Google Analytics