如何学习 CMake
一、如何学习 cmake
cmake 是目前管理 C++ 工程,尤其是一个大型 C++ 项目常用的一个工具,尤其是 Linux C/C++ 项目,主流的网络库,例如 libevent、libuv 基本上都使用 cmake 管理项目。
那么是不是意味着你必须学习 CMake 的方方面面,不是的,你只要掌握 CMake 常用语法和命令即可。
常用的命令有:
-
如何设置项目源码目录
-
如何设置项目 include 目录
-
如何设置依赖的库目录
-
如何指定可执行程序的生成方式(包括可直接运行的和依赖库(.so 和 .a 文件))
-
指定查找依赖的方式
-
条件编译
-
自定义变量以及如何执行 cmake 命令时给这些变量传递值。
常用的功能基本上就这么多,其他的命令可以在用到的时候去查一下即可。
甚至你也不用记住这些常用命令怎么写,你可以自己准备一份 CMakeLists.txt 模版,用的时候基于模板改一改就可以了。
下面是我的两个 CMakeLists.txt 模板,分享给大家,平常我开发新的项目时拿这两个模板改一改即可,很方便。
模板一
# 来自开源项目Flamingo:
# https://github.com/balloonwj/flamingo/blob/master/flamingoserver/CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project (FLAMGINGO_SERVER)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -g -Wall -O0 -Wno-unused-variable -pthread")
link_directories(
${PROJECT_SOURCE_DIR}/lib
/usr/lib64/mysql/
)
set(net_srcs
base/AsyncLog.cpp
base/ConfigFileReader.cpp
base/Platform.cpp
base/Timestamp.cpp
net/Acceptor.cpp
net/ByteBuffer.cpp
net/Channel.cpp
net/Connector.cpp
net/EpollPoller.cpp
net/EventLoop.cpp
net/EventLoopThread.cpp
net/EventLoopThreadPool.cpp
net/InetAddress.cpp
net/Poller.cpp
net/PollPoller.cpp
net/ProtocolStream.cpp
net/SelectPoller.cpp
net/Sockets.cpp
net/TcpClient.cpp
net/TcpConnection.cpp
net/TcpServer.cpp
net/Timer.cpp
net/TimerQueue.cpp
)
set(mysqlapi_srcs
mysqlapi/DatabaseMysql.cpp
mysqlapi/Field.cpp
mysqlapi/QueryResult.cpp
)
set(mysqlmgr_srcs
mysqlmgr/MysqlManager.cpp
mysqlmgr/MysqlThrd.cpp
mysqlmgr/MysqlThrdMgr.cpp
mysqlmgr/TaskList.cpp
)
set(json_srcs
jsoncpp1.9.0/json_reader.cpp
jsoncpp1.9.0/json_value.cpp
jsoncpp1.9.0/json_writer.cpp
)
set(zlib_srcs
zlib1.2.11/zutil.c
zlib1.2.11/uncompr.c
zlib1.2.11/trees.c
zlib1.2.11/inftrees.c
zlib1.2.11/inflate.c
zlib1.2.11/inffast.c
zlib1.2.11/infback.c
zlib1.2.11/gzwrite.c
zlib1.2.11/gzread.c
zlib1.2.11/gzlib.c
zlib1.2.11/gzclose.c
zlib1.2.11/deflate.c
zlib1.2.11/crc32.c
zlib1.2.11/compress.c
zlib1.2.11/adler32.c
zlib1.2.11/ZlibUtil.cpp
)
set(utils_srcs
utils/StringUtil.cpp
utils/URLEncodeUtil.cpp
utils/MD5.cpp
utils/DaemonRun.cpp
)
set(chatserver_srcs
chatserversrc/main.cpp
chatserversrc/ChatServer.cpp
chatserversrc/ChatSession.cpp
chatserversrc/UserManager.cpp
chatserversrc/MsgCacheManager.cpp
chatserversrc/TcpSession.cpp
chatserversrc/MonitorSession.cpp
chatserversrc/MonitorServer.cpp
chatserversrc/HttpSession.cpp
chatserversrc/HttpServer.cpp
chatserversrc/BussinessLogic.cpp)
set(fileserver_srcs
fileserversrc/main.cpp
fileserversrc/FileServer.cpp
fileserversrc/FileSession.cpp
fileserversrc/FileManager.cpp
fileserversrc/TcpSession.cpp)
set(imgserver_srcs
imgserversrc/main.cpp
fileserversrc/FileServer.cpp
fileserversrc/FileSession.cpp
fileserversrc/FileManager.cpp
fileserversrc/TcpSession.cpp)
add_executable(chatserver ${net_srcs} ${json_srcs} ${chatserver_srcs} ${mysqlapi_srcs} ${mysqlmgr_srcs} ${zlib_srcs} ${utils_srcs})
#光包含库目录是没用的,还必须使用TARGET_LINK_LIBRARIES链接该库
TARGET_LINK_LIBRARIES(chatserver mysqlclient)
add_executable(fileserver ${net_srcs} ${fileserver_srcs} ${utils_srcs})
TARGET_LINK_LIBRARIES(fileserver)
add_executable(imgserver ${net_srcs} ${imgserver_srcs} ${utils_srcs})
TARGET_LINK_LIBRARIES(imgserver)
模板二
PROJECT(TRADESYSTEM)
AUX_SOURCE_DIRECTORY(./ SRC_LIST)
SET(EXECUTABLE_OUTPUT_PATH ../bin)
ADD_DEFINITIONS(-g -O0 -W -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO -DAC_HAS_WARNING -DAC_HAS_ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL -DHAVE_CXX_STDHEADERS -Wno-deprecated ${CMAKE_CXX_FLAGS})
INCLUDE_DIRECTORIES(
./
/usr/local/include/commonlib/dbapi
/usr/local/include/commonlib/json2
/usr/local/include/commonlib/mysql
)
LINK_DIRECTORIES(
./
/usr/local/lib/commonlib
)
ADD_EXECUTABLE(trade ${SRC_LIST})
TARGET_LINK_LIBRARIES(trade pthread netutil json2 mysqlclient dbapi )
编写完 CMakeLists.txt 文件后,进入 CMakeLists.txt 文件依次执行如下命令即可生成最终的二进制文件:
# 利用cmake生成Makefile
cmake .
# 执行make命令,利用gcc/g++编译生成最终的二进制文件
make
CMakeLists.txt 也支持递归编译,父目录的 CMakeLists 先执行再接着执行子目录的 CMakeLists.txt 文件。
二、cmake 学习资料
cmake 官方出了一个 cmake 教程电子书《mastering cmake》,这个点子书涉及到 cmake 的方方面面,如果你想系统地学习 cmake,可以看看这本书。
《mastering cmake》下载链接:
链接: https://pan.baidu.com/s/1hy5kcMueNHI9jpS7GuSNvA 提取码: 97tx
官方文档虽然详尽,但是内容太多了,我这里有一份 CMake 简明教程 《CMake Practice》,介绍了 CMake 的必备知识,内容也不多,看起来也比较轻松,推荐一下:
链接: https://pan.baidu.com/s/1DX6MgPJmL5LqwnyNvvaD8w 提取码: 2mke
三、利用 cmake 工具生成 Visual Studio 工程文件
对于习惯了 Visual Studio 强大的管理项目、编码和调试功能的读者来说,在 Linux 下使用 gcc/g++ 编译、使用 gdb 调试是一件何其痛苦的事情,对于大多数的开源 C/C++ 项目,如果我们不在意 Windows 和 Linux 在一些底层 API 接口上的使用差别,想熟悉该项目的执行脉络和原理,在 Windows 上使用 Visual Studio 调试该项目也未尝不可。
凡是可以使用 CMake 工具编译的 Linux 程序(即提供了 CMakeLists.txt 文件),我们同样也可以利用 CMake 工具生成 Windows 上的 Visual Studio 工程文件。前提是这个项目支持 Windows 平台,且 CMakeLists.txt 里面有支持 Windows 平台的指令。
这里我们以著名的开源网络库 libuv (node.js 背后的 WebServer 实现)为例。
从 libuv 的官方地址提供的下载链接:Index of dist 下载最新的 libuv 的源码得到文件 libuv-v1.31.0.tar.gz(笔者写作此书时,libuv 最新版本是 1.31.0),解压该文件。在我的机器上,我解压至 F:\mycode\libuv-v1.31.0\ ,解压后的目录中确实存在一个 CMakeLists.txt 文件,如下图所示:
启动 Windows 上的 CMake 图形化工具(cmake-gui),按下图进行设置:
设置完成之后,点击界面上的Configure 按钮,会提示 vsprojects 目录不存在,提示是否创建,我们点击 Yes 进行创建。
如果您的机器上安装了多个版本的Visual Studio,接下来会弹窗对话框让我们选择要生成的工程文件对应的 Visual Studio 版本号。读者可以根据自己的实际情况按需选择。我这里选择 Visual Studio 2019。
点击 Finish 按钮后开始启动 CMake 的检测和配置工作。等待一会儿,CMake 底部的输出框中提示 “Configuring Done” 表示配置工作已经完成。
接下来点击 Generate 按钮即可生成所选版本的 Visual Studio 工程文件,生成的文件位于 vsprojects 目录。
我们可以在界面上点击按钮 Open Project 按钮直接打开工程文件,也可以找到对应目录下的 libuv.sln 打开。
打开后如下图所示:
接下来,我们就可以使用 Visual Studio 愉快地进行编译和调试了。
让我们再深入聊一下上述过程:
在点击 Configure 按钮之后,和在 Linux 下执行 cmake 命令一样,CMake 工具也是在检测所在的系统环境是否匹配 CMakeLists.txt 中定义的各种环境,本质上是生成了一份可以在 Windows 上编译和运行的代码(也就是说该源码支持在 Windows 上运行) 。因此,对于很多虽然提供了 CMakeLists.txt 文件但并不支持在 Windows 上运行的的 Linux 工程,虽然利用上述方法也能最终生成 Visual Studio 工程文件,但是这些文件并不能在 Windows 上直接无错编译和调试。
由于不同的 CMake 版本支持的 CMakeLists.txt 中的语法可能略有细微差别,有些 CMakeLists.txt 文件在使用上述方法 configure 时可能会产生一些错误,需要读者做些修改才能通过。
本文转载自我的站点:2.3 使用Visual Studio管理和阅读开源项目代码
四、一些可能对你有用的 C++ 学习资源
CppGuide学习资料
我学习和使用 C/C++ 开发快 13 年了,目前在大厂做 C++ 开发,我整理了一套 C/C++ 优质学习资料————CppGuide,内容从 C/C++ 语言、网络编程、操作系统原理到完整的项目源码分析,同时这份资料也包括 C/C++ 学习方法、推荐的阅读书籍、简历指导和求职技巧等。
需要获取以下资料的同学可以点击这里:
CppGuide 学习资料https://mp.weixin.qq.com/s/Oej6y-pYcv20YGo6cCyLwg
原创不易,如果觉得有帮助,可以给 @张小方 点个赞~
更多推荐
所有评论(0)