• 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 ...)
      
      其中command为命令名,args为空格分隔的参数列表,如果参数中包含空格,使用双引号引起来。命令不区分大小写。
      
      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文件的编写技巧,将在后续的文件中继续这个话题。
      CMake使用总结(2)
      项目文件组织
      
      一个项目,通常包含若干子模块。比如上一篇的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就成为可能了。


    使用Cmake生成makefile文件  点击打开链接

     如何使用CMAKE生成makefile文件 点击打开链接

  • 相关阅读:
    使用jQuery插件时避免重复引入jquery.js文件
    读书笔记《集体智慧编程》Chapter 2 : Make Recommendations
    数据挖掘学习07 《数据挖掘导论》第二章:数据
    推荐2款在线Ascii画图工具
    数据挖掘学习08 实验:使用R评估kmeans聚类的最优K
    数据挖掘学习05 使用R对文本进行hierarchical cluster并验证结果
    Apache alias目录配置
    数据挖掘学习06 《数据挖掘导论》导读
    Unix网络编程 3rd vol1 读书笔记
    关于Xcode
  • 原文地址:https://www.cnblogs.com/byfei/p/6389695.html
Copyright © 2020-2023  润新知