- 项目依赖的cmkae最低版本,注意括号中的 VERSION 要带上。
- 指定项目名称为 websockets,语言框架为C++
- 指定C++标准版本为17
- 指定项目编译时需要依赖 zlib 库
- 设置 third_party 作为子模块,在编译项目时,会先编译子模块
- add_subdirectory指定的目录下需要包括 CMakeLists.txt
- 指定源码目录
- 指定项目需要引入的第三方头文件,注意中间分隔符是 空格,不是逗号
- 设置项目可执行文件,即将 SRC_DIR 指定的源码编译为以 项目名 命名的二进制文件
- 添加第三方依赖编译输出的静态链接库,uwebsockets为库名称
- 设置uWebSockets编译输出的静态链接库路径,注意,uWebSockets本身没有静态链接库,只有头文件,只有其依赖的uSockets才有静态链接库输出
- 注意:CMAKE_CURRENT_SOURCE_DIR指的是 当前 CMakeLists.txt文件所在的目录,并不是项目工程的跟目录。
- 设置编译输出的头文件所在目录,需要提前在 third_party 目录下创建 include,否则编译会失败
- 设置构建uWebSockets的构建命令
- OUTPUT指定输出的静态链接库的路径
- COMMAND指定了构建命令,后面可以跟多个命令,LIBUS_NO_SSL=1为构建参数
- WORKING_DIRECTORY指定命令执行的目录,即源码中Makefile目录所在
- add_custom_target通过用户指定的指令来增加一个新的编译目标
- 创建静态链接库,依赖上述自定义编译输出
- 注意: 在测试中发现,GLOBAL一定要设置,否则,在项目中找不到该静态库
- 指定该静态库的路径信息以及头文件信息
以 uWebSockets 的使用为例。
参考:
https://www.hahack.com/codes/cmake/
https://chenxiaowei.gitbook.io/cmake-cookbook/
- 新建工程,结构如下:
.
├── CMakeLists.txt
├── build
├── src
│ └── main.cc
└── third_party
├── CMakeLists.txt
├── include
└── uWebSockets
目录结构说明:
CMakeLists.txt
为项目工程的cmake
描述文件。build
为构建输出目录。cmake
没有清理命令,所以,一般将输出放到独立的目录下,方便区分。src
为源码跟目录。third_party
为第三方依赖。在third_party
目录下也创建CMakeLists.txt
,管理所有的第三方依赖。- 增加依赖
uWebSockets
:第三方依赖是通过
git submodule
和cmake
结合的方式。
- 增加依赖
在项目跟目录下执行
git init
初始化。增加
submodule
:git submodule add https://github.com/uNetworking/uWebSockets.git third_party/uWebSockets
- 由于
uWebSockets
本身也包含了submodule
,需在工程目录下执行git submodule update —init —recursive
。
- 创建项目的
CMakeLists.txt
: ```cmake项目依赖的cmkae最低版本,注意括号中的 VERSION 要带上。
cmake_minimum_required(VERSION 3.16.2)
指定项目名称为 websockets,语言框架为C++
project(websockets CXX)
指定C++标准版本为17
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_REQUIRED ON)
指定项目编译时需要依赖 zlib 库
link_libraries(z)
设置 third_party 作为子模块,在编译项目时,会先编译子模块
add_subdirectory指定的目录下需要包括 CMakeLists.txt
add_subdirectory(third_party)
指定源码目录
aux_source_directory(src SRC_DIR)
指定项目需要引入的第三方头文件,注意中间分隔符是 空格,不是逗号
include_directories(“third_party/uWebSockets/src” “third_party/uWebSockets/uSockets/src”)
设置项目可执行文件,即将 SRC_DIR 指定的源码编译为以 项目名 命名的二进制文件
add_executable(${PROJECT_NAME} ${SRC_DIR})
添加第三方依赖编译输出的静态链接库,uwebsockets为库名称
target_link_libraries(${PROJECT_NAME} uwebsockets)
<br />`link_libraries(z)`是为了引入`zlib`包,否则在执行`make`时报错:
```bash
[100%] Linking CXX executable websockets
undef: _deflateEnd
undef: _inflateEnd
Undefined symbols for architecture x86_64:
"_deflateEnd", referenced from:
uWS::DeflationStream::~DeflationStream() in main.cc.o
"_inflateEnd", referenced from:
uWS::InflationStream::~InflationStream() in main.cc.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
- 创建管理依赖的
third_party/CMakeLists.txt
: ```cmake cmake_minimum_required(VERSION 3.16.2)
设置uWebSockets编译输出的静态链接库路径,注意,uWebSockets本身没有静态链接库,只有头文件,只有其依赖的uSockets才有静态链接库输出
注意:CMAKE_CURRENT_SOURCE_DIR指的是 当前 CMakeLists.txt文件所在的目录,并不是项目工程的跟目录。
set(UWEBSOCKETS_LIB ${CMAKE_CURRENT_SOURCE_DIR}/uWebSockets/uSockets/uSockets.a)
设置编译输出的头文件所在目录,需要提前在 third_party 目录下创建 include,否则编译会失败
set(LIB_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/include)
设置构建uWebSockets的构建命令
OUTPUT指定输出的静态链接库的路径
COMMAND指定了构建命令,后面可以跟多个命令,LIBUS_NO_SSL=1为构建参数
WORKING_DIRECTORY指定命令执行的目录,即源码中Makefile目录所在
add_custom_command(OUTPUT ${UWEBSOCKETS_LIB} COMMAND LIBUS_NO_SSL=1 make WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/uWebSockets)
add_custom_target通过用户指定的指令来增加一个新的编译目标
add_custom_target(build_uwebsockets DEPENDS ${UWEBSOCKETS_LIB})
创建静态链接库,依赖上述自定义编译输出
注意: 在测试中发现,GLOBAL一定要设置,否则,在项目中找不到该静态库
add_library(uwebsockets STATIC IMPORTED GLOBAL) add_dependencies(uwebsockets build_uwebsockets)
指定该静态库的路径信息以及头文件信息
set_target_properties(uwebsockets PROPERTIES IMPORTED_LOCATION ${UWEBSOCKETS_LIB} INTERFACE_INCLUDE_DIRECTORIES ${LIB_HEADER})
> 其中 `add_custom_command` 和 `add_custom_target`可以合并为一条:
> ```cmake
add_custom_target(build_uwebsockets COMMAND ${CMAKE_MAKE_PROGRAM}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/uWebSockets)
third_party
目录结构:
.
├── CMakeLists.txt
├── include
└── uWebSockets
├── BroadcastingEchoServer
├── EchoServer
├── EchoServerThreaded
├── HelloWorld
├── HelloWorldThreaded
├── LICENSE
├── Makefile
├── README.md
├── benchmarks
├── examples
├── fuzzing
├── misc
├── src
├── tests
└── uSockets
注意:由于
uWebSockets
不是cmake项目,只有Makefile
文件,所以上述示例中介绍的是在cmake中直接引用Makefile项目。对于引用cmake项目,通过add_subdirectory
指令。
- 构建
# 在build目录下执行 cmake .. make