树形结构方式布局。

OTL 中每一个文件中的CMakeLists.txt 有不同的作用:按查看文件的先后顺便进行分层理解, 根文件即第一次 中的.txt是 启用 CMAKE_MODULE_PATH模板,加载相关文件,每一层的.txt负责创建同一层不同文件夹的子目录。如:add_subdirectory("${CMAKE_SOURCE_DIR}/Test"). 然后进入第二层,在第一层创建了相应文件夹的子目录中再进行遍历,具体与第一层类似。在遍历文件的数据结构类似树的结点,如 对Test文件进行遍历,首先设置路径: set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin/test"},然后将路径加载到list_projects中 list_projects("${CMAKE_CURRENT_SOURCE_DIR}"),最后循环遍历每一个子文件。foreach(PROJECT_ITEM ${PROJECT_LIST})

  message("Adding test: " " ${PROJECT_ITEM}")

  add_subdirectory("${PROJECT_ITEM}")

endforeach()

3.Cmake使用

3.1.单个文件示例

    下面是一个简单的C程序代码(打印“helloworld!”字符串):
#include <stdio.h>
 
int main(void)
{
   printf("hello world!\n");
   return 0;
}
   在H:\CmakeTest目录下创建一个Exp1目录,在该目录下创建一个main.c文件,内容为上面的C程序代码,然后再创建一个CMakeLists.txt文件,内容如下:
PROJECT (HELLO)
SET (SRC_LIST main.c)
ADD_EXECUTABLE (hello ${SRC_LIST})
   最后,在Exp1目录中创建一个build子目录,进入build目录,调用cmake命令自动生成项目文件,然后执行nmake进行编译生成可执行文件:
H:\CmakeTest\Exp1> mkdir build & cdbuild
H:\CmakeTest\Exp1\build> cmake ..-G"NMake Makefiles”
H:\CmakeTest\Exp1\build> nmake
   注1:为了简单起见,上面采用cmake的Out-Of-Source方式构建,即生成的中间产物和代码相分离。
   注2:必须使用“VisualStudio 2008 Command Line”快捷方式打开命令行窗口,然后执行上面的命令,否则不能创建“NMake Makefiles”的项目。
   注3:如果使用MinGW开发环境进行编译,执行下面的cmake命令:
#> cmake .. -G”MinGW Makefiles”
#> make
   nmake编译完成后,在当前目录下会生成一个hello.exe,运行它会在屏幕上打印“hello world!”字符串。
H:\CmakeTest\Exp1\build>hello.exe
hello world!
   此时,目录结构如下:
H:\CMAKETEST\EXP1
│  CMakeLists.txt
│  main.c

└─build
    │  CMakeCache.txt
    │  cmake_install.cmake
│  hello.exe   
│  ……
   CMakeLists.txt文件说明:
   第一行PROJECT不是强制性的,推荐使用,这一行会引入两个变量HELLO_BINARY_DIR和HELLO_SOURCE_DIR。同时cmake自动定义了两个等价的变量PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR。由于基于Out-Of-Source方式构建,务必注意这两个变量对应的目录,可以通过MESSAGE来输出变量的值,例如:MESSAGE(${PROJECT_SOURCE_DIR})。
   SET命令用于设置变量。
   ADD_EXECUTABLE命令用于告诉工程生成一个可执行文件。
   ADD_LIBRARY命令用于告诉工程生成一个库文件。
注意:CMakeLists.txt文件中,命令的名称是不区分大小写的,而参数和变量名是大小写敏感的。
Cmake命令说明:
Cmake命令后面跟一个路径参数,它用来指定CMakeLists文件所在的位置。
由于系统中可能有多套构建工程的开发环境,我们可以通过-G命令行参数来指定生成那种工程,你可以通过cmake --help命令获得-G参数的详细信息。
如果要显示执行构建工程过程中详细信息,可以在CMakeLists.txt文件中加入:
SET (CMAKE_VERBOSE_MAKEFILEon)
或者执行make时:
$ make VERBOSE=1
或者
$ exportVERBOSE=1
$ make

