cmake使用笔记

之前一直使用MakeFile,看过一些开源项目后,了解到了cmake,它是一个跨平台的编译工具,不但能生成类unix系统下的makefile还能生成windows下project文件,这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。

基本使用方法

cmake所的所有语句写在CMakeLists.txt中,

因为cmake生成makefile或project然后在编译时会生成很多中间文件,打乱项目文件结构,所以我们一般新建一个build目录,在里面编译。

基本操作只需要二步即可 :

1、cmake CMakeLists.txt文件目录

2、make

3、如果配置了安装路径,还可以进行make install 等.

相较于makefile的优点

目前个人体感上的优点。

1、跨平台。

2、语法相较于makefile简洁不少,makefile有的,cmake基本都有。

3、编译显示自带进度,颜色,看着很舒服,(当然makefile肯定也能实现,省了不少事罢了)。

下面讲讲常用语句:

常用语法

cmake_minimum_required

CMake要求的最低版本

project

项目名称

cmake_minimum_required (VERSION 2.8.7)
project (test_project)

PROJECT_SOURCE_DIR

项目根目录,也就是CmakeLists.txt目录的绝对路径。

set

设置变量

例如

###
# variables
###
set(SOURCES_DIRECTORY ${PROJECT_SOURCE_DIR}/sources)
set(OPEN_SOURCES_DIRECTORY ${PROJECT_SOURCE_DIR}/open_sources)
set(INCLUDES_DIRECTORY ${PROJECT_SOURCE_DIR}/includes) set(MUDUO_LOGGER_INCLUDES ${INCLUDES_DIRECTORY}/muduo_logger)
set(MUDUO_NETWORK_INCLUDES ${INCLUDES_DIRECTORY}/muduo_network)
set(CPP_REDIS_INCLUDES ${OPEN_SOURCES_DIRECTORY}/cpp_redis/includes)

include_directories

包含头文件路径,类似于makfilede的-I

例如

###
# includes
###
include_directories(${INCLUDES_DIRECTORY}
${MUDUO_LOGGER_INCLUDES}
${MUDUO_NETWORK_INCLUDES}
${SOURCES_DIRECTORY}/sip_server
${CPP_REDIS_INCLUDES}
${OPEN_SOURCES_DIRECTORY}/includes
${OPEN_SOURCES_DIRECTORY}/includes/mysql++)

link_directories

链接路径,类似于makfilede的-L

###
# libraries
###
link_directories("${PROJECT_SOURCE_DIR}/library")
link_directories("${OPEN_SOURCES_DIRECTORY}/library")

常用变量

CMAKE_CURRENT_LIST_DIR

表示正在处理的CMakeLists.txt 文件的所在的目录的绝对路径(2.8.3 以及以后版本才支持)

CMAKE_ARCHIVE_OUTPUT_DIRECTORY

用于设置 ARCHIVE 目标的输出路径

CMAKE_LIBRARY_OUTPUT_DIRECTORY

用于设置 LIBRARY 目标的输出路径

CMAKE_RUNTIME_OUTPUT_DIRECTORY

用于设置 RUNTIME 目标的输出路径

LIBRARY_OUTPUT_PATH

用于设置 库文件 的输出路径

EXECUTABLE_OUTPUT_PATH

用于设置 可执行文件的输出路径

例如

###
# outputs
###
#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
#set(CMAKE_PKGCONFIG_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pkgconfig)
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/library)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

编译链接标志

CMAKE_C_FLAGS

CMAKE_C_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]

C 编译标志相关变量。

CMAKE_CXX_FLAGS

CMAKE_CXX_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]

C++ 编译标志相关变量。

CMAKE_C_FLAGS 或CMAKE_CXX_FLAGS 可以指定编译标志

CMAKE_C_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]或 CMAKE_CXX_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO] 则指定特定构建类型的编译标志,这些编译标志将被加入到 CMAKE_C_FLAGS 或 CMAKE_CXX_FLAGS 中去,例如,如果构建类型为 DEBUG,那么 CMAKE_CXX_FLAGS_DEBUG 将被加入到 CMAKE_CXX_FLAGS中去

