前言
在 GitHub 看到一个 Web 服务器项目,想用来回顾一下网络编程方面的知识。发现这是一个由 makefile 构建的项目,而现在主流的构建方式是 CMake,所以想先把它转化为一个 CMake 项目。主要是根据项目结构以及 makefile 文件编写 CMakeLists.txt。
准备工作
- 在 Linux 中安装 MySQL,推荐在 docker 中安装。(踩坑:一开始是直接在 Linux 中安装,后来想改成 docker 安装,在 docker 中安装后启动时报错端口被占用和一个别的错误,最后发现是一开始直接安装的 MySQL 和 docker 中的冲突的,原来的 mysqld 进程一直占用着 3306 端口, kill -9 也杀不掉,最后把直接安装的 MySQL 卸载干净了才能顺利启动 docker 中的 MySQL)
- 安装 mysql 开发库:sudo apt-get install libmysqlclient-dev (安装在 /usr/include/mysql 目录下)
项目结构
这个项目有三个分支,我选择从 raw_version 分支入手。该分支的项目结构如下:
有些模块的接口定义(.h)和实现(.cpp)分离了而有些模块没有,个人觉得这是一个不够规范的地方。makefile 文件的内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| server: main.c \ ./threadpool/threadpool.h \ ./http/http_conn.cpp ./http/http_conn.h \ ./lock/locker.h ./log/log.cpp ./log/log.h ./log/block_queue.h \ ./CGImysql/sql_connection_pool.cpp ./CGImysql/sql_connection_pool.h
g++ -o server \ main.c \ ./threadpool/threadpool.h \ ./http/http_conn.cpp ./http/http_conn.h \ ./lock/locker.h ./log/log.cpp ./log/log.h \ ./CGImysql/sql_connection_pool.cpp ./CGImysql/sql_connection_pool.h \ -lpthread -lmysqlclient
clean: rm -r server
|
总体来说是比较简单的。这里将一些头文件(.h)也一并加入,我尝试过去掉这些头文件后同样能正常编译运行。
编写 CMakeLists.txt
首先新建了 include
文件夹,在其中放置各个模块的头文件,定义和实现没有分离的也一并放入其中。此时项目结构如下:
根据此时的项目结构,结合已有的 makefile 文件编写 CMakeLists.txt 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| cmake_minimum_required(VERSION 3.0)
project(WebServerCmake)
set(CMAKE_BUILD_TYPE Debug) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
set(path ${CMAKE_SOURCE_DIR})
include_directories(${path}/include)
add_executable(WebServerCmake main.cpp CGImysql/sql_connection_pool.cpp log/log.cpp http/http_conn.cpp)
target_link_libraries(WebServerCmake libmysqlclient.so) target_link_libraries(WebServerCmake libpthread.so)
|
还需要修改一下修改后文件的 #include 路径;之后运行下面的命令后就可以构建并运行项目了:
1 2 3 4
| mkdir build && cd build cmake .. make ./WebServerCmake 1256
|
在 vscode 中运行并调试项目
主要是配置 .vscode 文件夹中的 launch.json 和 tasks.json。在 vscode 中启动 c++ 项目调试便是依靠这两个文件的配置
tasks.json 中的命令会在 launch.json 中的 命令之前前执行,即对应preLaunchTask
,可以在 tasks.json 中配置执行 cd build && cmake … && make 这些命令
tasks.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| { "version": "2.0.0", "options": { "cwd": "${workspaceFolder}/build" }, "tasks": [ { "type": "shell", "label": "cmake", "command": "cmake", "args": [ ".." ] }, { "label": "make", "group": { "kind": "build", "isDefault": true }, "command": "make", "args": [
] }, { "label": "Build", "dependsOrder": "sequence", "dependsOn":[ "cmake", "make" ] } ] }
|
launch.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| { "version": "0.2.0", "configurations": [ { "name": "g++ - 生成和调试活动文件", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/WebServerCmake", // 可执行文件的位置 "args": [ "1256" // 命令行启动时的参数 ./WebServerCmake 1256 ], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "为 gdb 启用整齐打印", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "preLaunchTask": "Build", // 这里要和 task.json 中 的 Build 一致 "miDebuggerPath": "/usr/bin/gdb" } ] }
|
参考