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. vue单页应用中 返回列表记住上次滚动位置、keep-alive缓存之后更新列表数据 那点事

    实践场景需求 产品列表中,滚动到一定位置的时候,点击查看产品信息,后退之后,需要回到原先的滚动位置,这是常见的需求 所有页面均在router-view中,暂时使用了keep-alive来缓存所有页面, ...

  2. 实例详析ImageView的adjustViewBonds和scaleType

    android:adjustViewBounds是否保持宽高比.需要与maxWidth.MaxHeight一起使用,否则单独使用没有效果. 设置View的最大高度,单独使用无效,需要与setAdjus ...

  3. Java 线性表、栈、队列和优先队列

    1.集合 2.迭代器 例子: 3.线性表 List接口继承自Collection接口,有两个具体的类ArrayList或者LinkedList来创建一个线性表 数组线性表ArrayList Linke ...

  4. sql 查询名字中有_的员工

    select * from emp where ename like '%\_%' escape '\' ;\可以换作任意的字符 select * from emp where ename like ...

  5. Ajax文件上传并添加Bootstrap进度条

    1.项目中需要用到文件上传和显示进度,网上各种插件搞得头晕,决定自己实现一个 三个步骤:Ajax上传文件,获取上传进度,显示进度 html: <!DOCTYPE HTML> <htm ...

  6. python 历险记(四)— python 中常用的 json 操作

    目录 引言 基础知识 什么是 JSON? JSON 的语法 JSON 对象有哪些特点? JSON 数组有哪些特点? 什么是编码和解码? 常用的 json 操作有哪些? json 操作需要什么库? 如何 ...

  7. mysql binglog server的设置方法【原创】

    MySQL备份数据都是MySQL备份+binlog,这样才能保证数据的完整性.下面就是利用mysqlbinlog搭建mysql binlog server,可以把binlog传到远程存储上. 试验环境 ...

  8. python中对列表和循环使用的小练习

    #author devilf product_list = [ (), (), (), (), () ] shop_list = [] salary = input('pls enter your s ...

  9. 转载:2.2.5 在配置中使用变量《深入理解Nginx》(陶辉)

    原文:https://book.2cto.com/201304/19630.html 有些模块允许在配置项中使用变量,如在日志记录部分,具体示例如下.log_format  main  '$remot ...

  10. expdp和impdp 使用注意事项

    使用EXPDP和IMPDP时应该注意的事项: EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. EXPDP和IMPDP是服务端的工具程序,他们只能在ORACLE服务端使用, ...