CMake简介
一、CMake简介
- CMake是一个跨平台的编译工具,能够输出各种各样的makefile或者project文件。
- CMake并不直接构建出最终的软件,而是生成标准的Makefile文件或者VisualStudio项目文件,然后再使用Make或者VisualStudio进行编译。
- CMake在Windows平台上生成VisualStudio项目文件,在Linux和Unix平台上生成Makefile文件。
二、CMake典型示例
源代码 demo.cpp
int main()
{
return 0;
}
cmake脚本 CMakeLists.txt
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (demo)
# 指定生成目标
add_executable(demo demo.cpp)
编译流程
Windows
- 创建build文件夹
- 在build文件夹中执行
cmake ..
命令 - 用Visual Studio打开生成的demo.sln,然后编译
Linux
mkdir build
cd build
cmake ..
make
三、CMake常用命令
CMake中常用的语法包含三类:
- 命令
- 变量
- 属性
常用命令介绍
- cmake_minimum_required (VERSION 2.8) 要求cmake的最小版本
- project(demo) 设置项目名字,windows下会生成demo.sln
设置编译目标类型
- add_executable 生成可执行文件
- add_library 生成库文件
比如:
add_executable(demo demo.cpp)
add_library(common util.cpp)
add_library默认生成静态库,可以显式的控制生成的库的类型
add_library(common STATIC util.cpp) #生成静态库
add_library(common SHARED util.cpp) #生成动态库或共享库
通过以上命令生成文件名字,在Windows下是:
demo.exe
common.lib
common.dll
在Linux下是:
demo
libcommon.a
libcommon.so
指定编译包含的源文件
- 明确指定包含的源文件
add_executable(demo demo.cpp test.cpp util.cpp)
- 搜索所有的cpp文件
aux_source_directory(. SRC_LIST) #搜索当前目录下的所有.cpp文件
add_executable(demo ${SRC_LIST})
- 自定义搜索规则
file(GLOB SRC_LIST "*.cpp" "*.cc")
add_executable(demo ${SRC_LIST})
- 包含多个文件夹的文件
file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_executable(demo ${SRC_LIST})
# 或者
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_executable(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
# 或者
aux_source_directory(. SRC_LIST)
aux_source_directory(protocol SRC_PROTOCOL_LIST)
add_executable(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
- 通过模糊搜索的方式包含源文件,当添加新的源文件后,需要通过cmake命令重新生成Makefile或者VS项目文件
设置包含目录
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
)
Linux下还可以通过如下方式设置包含目录
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}")
设置链接库搜索目录
link_directories(
${CMAKE_CURRENT_SOURCE_DIR}/libs64
)
Linux下还可以通过如下方式设置包含目录
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs64")
设置需要链接的库
根据链接库目录搜索
target_link_libraries(demo Math)
- 在Windows下,会根据链接库目录,搜索
Math.lib
文件 - 在Linux下,会根据链接库目录搜索如下文件:
libMath.so
libMath.a
默认优先链接动态库,可以在链接时指定动态库或者静态库如:
target_link_libraries(demo Math.a) # 链接libMath.a
target_link_libraries(demo Math.so) # 链接libMath.so
指定全路径
target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs64/libMath.a)
target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs64/libMath.so)
指定多个链接库
target_link_libraries(demo
${CMAKE_CURRENT_SOURCE_DIR}/libs64/libMath.a
boost_system.a
boost_thread
pthread)
设置变量
- set 直接设置变量的值
set(SRC_LIST main.cpp test.cpp)
add_executable(demo ${SRC_LIST})
- set 追加变量的值
set(SRC_LIST main.cpp)
set(SRC_LIST ${SRC_LIST} test.cpp)
add_executable(demo ${SRC_LIST})
- list 追加或者删除变量的值
set(SRC_LIST main.cpp)
list(APPEND SRC_LIST test.cpp)
list(REMOVE_ITEM SRC_LIST main.cpp)
add_executable(demo ${SRC_LIST})
条件控制
- if else elseif endif
if(MSVC)
set(LINK_LIBS common)
else()
set(boost_thread boost_log.a boost_system.a)
endif()
target_link_libraries(demo ${LINK_LIBS})
# 或者
if(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fpermissive -g")
else()
add_definitions(-D_SCL_SECURE_NO_WARNINGS
-D_CRT_SECURE_NO_WARNINGS
-D_WIN32_WINNT=0x601
-D_WINSOCK_DEPRECATED_NO_WARNINGS)
endif()
if(${CMAKE_BUILD_TYPE} MATCHES "debug")
...
else()
...
endif()
- while break continue foreach end_while end_foreach
其他常用命令
- message 显示一些消息
message(${MY_VAR})
message("build with debug mode")
message(WARNING "this is warnning message")
message(FATAL_ERROR "this build has many error") # 会导致生成失败
- source_group 在Windows下起作用,设置源文件在项目中的目录结构
file(GLOB PROTOCOL_FILES "protocol/*.cpp")
source_group("协议" FILES ${PROTOCOL_FILES})
- set_target_properties 设置项目属性
- set_property 设置全局属性、项目属性等
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
#设置项目在解决方案中的目录结构,只在Windows下生效
set_target_properties(ServerManager PROPERTIES FOLDER "manager")
- include 包含其他cmake文件
include(./common.cmake) #指定包含文件的全路径
include(def) #在搜索路径中搜索def.cmake文件
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) #设置include的搜索路径
四、复杂项目示例
多个目录,多个源文件,多个项目
项目目录结构如下:
./demo
|
+--- main.cc
|
+--- math/
|
+--- MathFunctions.cc
|
+--- MathFunctions.h
这种情况还可以通过add_subdirectory的方式添加子目录
添加cmake脚本后的目录结构如下:
./demo
|
+--- CMakeLists.txt
|
+--- main.cc
|
+--- math/
|
+--- CMakeLists.txt
|
+--- MathFunctions.cc
|
+--- MathFunctions.h
demo下的CMakeLists.txt文件如下:
cmake_minimum_required (VERSION 2.8)
project(demo)
aux_source_directory(. DIR_SRCS)
# 添加math子目录
add_subdirectory(math)
# 指定生成目标
add_executable(demo ${DIR_SRCS})
# 添加链接库
target_link_libraries(demo MathFunctions)
math目录中的CMakeLists.txt:
aux_source_directory(. DIR_LIB_SRCS)
# 生成链接库
add_library(MathFunctions ${DIR_LIB_SRCS})
五、常用变量
构建类型
cmake默认支持多种构建类型(build type),每种构建类型都有专门的编译参数变量,详情见下表
CMAKE_BUILD_TYPE | 对应的c编译选项变量 | 对应的c++编译选项变量 |
---|---|---|
None | CMAKE_C_FLAGS | CMAKE_CXX_FLAGS |
Debug | CMAKE_C_FLAGS_DEBUG | CMAKE_CXX_FLAGS_DEBUG |
Release | CMAKE_C_FLAGS_RELEASE | CMAKE_CXX_FLAGS_RELEASE |
RelWithDebInfo | CMAKE_C_FLAGS_RELWITHDEBINFO | CMAKE_CXX_FLAGS_RELWITHDEBINFO |
MinSizeRel | CMAKE_C_FLAGS_MINSIZEREL | CMAKE_CXX_FLAGS_MINSIZEREL |
指定构建类型
- Windows的VS项目属于多配置型,可以在VS中选择生成的配置
- 生成后的项目默认包含四种配置
- 改变默认的配置
set(CMAKE_CONFIGURATION_TYPES "Debug;RelWithDebInfo")
- 默认生成的平台类型为Win32,如果需要x64类型,则需要按如下命令执行
cmake -G "Visual Studio 14 2015 Win64" ..
- Linux下的Makefile属于单配置型,需要指定生成配置
- 默认执行
cmake ..
,会生成None配置 - 可以通过命令行指定配置
cmake -DCMAKE_BUILD_TYPE=Debug ..
- 可以在CMake文件中指定配置
set(CMAKE_BUILD_TYPE DEBUG)
变量
- 变量的引用方式是使用“${}”,在if命令中,不需要使用这种方式,直接使用变量名即可
- 自定义变量使用SET(OBJ_NAME xxxx),使用时${OBJ_NAME}
常用变量
CMAKE_BINARY_DIR,PROJECT_BINARY_DIR,_BINARY_DIR:
这三个变量内容一致,如果是内部编译,就指的是工程的顶级目录,如果是外部编译,指的就是工程编译发生的目录。CMAKE_SOURCE_DIR,PROJECT_SOURCE_DIR,_SOURCE_DIR:
这三个变量内容一致,都指的是工程的顶级目录。CMAKE_CURRENT_BINARY_DIR:外部编译时,指的是target目录,内部编译时,指的是顶级目录
CMAKE_CURRENT_SOURCE_DIR:CMakeList.txt所在的目录
CMAKE_CURRENT_LIST_DIR:CMakeList.txt的完整路径
CMAKE_CURRENT_LIST_LINE:当前所在的行
CMAKE_MODULE_PATH:如果工程复杂,可能需要编写一些cmake模块-,这里通过SET指定这个变量
LIBRARY_OUTPUT_DIR,BINARY_OUTPUT_DIR:库和可执行的最终存放目录
环境变量
- 使用环境变量:$ENV{Name}
- 写入环境变量:set(ENV{Name} value) #这里没有“$”符号
系统信息
- CMAKE_MAJOR_VERSION,CMAKE 主版本号,比如2.4.6 中的2
- CMAKE_MINOR_VERSION,CMAKE 次版本号,比如2.4.6 中的4
- CMAKE_PATCH_VERSION,CMAKE 补丁等级,比如2.4.6 中的6
- CMAKE_SYSTEM ,系统名称,比如Linux-2.6.22
- CMAKE_SYSTEM_NAME ,不包含版本的系统名,比如Linux
- CMAKE_SYSTEM_VERSION ,系统版本,比如2.6.22
- CMAKE_SYSTEM_PROCESSOR,处理器名称,比如i686
- UNIX ,在所有的类UNIX平台为TRUE,包括OS X 和cygwin
- WIN32 ,在所有的win32 平台为TRUE,包括cygwin
主要开关选项
- BUILD_SHARED_LIBS, 这个开关用来控制默认的库编译方式,如果不进行设置,使用add_library 并没有指定库类型的情况下,默认编译生成的库都是静态库。如果set(BUILD_SHARED_LIBS ON) 后,默认生成的为动态库
- CMAKE_C_FLAGS 设置C编译选项,也可以通过指令add_definitions() 添加
- CMAKE_CXX_FLAGS 设置C++ 编译选项,也可以通过指令add_definitions() 添加
六、参考资料
CMake简介的更多相关文章
- 【转载】CMake 简介和 CMake 模板
转载自我的博客: CMake 简介和 CMake 模板 . 如果你用 Linux 操作系统,使用 cmake 会简单很多,可以参考一个很好的教程: CMake 入门实战 | HaHack .如果你用 ...
- CMake 简介与使用
cross platform make的缩写. 是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目文件.通过编写CMakeLists ...
- cmake 简介
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的 ...
- 非常陌生的cmake
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的 ...
- cmake,gtest单元测试程序
参考:http://blog.csdn.net/stdcoutzyx/article/details/8284183 PROJECT (HELLO) SET(SRC_LIST main.c) MESS ...
- CMake基本语法
CMake简介 CMake 是做什么的? CMake是一套类似于automake的跨平台辅助项目编译的工具. 我觉得语法更加简单易用. CMake的工作流程 CMake处理顶级目录的CMakeList ...
- CMake 条件判断
CMake简介 CMake 是做什么的? CMake是一套类似于automake的跨平台辅助项目编译的工具. 我觉得语法更加简单易用. CMake的工作流程 CMake处理顶级目录的CMakeList ...
- 基于Cmake+QT+VS的C++项目构建开发编译简明教程
目录 一.工具下载与安装 1. Qt 2. Visual Studio 2015 3. Cmake 二.C++及Qt项目构建 1. 基于VS构建Qt项目 2. ...
- [转] CMake
转载地址:https://www.cnblogs.com/lidabo/p/7359422.html cmake 简介 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装( ...
随机推荐
- ARM-Linux中断系统
1.前言 了解Linux中断子系统,同时也需要了解ARM体系结构中断处理流程:在熟悉整个软硬件架构和流程基础上,才能对流程进行细化,然后找出问题的瓶颈.<2. 梳理中断处理子系统> 但是所 ...
- 关于Linux虚拟化技术KVM的科普 科普三(From OenHan)
http://oenhan.com/archives,包括<KVM源代码分析1:基本工作原理>.<KVM源代码分析2:虚拟机的创建与运行>.<KVM源代码分析3:CPU虚 ...
- sql server 高可用故障转移(上)
群集准备工作 个人电脑 内存12G,处理器 AMD A6-3650CPU主频2.6GHz 虚拟机 VMware Workstation 12 数据库 sql server 2008 r2 三台虚拟服 ...
- springMVC简单的一些操作
SpringMVC的模型-视图-控制器(MVC)框架是围绕一个DispatcherServlet来设计的,这个Servlet会把请求分发给各个处理器进行处理,由DispatcherServlet来统一 ...
- Python 可视化工具 Matplotlib
英文出处:Chris Moffitt. Matplotlib是Python中最常用的可视化工具之一,可以非常方便地创建海量类型的2D图表和一些基本的3D图表.本文主要介绍了在学习Matplotlib时 ...
- bzoj4067 [Ctsc2015]gender
好神的一道题啊! 我们发现题目中的ln的贡献非常傻逼,但是我们可以发现这个东西的取值只有40个左右,于是我们可以枚举他! 枚举完了对于题里的贡献就是一个普通的最小割,采用的是文理分科的思想,与S连代表 ...
- BZOJ_2038_[2009国家集训队]小Z的袜子(hose)_莫队
BZOJ_2038_[2009国家集训队]小Z的袜子(hose)_莫队 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无 ...
- Bot Framework 搭建聊天机器人
这周我来跟大家分享的是在Microsoft Build 2016上发布的微软聊天机器人的框架. 现如今,各种人工智能充斥在我们的生活里.最典型的人工智能产品就是聊天机器人,它既可以陪我们聊天,也可以替 ...
- MediatR 知多少
引言 首先不用查字典了,词典查无此词.猜测是作者笔误将Mediator写成MediatR了.废话少说,转入正题. 先来简单了解下这个开源项目MediatR(作者Jimmy Bogard,也是开源项目A ...
- 分布式日志框架Exceptionless之生产环境部署步骤
Exceptionless 是一个开源的实时的日志收集框架,它将日志收集变得简单易用并且不需要了解太多的相关技术细节及配置.本篇基于我的上一篇<基于Exceptionless实现分布式日志> ...