文章目錄
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 腳本中最基礎且重要的命令之一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(<目錄路徑> <變量名>)
為什么不推薦使用?
- 不會自動檢測新增文件
需要手動重新運行 CMake 才能識別新添加的源文件。 - 包含無關文件風險
可能意外包含測試文件、備份文件(如main.cpp.bak
)。 - 破壞構建系統的確定性
隱式文件收集會導致構建行為不可預測。 - 與現代 CMake 理念沖突
現代 CMake 強調顯式聲明源文件(target_sources()
)。
推薦使用 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;
}