3.2.多个文件示例

    下面针对多个文件构建工程,假设有hello.h/hello.c/main.c三个源代码文件,如下所示:
Hello.h代码:
#ifndef __HELLO_H__
#define __HELLO_H__
void hello(const char *name);
#endif
Hello.c代码:
#include "hello.h"
#include <stdio.h>
 
void hello(const char *name)
{
    printf("hello%s!\n", name);
}
Main.c代码:
#include "hello.h"
 
int main(void)
{
    hello("world");
    return 0;
}
  在CMakeTest目录下创建Exp2目录,并且在Exp2目录中创建上面的三个源代码文件,然后再创建CMakeLists.txt文件,内容如下:
PROJECT(HELLO)
SET(SRC_LIST main.c hello.c)
ADD_EXECUTABLE (hello ${SRC_LIST})
   创建build目录,进入到该目录进行构建,如下所示:
H:\CmakeTest\Exp2>mkdirbuild & cd build
H:\CmakeTest\Exp2\build>cmake.. -G"NMake Makefiles"
构建完成后使用nmake进行编译生成hello程序,然后运行程序如下所示:
H:\CmakeTest\Exp2\build>nmake
H:\CmakeTest\Exp2\build>hello
hello world!
Exp2的目录结构如下所示:
H:\CMAKETEST\EXP2
│  CMakeLists.txt
│  hello.c
│  hello.h
│  main.c

└─build
    │  CMakeCache.txt
    │  cmake_install.cmake
    │  hello.exe

3.3.生成库文件示例

    还是使用上面例子中多个源代码,这里我们将hello.c生成一个库,然后在main.c中调用。修改CMakeLists.txt文件如下:
PROJECT (HELLO)
SET(SRC_LIBhello.c)
SET(SRC_APPmain.c)
ADD_LIBRARY(libhello ${SRC_LIB})
ADD_EXECUTABLE(hello ${SRC_APP})
TARGET_LINK_LIBRARIES(hellolibhello)
在上面的文件中,我们添加一个新的目标库libhello,并且把它链接到hello程序中。
注:在CMakeTest目录下创建一个Exp3目录,然后把Exp2目录中除build目录以外的4个文件拷贝到该目录下,最后修改CMakeLists.txt文件内容。
创建一个build目录进行构建工程:
H:\CmakeTest\Exp3>mkdirbuild & cd build
H:\CmakeTest\Exp3\build>cmake.. -G"NMake Makefiles"
H:\CmakeTest\Exp3\build>hello.exe
   由于可执行程序使用hello这个名称,此时添加类时就不能使用这个名称,而是使用libhello,此时编译生成的库名为libhello.lib,如果希望生成hello.lib库,添加下面一行:
SET_TARGET_PROPERTIES(libhelloPROPERTIES OUTPUT_NAME “hello”)
   注意:推荐添加设置选项为cmake_minimum_required(VERSION2.8)。

3.4.多个目录示例

    源文件位于多个目录情况下构建工程,源代码放置于不同路径下的结构如下:
H:\CMAKETEST\EXP4
│  CMakeLists.txt

├─build
├─libhello
│      CMakeLists.txt
│      hello.c
│      hello.h

└─src
       CMakeLists.txt
       main.c
