文章目录
- Cmake简单介绍
-
- Cmake与Makefile
- Cmake配置
- [CmakeLists.txt 编写](#CmakeLists.txt 编写)
- 完整cmake例子
- 文件夹杂乱问题
- 多级目录Cmake
- [vscode 极其推荐 的 cmake方式](#vscode 极其推荐 的 cmake方式)
- Mysql环境与编程
- 集群聊天项目工程目录创建
- 网络模块代码Chatserver
Cmake简单介绍
Cmake与Makefile
Makefile 在大项目里, 很难写 出来, 推荐Cmake
- Makefile
- 直接构建工具 :定义编译规则(如
gcc -o main main.c
),由make
直接执行。 - 手动编写:需指定每个文件的依赖和命令,适合小型项目。
- 平台差异 :不同系统的
make
可能有兼容性问题。
- 直接构建工具 :定义编译规则(如
- CMake
- 构建系统生成器 :通过
CMakeLists.txt
描述项目结构,自动生成平台相关的构建文件(如 Makefile 或 IDE 工程)。 - 跨平台:一套配置适配多平台(Linux/Mac/Windows)。
- 高级功能:自动处理依赖、安装规则等,适合中大型项目。
- 构建系统生成器 :通过
Cmake配置
直接手写 cmake配置文件CMakeLists.txt
, 命令行执行, 是可行的
vscode的cmake插件 , 再写 cmake 时 会有代码提示 ----------> cmake 与 cmake tools
-
cmake tools 设置里, 在对应的 本机或者 远程 设置一下 cmake 的 build enviroment: 添加一下 cmake的 路径(需要安装 cmake)
CmakeLists.txt 编写
-
CMAKE_CXX_FLAGS 是 CMake 中用于设置 全局 C++ 编译器选项 的变量,影响项目中所有 C++ 目标的编译行为。
-
在 CMake 中,
set()
命令用于 定义或修改变量,是 CMake 脚本中最基础且重要的命令之一cmakeset(变量名 值) # 定义普通变量
-
在 CMake 中,
add_executable
是一个核心命令,用于定义可执行文件目标。cmakeadd_executable(<目标名称> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] <源文件列表>)
最主要的是 目标名称 和 源文件列表
例子:
cmake#单文件 add_executable(hello_world main.cpp) #多文件 add_executable(my_app main.cpp utils.cpp include/utils.h ) #条件编译--不同平台 if(WIN32) add_executable(my_win_app WIN32 win_main.cpp) else() add_executable(my_win_app main_unix.cpp) endif() #使用变量组织源文件 set(APP_SOURCES src/main.cpp src/core.cpp ) add_executable(my_app ${APP_SOURCES})
-
在 CMake 中,
target_link_libraries
是一个关键命令,用于为指定的目标(可执行文件或库)链接依赖库。它管理目标的所有链接依赖关系,是现代 CMake 推荐的做法。 --- 更多使用, 多见多总结 --- 老师pdf也有很多, 多看c++target_link_libraries(<目标名称> <PRIVATE|PUBLIC|INTERFACE> <库1> [<库2>...] [<PRIVATE|PUBLIC|INTERFACE> <库3>...] )
-
aux_source_directory
是 CMake 中一个 用于自动收集源文件 的命令,但现代 CMake 已不再推荐使用它。c++aux_source_directory(<目录路径> <变量名>)
为什么不推荐使用?
- 不会自动检测新增文件
需要手动重新运行 CMake 才能识别新添加的源文件。 - 包含无关文件风险
可能意外包含测试文件、备份文件(如main.cpp.bak
)。 - 破坏构建系统的确定性
隐式文件收集会导致构建行为不可预测。 - 与现代 CMake 理念冲突
现代 CMake 强调显式声明源文件(target_sources()
)。
推荐使用 set 手动, 很麻烦
- 不会自动检测新增文件
完整cmake例子
cmake
cmake_minimum_required(VERSION 3.0)
project(main) #工程名
# 配置编译选项
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)
# 配置头文件搜索路径
include_directories()
# 配置库文件搜索路径
link_directories()
#设置需要编译的 源文件列表
set(SRC_LIST ./nuduo_server.cpp)
#把 . 指定路径下的 所有源文件名字 放入变量名--不用手动一个个输入
# aux_source_directory(. SRC_LIST) #暂时不用
#生成可执行文件
add_executable(server ${SRC_LIST})
# 表示server 这个目标程序 需要链接的 库
target_link_libraries(server muduo_net muduo_base pthread)
然后 先执行 cmake .
----> 得到 makefile文件 ---> 再make
即可
文件夹杂乱问题
直接 使用上面的 构建, 生成许多杂乱的 文件夹
一般 开源性代码 会有以下结构:
目录/文件 | 用途描述 | 文件类型示例 |
---|---|---|
bin/ |
存放生成的可执行文件(二进制文件) | myapp , myapp.exe |
lib/ |
存放编译生成的库文件 | libmylib.a , mylib.so |
include/ |
存放项目的公共头文件 | utils.h , config.hpp |
src/ |
存放项目的主要源代码文件 | main.cpp , module.c |
build/ |
存放CMake生成的构建文件 | Makefile , build.ninja |
example/ |
存放示例代码或测试用例 | demo.cpp , test_case.py |
thirdparty/ |
存放第三方依赖库或源码 | googletest/ , boost/ |
CMakeLists.txt |
CMake的主配置文件 | - |
autobuild.sh |
自动化构建脚本 | - |
-
在 CMake 中,
EXECUTABLE_OUTPUT_PATH
是一个用于设置可执行文件输出路径 的全局变量。它控制通过add_executable()
生成的可执行文件的存放位置。在 CMake 中,
PROJECT_SOURCE_DIR
是一个预定义变量 ,表示当前项目的根目录路径 (即包含顶层CMakeLists.txt
的目录)。cmakeset(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
-
建立 build 文件, 进入build 进行
cmake ..
, 之前的 杂乱的文件夹就在这个目录里了, 并且 可执行文件 在bin目录里 -
完整如下:
cmakecmake_minimum_required(VERSION 3.0) project(main) #工程名 # 配置编译选项 set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g) # 配置头文件搜索路径 include_directories() # 配置库文件搜索路径 link_directories() #设置需要编译的 源文件列表 set(SRC_LIST ./nuduo_server.cpp) # 设置可执行文件最终目录 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) # 设置库文件最终目录 set(LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) #把 . 指定路径下的 所有源文件名字 放入变量名--不用手动一个个输入 # aux_source_directory(. SRC_LIST) #暂时不用 #生成可执行文件 add_executable(server ${SRC_LIST}) # 表示server 这个目标程序 需要链接的 库 target_link_libraries(server muduo_net muduo_base pthread)
多级目录Cmake
内部的CMakeLists.txt
不需要 前5行, 这是 cmake的 入口
把这5行 放入 最外部的 CMakeLists.txt
, 并且 加入 指定搜索的 子目录 即可
cmake
cmake_minimum_required(VERSION 3.0)
project(main) #工程名
# 配置编译选项
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)
# 指定搜索的 子目录
add_subdirectory(testmuduo)
vscode 极其推荐 的 cmake方式
vscode 插件 会有图标, 使用这个 进行 编译------> 即完成, 并会 外部 自动构建 build 文件

注意: 仅会自动构建 build 文件, bin 文件 还需要手动指定, 在 内部CMakeLists.txt 里 进行
VS Code CMake 插件的自动化机制
(1) 自动行为说明
-
自动生成
build/
目录插件默认会在项目根目录下创建
build/
(或用户配置的路径),自动处理以下内容:mkdir -p build && cd build cmake .. -DCMAKE_BUILD_TYPE=Debug # 自动选择编译器工具链
-
实时更新
插件会监控
CMakeLists.txt
和源码文件的修改,但不会实时构建,仅在以下情况触发:- 手动点击编译按钮
- 保存文件时(若开启
"cmake.configureOnEdit": true
) - 执行调试/运行任务时
(2) 优势
- 无需手动输入 CMake 命令
- 自动匹配编译器工具链(通过
CMake: Scan for Kits
) - 与 VS Code 调试功能深度集成
Cmake 到此为止-----> 更多内容 见 pdf
Mysql环境与编程
登录 之前写过, 略
mysql 有课程, 建议看一下 --- > 必须要了解 数据库 mysql !!!
mysql简单使用
-
创建数据库:
c++CREATE DATABASE database_name; // 大小写都行
-
选择要操作的 数据库:
c++use database_name;
-
查看默认的字符编码:
c++show variables like "char%";
修改表的字符编码:
alter table user default character set utf8;
修改属性的字符编码:
alter table user modify column name varchar(50) character set utf8;
-
从已有的 sql文件读取, 需要先创建 一个数据库, 并且选中它进行操作, 再
source ./<..>.sql
-
根据表, 在mysql里 进行创建. --- 具体表
User表
字段名称 字段类型 字段说明 约束 id INT 用户id PRIMARY KEY, AUTO_INCREMENT name VARCHAR(50) 用户名 NOT NULL, UNIQUE password VARCHAR(50) 用户密码 NOT NULL state ENUM('online','offline') 当前登录状态 DEFAULT 'offline' Friend表
字段名称 字段类型 字段说明 约束 userid INT 用户id NOT NULL, 联合主键 friendid INT 好友id NOT NULL, 联合主键 AllGroup表
字段名称 字段类型 字段说明 约束 id INT 组id PRIMARY KEY, AUTO_INCREMENT groupname VARCHAR(50) 组名称 NOT NULL, UNIQUE groupdesc VARCHAR(200) 组功能描述 DEFAULT '' GroupUser表
字段名称 字段类型 字段说明 约束 groupid INT 组id NOT NULL, 联合主键 userid INT 组员id NOT NULL, 联合主键 grouprole ENUM('creator','normal') 组内角色 DEFAULT 'normal' OfflineMessage表
字段名称 字段类型 字段说明 约束 userid INT 用户id NOT NULL message VARCHAR(500) 离线消息(存储Json字符串) NOT NULL
集群聊天项目工程目录创建
略---> bin build include src thirdparty 文件夹
外层 CMakeLists.txt 和 src 的两层 CMakeLists.txt
cmake
cmake_minimum_required(VERSION 3.0)
project(main) #工程名
# 配置编译选项
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)
# 配置最终的可执行文件输出的路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# 配置 头文件 搜索路径
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/include/server)
# 加载子目录 src 既然进去, 就有 CMakeLists.txt
add_subdirectory(src)
cmake
# 加载子目录 src 既然进去, 就有 CMakeLists.txt
add_subdirectory(server)
cmake
# 所有源文件
aux_source_directory(. SRC_LIST)
# 生成可执行
add_executable(Chatserver ${SRC_LIST})
# 链接库
target_link_libraries(Chatserver muduo_net muduo_base pthread)
网络模块代码Chatserver
hpp文件 写声明
源文件 进行定义使用
头文件
include/chatserver.hpp
c++
#ifndef CHATSERVER_H
#define CHATSERVER_H
#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
using namespace muduo;
using namespace muduo::net;
// 聊天服务器主类
class ChatServer
{
public:
// 初始化聊天服务器对象
ChatServer(EventLoop *loop,
const InetAddress &listenAddr,
const string &nameArg);
// 启动服务
void start();
private:
// 上报连接 相关信息的回调
void onConnect();
// 上报读写事件相关信息的 回调
void onMessage();
TcpServer _server; // 组合的muduo库, 实现服务器功能的 类对象
EventLoop *_loop; // 指向事件循环对象的 指针
};
#endif
类函数定义文件
src/server/chatserver.cpp
不完整, 回调内部 还没写
c++
#include "chatserver.hpp"
#include <functional>
using namespace std;
using namespace placeholders;
// 类外 定义成员函数
ChatServer::ChatServer(EventLoop *loop,
const InetAddress &listenAddr,
const string &nameArg)
: _server(loop, listenAddr, nameArg), _loop(loop)
{
// 注册连接回调函数
_server.setConnectionCallback(std::bind(&ChatServer::onConnect, this, _1));
// 注册消息回调
_server.setMessageCallback(std::bind(&ChatServer::onMessage, this, _1, _2, _3));
// 设置线程数
_server.setThreadNum(4);
}
void ChatServer::start()
{
_server.start();
}
void ChatServer::onConnect(const TcpConnectionPtr& conn)
{
}
void ChatServer::onMessage(const TcpConnectionPtr& conn,
Buffer* buf,
Timestamp time)
{
}
主函数文件
src/server/main.cpp
c++
#include "chatserver.hpp"
#include <iostream>
using namespace std;
int main()
{
EventLoop loop;
InetAddress addr("127.0.0.1", 6000);
ChatServer server(&loop, addr, "ChatServer");
server.start();
loop.loop();
return 0;
}