文章目录
- Cmake简单介绍
-
- Cmake与Makefile
- Cmake配置
- CmakeLists.txt 编写
- 完整cmake例子
- 文件夹杂乱问题
- 多级目录Cmake
- vscode 极其推荐 的 cmake方式
- Mysql环境与编程
-
- mysql简单使用
- User表
- Friend表
- AllGroup表
- GroupUser表
- OfflineMessage表
- 集群聊天项目工程目录创建
- 网络模块代码Chatserver
-
- 头文件
- 类函数定义文件
- 主函数文件
Cmake简单介绍
Cmake与Makefile
Makefile 在大项目里, 很难写 出来, 推荐Cmake
- 直接构建工具:定义编译规则(如 gcc -o main main.c),由 make 直接执行。
- 手动编写:需指定每个文件的依赖和命令,适合小型项目。
- 平台差异:不同系统的 make 可能有兼容性问题。
- 构建系统生成器:通过 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 脚本中最基础且重要的命令之一
set(变量名 值) # 定义普通变量
在 CMake 中,add_executable 是一个核心命令,用于定义可执行文件目标。
add_executable(<目标名称> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] <源文件列表>)
最主要的是 目标名称 和 源文件列表
例子:
#单文件
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也有很多, 多看
target_link_libraries(<目标名称>
<PRIVATE|PUBLIC|INTERFACE> <库1> [<库2>…]
[<PRIVATE|PUBLIC|INTERFACE> <库3>…]
)
aux_source_directory 是 CMake 中一个 用于自动收集源文件 的命令,但现代 CMake 已不再推荐使用它。
aux_source_directory(<目录路径> <变量名>)
为什么不推荐使用?
推荐使用 set 手动, 很麻烦
完整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 的目录)。
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
建立 build 文件, 进入build 进行 cmake .., 之前的 杂乱的文件夹就在这个目录里了, 并且 可执行文件 在bin目录里
完整如下:
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)
# 设置可执行文件最终目录
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_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简单使用
创建数据库:
CREATE DATABASE database_name; // 大小写都行
选择要操作的 数据库:
use database_name;
查看默认的字符编码:
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_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)
# 加载子目录 src 既然进去, 就有 CMakeLists.txt
add_subdirectory(server)
# 所有源文件
aux_source_directory(. SRC_LIST)
# 生成可执行
add_executable(Chatserver ${SRC_LIST})
# 链接库
target_link_libraries(Chatserver muduo_net muduo_base pthread)
网络模块代码Chatserver
hpp文件 写声明
源文件 进行定义使用
头文件
include/chatserver.hpp
#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
不完整, 回调内部 还没写
#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
#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;
}
评论前必须登录!
注册