Exp4目录下的CMakeLists.txt文件,内容如下:
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
PROJECT(HELLO)
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(libhello)
Src目录下的CMakeLists.txt文件,内容如下:
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/libhello)
SET(SRC_APP main.c)
ADD_EXECUTABLE(hello${SRC_APP})
TARGET_LINK_LIBRARIES(hellolibhello)
Libhello目录下CMakeLists.txt文件,内容如下:
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
SET(SRC_LIB hello.c)
ADD_LIBRARY(libhello ${SRC_LIB})
SET_TARGET_PROPERTIES(libhello PROPERTIES OUTPUT_NAME"hello")
建立build目录构建工程,在build目录中执行下面命令:
H:\CmakeTest\Exp4\build>cmake .. -G"NMake Makefiles"
H:\CmakeTest\Exp4\build>nmake
H:\CmakeTest\Exp4\build>src\hello
生成的执行文件位于build\src目录中,库文件位于build\libhello目录中。
在Exp4目录中的CMakeLists.txt文件中:
ADD_SUBDIRECTORY命令用来告诉cmake去子目录中查找可用的CMakeLists.txt文件。
在Src目录中的CMakeLists.txt文件中:
   INCLUDE_DIRECTORIES命令用来指明头文件所在的路径。

3.5.指定输出目录示例

     要求把生成的可执行文件和库文件分别输出到bin目录和lib目录下,目录结构如下:
H:\CMAKETEST\EXP5
│  CMakeLists.txt

├─build
│  ├─bin
│  └─lib
├─libhello
│      CMakeLists.txt
│      hello.c
│      hello.h

└─src
        CMakeLists.txt
        main.c
第一种方法,修改Exp5目录下的CMakeLists.txt文件,如下所示:
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)
ADD_SUBDIRECTORY(libhello lib)
这种方法在build目录下生成bin和lib目录替换上例中src和libhello目录,不满足要求。
第二种方法,不修改顶级文件,修改其它两个文件,如下:
src/CMakeLists.txt文件:
CMAKE_MINIMUM_REQUIRED (VERSION2.8)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/libhello)
#LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/lib)
SET(SRC_APP main.c)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
ADD_EXECUTABLE(hello ${SRC_APP})
TARGET_LINK_LIBRARIES(hello libhello)
libhello/CMakeLists.txt文件:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(SRC_LIB hello.c)
ADD_LIBRARY(libhello ${SRC_LIB})
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
SET_TARGET_PROPERTIES(libhello PROPERTIES OUTPUT_NAME"hello")
上面主要是设置LIBRARY_OUTPUT_PATH和EXECUTABLE_OUTPUT_PATH两个环境变量。
在build目录下使用cmake构建工程,nmake进行编译,命令如下:
H:\CmakeTest\Exp4\build>cmake.. -G"NMake Makefiles"
H:\CmakeTest\Exp4\build>nmake

3.6.编译动态库示例

    上述示例中都是使用静态库,下面考虑下如何编译成动态库。
如果不是Windows操作系统,Linux/Unix下生成动态库很容易,只要修改下libhello/CMakeLists.txt文件中的ADD_LIBRARY命令(添加SHARED参数)即可,如下所示:
ADD_LIBRARY(librarySHARED ${SRC_LIB})
如果要做到Windows和Linux下可移植性,需要修改hello.h的头文件,如下所示:
#ifndef__HELLO_H__
#define__HELLO_H__
#ifdef WIN32
#ifLIBHELLO_BUILD
#defineLIBHELLO_API __declspec(dllexport)
#else
#define LIBHELLO_API__declspec(dllimport)
#endif
#else
#defineLIBHELLO_API
#endif
LIBHELLO_APIvoid hello(const char *name);
#endif
修改libhello/CMakeLists.txt文件
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(SRC_LIBhello.c)
ADD_DEFINITIONS("-DLIBHELLO_BUILD")
ADD_LIBRARY(libhelloSHARED${SRC_LIB})
SET(LIBRARY_OUTPUT_PATH${PROJECT_BINARY_DIR}/lib)
SET_TARGET_PROPERTIES(libhelloPROPERTIES OUTPUT_NAME "hello")
接下来可以在build目录下使用cmake进行构建,构建完成后就可以编译和执行。
H:\CmakeTest\Exp6\build>cmake.. -G"NMake Makefiles"
H:\CmakeTest\Exp6\build>nmake
注:在bin目录下的hello.exe无法运行,必须先把lib目录下的hello.dll拷贝到bin目录才能正常运行。
转载:http://blog.csdn.net/fan_hai_ping/article/details/8208898

