注:个人学习记录,如误引用,万分抱歉
1 认识cmake
cmake是一款开源、跨平台的构建工具,在一个项目中,往往包含多个目录和文件(目录树),在Linux系统下,往往使用makefile文件来构建项目,但是makefile文件可移植性较差,语义也较难理解,费力又不讨好,使用cmake编写CMakeLists.txt文件,可以灵活的生成本地makefile文件,无需修改,非常方便。
2 使用cmake
在对一个包含多个目录文件的项目进行构建时,往往会用到多个CMakeLists.txt文件,编写时应从项目根目录(工作目录)的CMakeLists.txt进行编写(CMakeLists.txt位于根目录下),然后在对一级目录,二级目录…中的CMakeLists.txt进行编写,以开源项目webserver为例,项目的目录结构如下:
└── my-weberver
├── bin
├── build
├── CMakeLists.txt
├── code
├── demo
├── lib
└── resources
项目的根目录为my-webserver, 所以先编写位于其下的cmake文件,代码如下:
# 最低cmake版本
cmake_minimum_required(VERSION 2.8)
# 项目名称(项目根目录)
project(my-weberver)
# 制定构建类型,并设置相关选项
set(CMAKE_BUILD_TYPE DEBUG)
set(CMAKE_CXX_FLAGS "-std=c++14 -Wall")
set(CMAKE_CXX_FLAGS_DEBUG
"-std=c++14 -O2 -fopenmp -pthread -g -ggdb")
# 可执行文件输出路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# 库输出路径(动态库或静态库)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
# 头文件路径
include_directories(${PROJECT_SOURCE_DIR}/code/buffer)
include_directories(${PROJECT_SOURCE_DIR}/code/http)
include_directories(${PROJECT_SOURCE_DIR}/code/log)
include_directories(${PROJECT_SOURCE_DIR}/code/pool)
include_directories(${PROJECT_SOURCE_DIR}/code/server)
include_directories(${PROJECT_SOURCE_DIR}/code/timer)
# 添加子目录(如果一个子目录中包含了cmake文件,就需要添加一个子目录) ,目的是为了和项目的目录等级关系进行对应
add_subdirectory(code) # 含有一个CmakeLists.txt
add_subdirectory(demo) # 含有一个CmakeLists.txt
然后,编写位于code目录下的cmake文件,该文件的作用主要是为了生成一个动态共享库,方便主函数进行链接,代码如下:
# 添加动态库,第一个参数为库名,第二个参数制定库类型,最后是库中包含的文件列表
# PROJECT_SOURCE_DIR是根目录
add_library(my-webserver SHARED ${PROJECT_SOURCE_DIR}/code/buffer/buffer.cpp
${PROJECT_SOURCE_DIR}/code/http/httpconn.cpp ${PROJECT_SOURCE_DIR}/code/http/httprequest.cpp ${PROJECT_SOURCE_DIR}/code/http/httpresponse.cpp
${PROJECT_SOURCE_DIR}/code/log/log.cpp ${PROJECT_SOURCE_DIR}/code/pool/sqlconnpool.cpp
${PROJECT_SOURCE_DIR}/code/server/epoller.cpp ${PROJECT_SOURCE_DIR}/code/server/webserver.cpp
${PROJECT_SOURCE_DIR}/code/timer/heaptimer.cpp)
最后,编写demo目录下的cmake文件,生成可执行程序,代码如下:
# 生成可执行程序 第一个参数为可执行程序名,第二个参数为包含main的文件(可多个)
add_executable(server main.cpp)
# 链接动态库
target_link_libraries(server my-webserver)
target_link_libraries(server mysqlclient)
当然,cmake文件的目录结构并非只有上述的一种,可以根据自己设计的目录结构灵活编写cmake文件,掌握cmake语法才是最重要的。
3 注意事项
- 编译cmake文件时,一般会创建一个build文件夹,用来保存编译产生的杂项文件,防止其污染整个项目的目录结构
- 一般会将编译得到可执行程序(.o)放在bin文件夹中,但是在运行
.o
文件时,要切换到根目录下运行,防止发生路径错误的问题 - 编译cmake文件是为了得到make文件,所以在执行cmake指令后,还应该执行make指令,得到最终的可执行程序
4 总结
以上只是cmake的一些基本功能,cmake还有很多其他强大的功能,由于在做webserver项目时只需要用到cmake的一些基本功能,故本文并未对cmake深入介绍,后续若用到其他cmake的特性,再来补充。总之,cmake是一个非常好用的项目构建工具,值得一学。