还有链接标志相关变量,作用类似

CMAKE_EXE_LINKER_FLAGS

CMAKE_EXE_LINKER_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]

CMAKE_MODULE_LINKER_FLAGS

CMAKE_MODULE_LINKER_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]

CMAKE_SHARED_LINKER_FLAGS

CMAKE_SHARED_LINKER_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]

###
# compilation options
###
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -W -Wall -Wextra -O3")

链接部分

add_library

添加要生成的库文件

语法:add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1source2 … sourceN)

用于指定从一组源文件 source1 source2 … sourceN 编译出一个库文件且命名为 name,默认是静态库.

例如

###
#library
###
add_library(async_logging ${muduo_logger_sources}) add_library(muduo_server ${muduo_network_sources})

add_executable

add_executable 命令

语法:add_executable(<name> [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL] source1 source2 … sourceN)

用于指定从一组源文件 source1 source2 … sourceN 编译出一个可执行文件且命名为 name

###
# executable
###
add_executable(sip_server ${test_excutable })
add_executable(mysql_use_test ${mysql_use_test_sources})

target_link_libraries

语法: target_link_libraries(<target> [item1 [item2 […]]][[debug|optimized|general] ] …)

用于指定 target 链接的依赖项 item1 item2 …。

例如:

###
# link librarys
###
target_link_libraries(async_logging pthread) target_link_libraries(muduo_server async_logging)
target_link_libraries(muduo_server pthread) target_link_libraries(test_excutable async_logging
muduo_server
pthread
cpp_redis
tacopie)

其他

add_subdirectory

如果想添加一个子项目或者模块,可以用它进行构建的子目录

语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

add_subdirectory(${OPEN_SOURCES_DIRECTORY}/cpp_redis)

Debug和Release版本

暂不多详述,简单介绍一下。

debug 版的项目生成的可执行文件需要有调试信息并且不需要进行优化,、

release 版的不需要调试信息但需要优化。这些特性在 gcc/g++ 中是通过编译时的参数来决定的,如果将优化程度调到最高需要设置参数-O3,最低是 -O0 即不做优化;添加调试信息的参数是 -g -ggdb ,如果不添加这个参数,调试信息就不会被包含在生成的二进制文件中。