310实验室(六)CMake学习心得的更多相关文章

  1. 20165221—JAVA第六周学习心得

    课本知识点小结 第8章:常用实用类 String类 常量对象放入常量池中,而用string声明的对象变量中存放着引用.凡是new构造的常量都不在常量池中. startIndex表示提取字符的起始位置, ...

  2. 我的MYSQL学习心得(六) 函数

    我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  3. 我的MYSQL学习心得(十六) 优化

    我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  4. 我的MYSQL学习心得(六)

    原文:我的MYSQL学习心得(六) 我的MYSQL学习心得(六) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL ...

  5. windows类书的学习心得(转载)

    原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...

  6. windows类书的学习心得

    原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...

  7. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  8. 我的MYSQL学习心得(二) 数据类型宽度

    我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  9. 我的MYSQL学习心得(三) 查看字段长度

    我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

随机推荐

  1. ubuntu 12.04 LTS server 中文乱码【转】

    ubuntu 12.04 LTS server 中文乱码 最近装了一台ubuntu 12.04 server装完后是没有桌面的,后来又手动安装了桌面,但进行后发现桌面是乱码,应该是缺少字体在googl ...

  2. 使用ffmepg的lib库调试,debug版本下调试无问题,但release版本会出现跑飞的现象

    如题(“使用ffmepg的lib库调试,debug版本下调试无问题,但release版本会出现跑飞的现象”). 今天使用ffmpeg进行宿放和颜色格式转换,很简单的代码,却折腾了我一天,这里说来就气啊 ...

  3. 在系统中使用read函数读取文件内容

    read函数(读取文件) read函数可以读取文件.读取文件指从某一个已打开地文件中,读取一定数量地字符,然后将这些读取的字符放入某一个预存的缓冲区内,供以后使用. 使用格式如下: number = ...

  4. 一个不错的在线的js调试器

    一个不错的在线的js调试器,可见即可得: http://jsbin.com/

  5. luasql在Fedora20下的安装与使用示例

    主要参考:http://www.boll.me/archives/614 luasql安装, 在终端通过yum命令安装: yum -y install lua-sql 接下来写个测试的lua脚本文件( ...

  6. 反编译工具 jad

    JAD(Java Decompiler)是一个比较流行的Java反编译工具,可以从网站 http://www.varaneckas.com/jad/ 下载,有多个系统下的应用程序,包括Windows. ...

  7. asp.net线程批量导入数据时通过ajax获取执行状态

    最近因为工作中遇到一个需求,需要做了一个批量导入功能,但长时间运行没个反馈状态,很容易让人看了心急,产生各种臆想!为了解决心里障碍,写了这么个功能. 通过线程执行导入,并把正在执行的状态存入sessi ...

  8. MathType在字母上加虚线的方法

    在数学中根据不同的需要,会对其中的公式或变量字母作不同的标记.这些标记在用MathType编辑数学公式时同样也要准确地编辑出来,例如在字母上方加虚线.这种数学样式在使用时也是根据自己的数学问题来使用的 ...

  9. DEDECMS教程:首页实现分页的两种方法

    有两种办法可以实现: 一.用arclist标签+Ajax实现织梦首页分页 二.交叉栏目ID 实现织梦首页分页 一.用arclist标签+Ajax实现织梦首页分页 1.必须在首页<head> ...

  10. MAC快捷键使用大全

    当写到标题的时候.突然想起刚接触电脑的时候总是会有一些window希统快捷键大全.foxmail快捷键使用大全,最没想到的是,作为一个说不上资深.也是有了年头的程序猿,到现在.我还要在写一个快捷键使用 ...