CMake入门

前言:

因为在学习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 文件,依次出现了几个命令:

  1. cmake_minimum_required:指定运行此配置文件所需的 CMake 的最低版本;
  2. project:参数值是proName,该命令表示项目的名称 。
  3. add_executable: 将源文件编译成一个名称为 exeName 的可执行文件。
编译项目

之后,在当前目录执行 cmake . ,得到 Makefile 后再使用 make 命令编译得到 Demo1 可执行文件。


多个源文件

同一目录,多个源文件

方法一: add_executable后面加多个源代码的文件名

方法二: 省事的方法是使用 aux_source_directory 命令,该命令会查找指定目录下的所有源文件,然后将结果存进指定变量名。其语法如下:

     
     
1
     
     
aux_source_directory(<dir> <variable>)
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo2)

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(Demo ${DIR_SRCS})


多个目录,多个源文件

文件目录
     
     
1
2
3
4
5
6
7
8
9
     
     
./Demo3
|
+--- main.cc
|
+--- math/
|
+--- MathFunctions.cc
|
+--- MathFunctions.h

每个文件夹下都需要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语法:

① 要求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,但是学的我云里雾里的~~~╮(╯▽╰)╭

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值