转载--网易博客--水灵
在《一起学习CMake - 03》一节中我们讲到了怎么用CMake来管理lib库文件,这一节里我们结合VTK的lib库文件,看看CMake里的CMakeLists.txt文件要怎么写。
还是跟前面几节一样,在CMake-Study目录下建立一个文件夹,起名为HelloCMake4,在我机子的完整路径是:D:\CMake\CMake-Study\HelloCMake4。
首先在这个文件夹里建立CMakeListst.txt文件,内容如下:
cmake_minimum_required(VERSION 2.6)
PROJECT(HelloCMake)
# 在CMake里设置HelloCMake软件的主版本号为1,次版本号为0。
set ( HelloCMake_VERSION_MAJOR 1 )
set ( HelloCMake_VERSION_MINOR 0 )
configure_file(
"${PROJECT_SOURCE_DIR}/HelloCMakeConfig.h.in"
"${PROJECT_BINARY_DIR}/HelloCMakeConfig.h"
)
Include_directories ("${PROJECT_BINARY_DIR}")
# 在CMake-GUI上增加选项USE_VTK_LIBS。默认值为ON。
option(USE_VTK_LIBS "Use VTK libs" ON)
# 是否加载VTK库文件?
if (USE_VTK_LIBS)
# Find VTK.
FIND_PACKAGE(VTK)
IF(VTK_FOUND)
INCLUDE(${VTK_USE_FILE})
ELSE(VTK_FOUND)
MESSAGE(FATAL_ERROR "Cannot build without VTK. Please set VTK_DIR.")
ENDIF(VTK_FOUND)
endif (USE_VTK_LIBS)
add_executable(HelloCMake hellocmake.cpp)
if (USE_VTK_LIBS)
TARGET_LINK_LIBRARIES(HelloCMake vtkRendering vtkIO)
endif (USE_VTK_LIBS)
接着写一个HelloCMake.cpp文件,完整内容如下:
#include <iostream>
#include "HelloCMakeConfig.h"
// 如果用户选择使用VTK,则包含相关的头文件
// 如果USE_VTK_LIBS的值为ON,就是定义了宏#define USE_VTK_LIBS;
// 如果USE_VTK_LIBS的值为OFF,就是/* #undef USE_VTK_LIBS */
// 这些都定义在自动生成的HelloCMakeConfig.h里。
#ifdef USE_VTK_LIBS
#include <vtkBMPReader.h>
#include <vtkImageViewer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#endif
int main(int argc, char *argv[])
{
if ( argc <2 )
{
std::cout<<"请输入命令行参数,格式如下:"<<std::endl;
std::cout<<argv[0]<<" InputBMPFileName"<<std::endl;
return -1;
}
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 – HelloCMake4"<<std::endl;
const char *fileName = argv[1];
#ifdef USE_VTK_LIBS
vtkSmartPointer<vtkBMPReader> bmpReader =
vtkSmartPointer<vtkBMPReader>::New();
bmpReader->SetFileName(fileName);
vtkSmartPointer<vtkImageViewer> bmpViewer =
vtkSmartPointer<vtkImageViewer>::New();
bmpViewer->SetInput(bmpReader->GetOutput());
bmpViewer->SetColorLevel(128);
bmpViewer->SetColorWindow(256);
bmpViewer->Render();
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
bmpViewer->SetupInteractor(interactor);
interactor->Initialize();
interactor->Start();
#endif
return 0;
}
然后是HelloCMakeConfig.h.in文件,内容跟上节的差不多:
// the configured options and settings for HelloCMake
#define HelloCMake_VERSION_MAJOR @HelloCMake_VERSION_MAJOR@
#define HelloCMake_VERSION_MINOR @HelloCMake_VERSION_MINOR@
#cmakedefine USE_VTK_LIBS
最后走一遍CMake(Configure, Generate),程序运行结果如图(1):
图(1)
一起来看看CMakeLists.txt里增加的几个命令都表示什么意思,把相关代码再贴一下:
if (USE_VTK_LIBS)
# Find VTK.
FIND_PACKAGE(VTK)
IF(VTK_FOUND)
INCLUDE(${VTK_USE_FILE})
ELSE(VTK_FOUND)
MESSAGE(FATAL_ERROR "Cannot build without VTK. Please set VTK_DIR.")
ENDIF(VTK_FOUND)
endif (USE_VTK_LIBS)
新增的命令是FIND_PACKAGE, INCLUDE, MESSAGE。Find_package作用就是搜索某一个模块,在CMake的安装目录下预先定放了很多模块,如图(2)所示。
图(2)
每个模块都是以Find***.cmake命令,比如红框里的FindVTK.cmake,当调用命令FindPackage( VTK )时,CMake就会调用模块FindVTK.cmake,然后去找本机中编译VTK的目录。如果找到了VTK,就会把VTK的目录设置到CMake-GUI上的VTK_DIR选项上,并包含与VTK有关的目录,这就是INCLUDE(${VTK_USE_FILE})的作用;如果找不到,就会调用命令MESSAGE(FATAL_ERROR "Cannot build without VTK. Please set VTK_DIR.")在CMake-GUI上提示出错,如图(3)所示。
(3)
碰到这种情况,就是CMake无法自己搜索相关的模块,你可以通过手动设置VTK_DIR或者ITK_DIR的值。也就是把VTKConfig.cmake,ITKConfig.cmake或其他的模块文件所在的完整目录路径给相应的***_DIR就可以了。
看完CMakeLists.txt里的内容,然后来看看HelloCMake.cpp文件里的内容,这个程序非常简单,完成的功能:根据用户在CMake-GUI上的选择,如果没有勾选USE_VTK_LIBS选项,程序跟第二节里的一模一样;如果选上了USE_VTK_LIBS选项,就会调用VTK里的类,读入一幅BMP图像,然后用VTK的窗口显示出来,程序的执行结果如图(1)所示。
该程序支持命令参数输入,对于命令行参数,有些非计算机专业的童鞋可能还不知道怎么来让这个程序运行,因为如果不给程序参数的话,程序就直接退出。要给程序命令行参数,可以这么来做:(1) 更改程序的代码,把程序中:
if ( argc <2 )
{
std::cout<<"请输入命令行参数,格式如下:"<<std::endl;
std::cout<<argv[0]<<" InputBMPFileName"<<std::endl;
return -1;
}
注释掉,然后把bmp图像的完整路径或相对路径给const char *fileName = argv[1]一行代码,然后编译运行程序即可。(2) 在VS环境下运行程序时,可以右击该工程->属性->配置属性->Debugging->Command Arguments(如图(4)所示)里输入程序要接收的参数即可。在调试程序时用这两种方法都可以,个人感觉用第二种方法比较好。
(4)
如果有不对的地方,请告诉我(水灵 MSN:shuiling119@hotmail.com QQ:348774226)。