一起学习CMake – 03

这一节我们就一起来看看如何用CMake来链接自己写的lib库,如何进行这些库文件的管理。

 

一个团队共同开发软件时,一般都是分模块进行作业的,每个人负责整个软件中的一部分,然后再整合成一个完整的软件系统。具体的做法一般是某个人开发的东西是以链接库的形式供团队中的其他人进行调用,或者供本人负责的程序的其他模块进行调用。

比如,A童鞋开发了一种算法,能做数A与数B的加法运算,A童鞋把它编译成lib库的形式给B童鞋调用,提供给B童鞋的就只有该加法运算的头文件(让B童鞋知道这个函数的接口是怎么样的)以及相应的函数实现lib库文件,B童鞋拿到了这两个文件以后,就可以在自己的程序里面直接调用A童鞋的加法运算。

当涉及到大型的软件开发项目时,这种链接库的形式普遍存在,文件少则几十上百,多则成千上万,这个时候就需要一个工具来对这些链接库进行管理,个人觉得CMake就是一个最好的选择。有用过VTK,ITK等开源工具包的童鞋应该都知道,VTK等编译完了以后会产生好多lib文件,比如vtkCommon.lib, vtkFiltering.lib, vtkGenericFiltering.lib, vtkGraphics.lib, vtkHybrid.lib, vtkImaging.lib, vtkIO.lib……等,而且好多刚学VTK的童鞋在编译链接VTK工程时会经常碰到类似“***无法解析的外部命令”,“***.h找不到”等等这样的错误。如果你是用CMake来构建工程的话,相信这些问题都是小菜一碟而已,所以了解一点CMake的知识对你使用那些开源工具包是灰常有帮助的。

不扯那么多了,进入主题吧。这一节我们就一起来看看如何用CMake来链接自己写的lib库,如何进行这些库文件的管理。

跟《一起学习CMake - 02》一样,在CMake-Study目录下再建一个空的文件夹,就叫HelloCMake03吧(在我机子上完整路径是:D:\CMake\CMake-Study\HelloCMake3),然后把HelloCMake02里的文件都copy到这个新建文件夹里去,等下我们就在这个基础上进行更改。接着在HelloCMake03目录下再建一个新的文件夹,等下里面会存放我们自己要实现lib的文件,简单起见,我们就做一个加法运算可以了,文件夹就起名:AddFunction。接着在AddFunction里新建两个文件,分别是AddFunction.h和AddFunction.cpp,什么作用应该不用再解释了。

AddFunction.h的代码如下:

 

//做整数的加法运算

int AddFunction(int x, int y);

 

AddFunction.cpp里的代码如下:

 

#include <iostream>

int AddFunction(int x, int y)

{

                  std::cout<<x<<" + "<<y<<" = "<<x+y<<std::endl;

                  return x + y;

}

 

然后在AddFunction文件夹里再建立一个CMakeLists.txt文件,CMake原则上要求每个文件夹里都要有一个名叫CMakeLists.txt的文件,因为我们等下是要把AddFunction.h和AddFunction.cpp这两个文件生成一个lib库文件,所以我们必须告诉CMake这个事情,而CMake是只认CMakeLists.txt文件的,所以这个目录里应该要有这个文件存在,里面的内容如下:

 

add_library(AddFunction AddFunction.cpp)

 

就这么一行代码。表示什么意思?add_library命令与add_executable命令(在第01节里有介绍)其实是差不多的,前者就是生成lib库文件,后者就是生成exe文件;它们所带的参数也都是一样的,就是用这个参数列表里的源文件来生成这些lib或exe文件。

这样就完成了自己的lib库文件创建的一些工程。接着回到AddFunction的外层目录里,里面有HelloCMake.cpp; HelloCMakeConfig.h.in; CMakeLists.txt这三个文件,先打开CMakeLists.txt文件吧,把里面的代码改为:

 

cmake_minimum_required(VERSION 2.6)

project(HelloCmake)

 

# 在CMake里设置HelloCMake软件的主版本号为1,次版本号为0。

set ( HelloCMake_VERSION_MAJOR 1 )

set ( HelloCMake_VERSION_MINOR 0 )

 

# 是否要使用我们自己的lib库里的加法函数。默认是使用。