PROJECT(main)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
SET(CMAKE_SOURCE_DIR .) SET(CMAKE_CXX_FLAGS_DEBUG"$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE"$ENV{CXXFLAGS} -O3 -Wall") AUX_SOURCE_DIRECTORY(. DIR_SRCS)
ADD_EXECUTABLE(main ${DIR_SRCS})

两个变量 CMAKE_CXX_FLAGS_DEBUG 和CMAKE_CXX_FLAGS_RELEASE, 分别用于 debug 和 release 的编译选项。编辑 CMakeList.txt 后需要执行 ccmake 命令生成 Makefile 。在进入项目的根目录,输入 "ccmake ." 进入一个图形化界面。

调试手段

message

打印信息,类似于 echo/printf ,主要用于查cmake文件的语法错误。

set(mysql_use_test_sources ${SOURCES_DIRECTORY}/test_sources/mysql_user_accounts.cpp)
message("mysql_use_test_sources : ${mysql_use_test_sources}")

CMAKE_VERBOSE_MAKEFILE

显示详细的原始编译信息,主要用于定位一些链接错误,看看库路径什么的是否配置对。

# print compile info
set(CMAKE_VERBOSE_MAKEFILE ON)

或者执行make时

$ make VERBOSE=1

或者

$ export VERBOSE=1

$ make

你讲能看到如下所示详细编译信息

cmake示例

cmake_minimum_required (VERSION 2.8.7)
project (ws_tcp_server) ###
# variables
###
set(SOURCES_DIRECTORY ${PROJECT_SOURCE_DIR}/sources)
set(OPEN_SOURCES_DIRECTORY ${PROJECT_SOURCE_DIR}/open_sources)
set(INCLUDES_DIRECTORY ${PROJECT_SOURCE_DIR}/includes) set(MUDUO_LOGGER_INCLUDES ${INCLUDES_DIRECTORY}/muduo_logger)
set(MUDUO_NETWORK_INCLUDES ${INCLUDES_DIRECTORY}/muduo_network)
set(CPP_REDIS_INCLUDES ${OPEN_SOURCES_DIRECTORY}/cpp_redis/includes) ###
# includes
###
include_directories(${INCLUDES_DIRECTORY}
${MUDUO_LOGGER_INCLUDES}
${MUDUO_NETWORK_INCLUDES}
${CPP_REDIS_INCLUDES}) ###
# libraries
###
link_directories("${PROJECT_SOURCE_DIR}/library") ###
# outputs
###
#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
#set(CMAKE_PKGCONFIG_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pkgconfig)
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/library)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) ###
# compilation options
###
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYSQLPP_MYSQL_HEADERS_BURIED -std=c++11 -g -W -Wall -Wextra -O3") # print compile info
#set(CMAKE_VERBOSE_MAKEFILE ON) ###
# sources file
###
set(MUDUO_NETWORK_SOURCES_DIRECTORY ${SOURCES_DIRECTORY}/muduo_network)
set(MUDUO_LOGGER_SOURCES_DIRECTORY ${SOURCES_DIRECTORY}/muduo_logger)
set(TEST_EXUTE_SOURCES_DIRECTORY ${SOURCES_DIRECTORY}/test_exute) foreach(dir ${MUDUO_LOGGER_SOURCES_DIRECTORY})
# get directory sources and headers
file(GLOB s_${dir} "${dir}/*.cpp")
file(GLOB h_${dir} "${dir}/*.hpp") # set async_logger sources
set(muduo_logger_sources ${s_${dir}} ${h_${dir}})
endforeach() foreach(dir ${MUDUO_NETWORK_SOURCES_DIRECTORY})
# get directory sources and headers
file(GLOB s_${dir} "${dir}/*.cpp")
file(GLOB h_${dir} "${dir}/*.hpp") # set muiduo_network sources
set(muduo_network_sources ${s_${dir}} ${h_${dir}})
endforeach() #message("muduo_network_sources: ${muduo_network_sources}") set(test_exute_sources
${WS_SERVER_SOURCES_DIRECTORY}/test_exute.cpp
${WS_SERVER_SOURCES_DIRECTORY}/main.cpp) #message("test_exute_sources : ${test_exute_sources}") ###
#library
###
add_library(async_logging ${muduo_logger_sources})
add_library(muduo_server ${muduo_network_sources}) ###
# executable
###
add_executable(test_exute ${test_exute_sources})

小结

这些是到目前对cmake使用,所用到的一些基本语法,和基本编译调试手段的一点笔记,后续如有新玩法另加。

