前言:
因为在学习VTK的过程中,我的操作系统win7 X64 + vs2012 X64 + VTK 7.0.0 ,VTK编程使用CMake编译要远比不使用它更实用。直接在VS中新建项目需要调用它的一些模块,不知道是不是因为VTK7.0.0是最新版的资源还不全,目前我还没有找到比较全面的宏命令来完成Implementation Modules部分。所以只有好好学习CMake,避免可能遇到的其他问题,此外,不是说,会不会写makefile,从一个侧面说明一个人是否具备完成大型工程的能力吗? so come on ...
参考链接:
CMake 入门实战
本文目的:总结自己在学习CMake这部分学习得到的知识点。 Write once, run everywhere.
CMake 是一个编译配置工具。
Windows下使用CMake教程 (我才发现我一直是错的)
可以描述为:
① 编写.cxx和CMakeLists.txt
② 运行cmake-gui.exe, 选择源代码所在文件夹(source code)和生成路径(where to build the binaries)
③ 执行configure,需要选择合适的编译器直到没有红色
④ 执行generate,直到generate done
⑤ 在命令提示符窗口中,生成路径下,运行 make 进行编译
⑥ 运行.exe文件
编写 CMakeLists.txt
首先,编写CMakeLists.txt,并保存在源文件同个目录下# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (proName)
# 指定生成目标
add_executable(exeName **.cxx)
CMakeLists.txt 的语法比较简单,由命令、注释和空格组成,其中命令是不区分大小写的。符号 #
后面的内容被认为是注释。命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔。
对于上面的 CMakeLists.txt 文件,依次出现了几个命令:
-
cmake_minimum_required
:指定运行此配置文件所需的 CMake 的最低版本; project
:参数值是proName,该命令表示项目的名称 。-
add_executable
: 将源文件编译成一个名称为 exeName 的可执行文件。
编译项目
之后,在当前目录执行 cmake .
,得到 Makefile 后再使用 make
命令编译得到 Demo1 可执行文件。
多个源文件
同一目录,多个源文件
方法一: add_executable后面加多个源代码的文件名方法二: 省事的方法是使用 aux_source_directory
命令,该命令会查找指定目录下的所有源文件,然后将结果存进指定变量名。其语法如下:
|
|
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo2)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 指定生成目标
add_executable(Demo ${DIR_SRCS})
多个目录,多个源文件
文件目录
|
|
每个文件夹下都需要CMakeLists.txt. 为了方便,我们可以先将 math 目录里的文件编译成静态库再由 main 函数调用。 根目录中的 CMakeLists.txt :
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo3)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 添加 math 子目录
add_subdirectory(math)
# 指定生成目标
add_executable(Demo main.cc)
# 添加链接库
target_link_libraries(Demo MathFunctions)
命令
add_subdirectory
指明本项目包含一个子目录 math, 这样 math 目录下的 CMakeLists.txt 文件和源代码也会被处理 。命令
target_link_libraries
指明可执行文件 main 需要连接一个名为 MathFunctions 的链接库 。
子目录中的 CMakeLists.txt:
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)
# 生成链接库
add_library (MathFunctions ${DIR_LIB_SRCS})
自定义编译选项
CMake 允许为项目增加编译选项,从而可以根据用户的环境和需求选择最合适的编译方案。【有待商榷】
① 要求CMake根据指定的源文件生成可执行文件
add_executable(demo main.cpp main.h main.rc)
② 调试CMakeLists.txt的办法
演示1 会显示一个警告框, 如下:
MESSAGE("俺们正在生成项目文件")
演示2 遇到这条指令,会把文字显示在状态栏里面(一闪而过,不容易发现),如下:
MESSAGE(STATUS "俺们正在创建项目文件")
演示3 这条指令会提示 出错,并退出,如下:
MESSAGE(FATAL_ERROR "严重错误,俺们搞不定啦")
③
使用标准模块
cmake提供了很多标准模块,扩展名都是txt.我们可以直接包含进来。就像使用C语言的#include指令一般。比如:
INCLUDE(FindBoost)
一句话,就告诉了CMake“我们的程序需要Boost”。
④ 使用变量
SET( MY_SOURCES main.cpp widget.cpp)
MESSAGE(STATUS "my sources: ${MY_SOURCES}")
SET()命令来为变量设置值。如果你列出了一个以上的字符串,变量将是串列表。列表是一列由分号隔开的字符串。如果只设置个一项,那么这项只有一个值。可以通过${VAR}获得变量的值。
可以使用FOREACH()来迭代一份列表:
FOREACH(next_ITEM ${MY_SOURCES})
MESSAGE(STATUS "next item: ${next_ITEM}")
ENDFOREACH(next_ITEM ${MY_SOURCES})
CMake中的命令是大小写无关的。变量名和参数名是大小写相关的。
办法一 (这个代码没有检验过哦)
IF (UNIX)
MESSAGE("这个是UNIX操作系统")
ENDIF (UNIX)
IF (MSVC)
MESSAGE("这个需要做VC的项目文件")
ENDIF (MSVC)
办法二 (这个测试过)
IF (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
SET(option WIN32)
SET(win32_LIBRARIES comctl32.lib shlwapi.lib shell32.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib)
#SET(defs -DUNICODE -D_UNICODE)
ENDIF (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
⑥ 要求CMake根据指定的源文件生成库文件
ADD_LIBRARY(libname [SHARED | <strong>STATIC</strong> | MODULE] [EXCLUDE_FROM_ALL] <span style="font-family: Arial; font-size: 14px; line-height: 26px;"> source1 source2 ... sourceN)</span>
⑦ 添加查找头文件的路径 .
INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
⑧
添加库文件的搜索路径 .
LINK_DIRECTORIES(directory1 directory2 ...)
⑨ 显式指定链接时需要的库文件
TARGET_LINK_LIBRARIES(target library1 <debug | optimized> library2 ...)
为所有目标统一指定需要的库文件(指定所有目标都用的库文件)
⑩ 显式实施宏定义
# 用法演示一(文本宏):
ADD_DEFINITIONS(-DDEBUG)
# 用法演示二(常量宏)
ADD_DEFINITIONS(-DVERSION=1)
常用的CMake变量
详细内容请参考CMake Useful Variables。
今天的目标本来是学习CMake,但是学的我云里雾里的~~~╮(╯▽╰)╭