option(USE_AddFunction "Use our Add Function" ON)

 

configure_file(

         "${PROJECT_SOURCE_DIR}/HelloCMakeConfig.h.in"

         "${PROJECT_BINARY_DIR}/HelloCMakeConfig.h"

         )

 

Include_directories ("${PROJECT_BINARY_DIR}")

 

# 是否加载AddFunction库文件?

if (USE_AddFunction)

  include_directories ("${PROJECT_SOURCE_DIR}/AddFunction")

  add_subdirectory (AddFunction)

  set (EXTRA_LIBS ${EXTRA_LIBS} AddFunction)

endif (USE_AddFunction)

 

add_executable(HelloCMake hellocmake.cpp)

target_link_libraries (HelloCMake ${EXTRA_LIBS})

 

红色字体标注的是新加的代码,一起来看看这些代码作用是什么。首先是option一行代码,option也是CMake里的命令,它的作用就是在CMake GUI上增加一个选项(如图(1)所示),具体到这个例子就是增加选项”USE_AddFunction”;第二个参数”User our Add Function”是标注信息,也就是当你的鼠标停留在CMake GUI的”USE_AddFunction”选项上是会有提示信息出现;第三个参数就是这个选项的值,默认是ON,也就是使用我们自己的加法库。如果更改了这些值,然后用CMake进行Configure, Generate时,这些选项的值会保存在你在”where to build the binaries”指定的编译目录里的CMakeCache.txt文件里。当你再次打开CMake时,CMake会自动去读取CMakeCache.txt文件里的各个选项的值。

 

 

 

(1)

再看看if/endif语句块,它的作用就是根据用户的选择(即USE_AddFunction的值)来决定是否要包含子目录AddFunction(include_directories/add_subdirectory两行代码)到头文件的搜索路径中去;以及设置变量EXTRA_LIBS的值为AddFunction.lib(set一行代码)。Set命令是CMake里用于设置变量值的一个命令,使用频率灰常高。还有,if/endif语句块必须要成对出现,if和endif后面所带的参数也必须一致。

target_link_libraries命令也是用得灰常多的一个命令,它的作用就是把${EXTRA_LIBS}这个变量里的库文件链接到HelloCMake这个工程里去。${……}是取某个变量的值的意思。

最外层的CMakeLists.txt内容介绍完,接着看看HelloCMakeConfig.h.in里要添加什么东西?在该文件的最后加入如下代码:

 

#cmakedefine USE_AddFunction

 

这行代码是告诉CMake在生成HelloCMakeConfig.h文件时用”#define USE_AddFunction”或者”/*#defineUSE_AddFunction*/”来代替” #cmakedefine USE_AddFunction”,到底是前者还是后者,取决于USE_AddFunction选项的值(ON还是OFF)。编译完HelloCMake这个工程以后,打开HelloCMakeConfig.h看看就知道怎么回事了。

接着来看看HelloCMake.cpp文件,完整代码如下:

 

#include <iostream>

#include "HelloCMakeConfig.h"

 

#ifdef USE_AddFunction

#include "AddFunction.h"

#endif

 

int main(int argc, char *argv[])

{

                std::cout<<"HelloCMake软件的主版本号是:"

           << HelloCMake_VERSION_MAJOR << std::endl;

        

                std::cout<<"HelloCMake软件的次版本号是:"

           << HelloCMake_VERSION_MINOR << std::endl; 

 

                fprintf(stdout, "%s Version is: %d.%d\n",

               argv[0],

                             HelloCMake_VERSION_MAJOR,

                             HelloCMake_VERSION_MINOR);

        

                std::cout<<"Study CMake Together - HelloCMake2"<<std::endl;

 

                int a, b;

               std::cin>>a>>b;

 

#ifdef USE_AddFunction

               int addResult = AddFunction(a,b);

#else

               int  addResult = a + b;

#endif

 

                return 0;

}

 

增加的代码都粗体字显示,这些代码都比较简单,一看就能明白了,这里就不多作介绍。有了这些文件以后,走一遍CMake(Configure, Generate),整个工程也就构建完成了。

我们来看看到底发生了哪些变量,有图有真相,看图吧:

 

 

(2)

 

 

(3)

 

 

(4)