cmake使用笔记的更多相关文章

  1. cmake学习笔记(五)

    在cmake 学习笔记(三) 中简单学习了 find_package 的 model 模式,在cmake 学习笔记(四)中了解一个CMakeCache相关的东西.但靠这些知识还是不能看懂PySide使 ...

  2. cmake 学习笔记(三)

    转自:http://blog.csdn.net/dbzhang800/article/details/6329314 接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cma ...

  3. cmake 学习笔记(二)

    在 Cmake学习笔记一 中通过一串小例子简单学习了cmake 的使用方式. 这次应该简单看看语法和常用的命令了. 简单的语法 注释 # 我是注释 命令语法 COMMAND(参数1 参数2 ...) ...

  4. cmake 学习笔记(三) (转)

    接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cmake 的使用. 学习一下cmake的 finder. finder是神马东西? 当编译一个需要使用第三方库的软件时,我 ...

  5. CMake学习笔记四:usb_cam的CMakeLists解析

    最近在学习cmake,在完整看了<cmake实践>一书后,跟着书上例程敲了跑了一遍,也写了几篇相关读书笔记,算是勉强基本入门了.所以找了usb_cam软件包的CMakeLists.txt来 ...

  6. cmake学习笔记之add_library、target_link_libraries和link_directories

    cmake是Linux(这里默认是Ubuntu系统)下常使用的编译C++的工具,而使用cmake就需要先在CmakeLists.txt文件中对编译规则进行.这里介绍常用的三种指令add_library ...

  7. CMake学习笔记

    C++开发者必备技能CMake  先简单介绍一下,CMake是一个跨平台的编译工具,它可以根据不用的平台,不同的编译环境,生成不同的MakeFile,从而控制编译的过程. 使用CMake的步骤: 1. ...

  8. cmake 学习笔记(六)

    希望这是现阶段阻碍阅读shiboken和PySide源码的涉及cmake的最后一个障碍 ^ _^ 学习 cmake 的单元测试部分 ctest. 简单使用 最简单的使用ctest的方法,就是在 CMa ...

  9. cmake 学习笔记(四)

    接前面的一二三,学习一下 CMakeCache.txt 相关的东西. CMakeCache.txt 可以将其想象成一个配置文件(在Unix环境下,我们可以认为它等价于传递给configure的参数). ...

随机推荐

  1. 超详细的Web前端开发规范文档

    规范目的为提高团队协作效率, 便于后台人员添加功能及前端后期优化维护, 输出高质量的文档, 特制订此文档. 本规范文档一经确认, 前端开发人员必须按本文档规范进行前台页面开发. 本文档如有不对或者不合 ...

  2. [USACO12DEC]逃跑的BarnRunning Away From…

    题意 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个 题解 似乎有好多种做法啊……然而蒟蒻只会打打主席树的板子…… 调了一个上午一直WA……狠下心来重打一遍居然直接一遍过 ...

  3. 修改centos和ubuntu ssh远程连接端口提升系统安全性

    #修改centos服务器ssh端口 sed -i 's/#Port 22/Port 38390/' /etc/ssh/sshd_config sed -i 's/^GSSAPIAuthenticati ...

  4. nagios系列(七)nagios通过自定义脚本的方式监控mysql主从同步

    nagios监控mysql主从同步 起因:nagios可能监控到mysql服务的运行情况,但确不能监控mysql的主从复制是否正常:有时候,同步已经停止,但管理人员却不知道. 登陆mysql从服务器, ...

  5. 03-MySql安装和基本管理

    本节掌握内容: MySQL的介绍安装.启动 windows上制作服务 MySQL破解密码 MySQL中统一字符编码 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 O ...

  6. Oracle 数据库逻辑结构

    注:本文来源于 <腾科OCP培训课堂>.非准许商业活动. Oracle 数据库逻辑结构 一.存储关系 Oracle 数据库逻辑上是由一个或多个表空间组成的,表空间物理上是由一个或多个数据 ...

  7. 用strings命令查看kafka-log内容

    kafka的log内容格式还不没怎么了解,想快速浏览消息内容的话,除了使用它自带的kafka-console-consumer.sh脚本,还可以直接去看log文件本身,不过内容里有部分二进制字符,通过 ...

  8. linux eclipse 报错过时的方法

    重新配置jre库 https://jingyan.baidu.com/article/7f766daff5b8cd4101e1d0b4.html

  9. windows service程序的Environment.CurrentDirectory路径

    当前工作目录Environment.CurrentDirectory,对于winform程序,其是在程序放置的目录里, 而windows service的Environment.CurrentDire ...

  10. 通过生成支付二维码来实现微信支付的解决方案 - EasyWechat版(转)

    上一篇我们讲了在微信浏览器内实现微信支付的功能,它特别适合于一些基于微信公众号的h5站点等,支付流程也相当流畅,但是... 还有一种情况,比如现在北哥兄弟连PC版,是生成了一个二维码,这个二维码是专属 ...