知道了这些东西,以后你在使用VTK, ITK等工具包时,再碰到类似前文提到的错误时,也就知道怎么回事了吧?下一节我们结合VTK等工具包来看看怎么链接VTK里的库文件到自己的工程里去。

如果有不对的地方,请告诉我(水灵 MSN:shuiling119@hotmail.com QQ:348774226)。

时间: 2024-11-06 03:37:29

一起学习CMake – 03的相关文章

一起学习CMake – 01

一起学习CMake – 01    本节介绍CMake里最常用的三个命令,分别是cmake_minimum_required; project; add_executable等. CMake是个好东西,在使用VTK, ITK, IGSTK, OpenCV, DCMTK等开源工具包时,是离不开CMake的,甚至有时你使用 FLTK , Qt等界面开发工具时,也经常会看到CMake,你会发现在好多目录下会有一个文件"CMakeLists.txt",这个文件就是使用CMake构建工程环境的重

一起学习CMake – 02

本节介绍如何用CMake来设置软件的版本号   在<一起学习CMake - 01>中我们看到了如何用CMakeLists.txt来构建一个最简单的工程,这一节里我们一起来看看如何用CMake对开发的软件进行版本号的设置.在介绍这方面的内容时,先简单看一下在软件开发中是如何对版本号进行设置的,如VTK 5.6.1,软件当中的版本都表示什么意思.   **************************************************************************

cmake 学习笔记(六)

希望这是现阶段阻碍阅读shiboken和PySide源码的涉及cmake的最后一个障碍 ^ _^ 学习 cmake 的单元测试部分 ctest. 简单使用 最简单的使用ctest的方法,就是在 CMakeLists.txt 添加命令: enable_testing() 该命令需要在源码的根目录文件内. 从这一刻起,就可以在工程中添加add_test命令了 add_test(NAME <name> [CONFIGURATIONS [Debug|Release|...]] [WORKING_DIR

cmake 学习笔记(三)

转自:http://blog.csdn.net/dbzhang800/article/details/6329314 接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cmake 的使用. 学习一下cmake的 finder. finder是神马东西? 当编译一个需要使用第三方库的软件时,我们需要知道: 去哪儿找头文件 .h 对比GCC的 -I 参数 去哪儿找库文件 (.so/.dll/.lib/.dylib/...) 对比GCC的 -L 参数 需要链接的库文件的名字

CMake安装使用教程

  CMake是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目. 通过编写CMakeLists.txt,可以控制生成的Makefile,从而控制编译过程.CMake自动生成的Makefile不仅可以通过make命令构建项目生成目标文件,还支持安装(make install).测试安装的程序是否能正确执行(make test,或者ctest).生成当前平台的安装包(make package).生成源码包(make package

CMake初步(2)

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

CMake入门指南

原文地址:http://www.cnblogs.com/sinojelly/archive/2010/05/22/1741337.html CMake是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目.通过编写CMakeLists.txt,可以控制生成的Makefile,从而控制编译过程.CMake自动生成的Makefile不仅可以通过make命令构建项目生成目标文件,还支持安装(make install).测试安装的程序是否能

[AS功能代码教程04] 进阶三角函数

在AS 03教程中,我们介绍了关于三角函数基础应用 现在为上次课的内容加以补充和发展 复习一下画圆的方法:x坐标cos(n),y坐标sin(n); n 从0-360的弧度 一.绘制椭圆 对比一下,我们只是把画圆方法中 R ,一分为二. 分成了 W 和 H 分别控制椭圆的宽和高. _root.createEmptyMovieClip("MC", 1); MC._x = 200; MC._y = 200; //创建一个空影片剪辑,放在舞台中央作为画线容器 var W = 50; var H

as 进阶三角函数及应用

在AS 03教程中,我们介绍了关于三角函数基础应用 现在为上次课的内容加以补充和发展 复习一下画圆的方法:x坐标cos(n),y坐标sin(n); n 从0-360的弧度 一.绘制椭圆 对比一下,我们只是把画圆方法中 R ,一分为二. 分成了 W 和 H 分别控制椭圆的宽和高. _root.createEmptyMovieClip("MC", 1); MC._x = 200; MC._y = 200; //创建一个空影片剪辑,放在舞台中央作为画线容器 var W = 50; var H