教程阐明

C++高性能网络服务保姆级教程

首发地址

day03 C++我的项目开发配置最佳实际(vscode近程开发配置、格式化、代码查看、cmake治理配置)

前言

通过后面两节课,咱们曾经从零开始写出了一个基于epoll和reactor多线程模型的高并发的网络服务器,为前面的内网穿透我的项目打下了相干根底。

工欲善其事,必先利其器,在持续往下讲我的项目的具体实现前,这节课带大家先把开发环境搭建配置好。

vscode近程开发配置

因为前面我的项目用到了epoll和splice,这些都是unix环境中才有的调用,所以咱们还是须要在linux环境中开发,我选用的vscode连贯linux进行近程开发

选用vscode的起因

在这里只跟clion做下比拟,clion反对的full remote development,基本原理是主动同步本地目录和远端服务器目录,在写代码时,用的还是本地环境,无奈辨认unix特有的那些头文件。

而vscode的近程开发,是把开发者本人机器上的 VSCode 原样拷贝到作为指标机器(Remote Host)上,以服务的模式运行,而本地的 VSCode 作为客户端,两者之间通过近程通信协定彼此协调单干,实际上的开发工作次要是在服务端实现的。

配置流程

  • 反对ssh公钥登录近程服务器
  • 装置remote-ssh近程插件

装置后重启能够在侧边栏看见这个

  • 增加ssh target

点击「SSH TARGETS」旁边的「Configure」,抉择编辑第一个文件(用户目录下的.ssh/config)

在文件中填上服务器连贯信息如下,更多配置信息可点击这里

  • 增加近程工作区

点击「RemoteServer」前面的connection按钮,会关上一个新vscode窗口,期待连贯近程服务器并实现一些初始化工作后,可点击「Open Folder」增加服务器的目录。

装置C++扩大

为了不便C++开发,咱们须要增加C++扩大

clang-format格式化代码

开发一个我的项目时,个别是由多个程序员共同开发保护,如果每个人的编码习惯格调都不同,整个我的项目可能格调芜杂,可读性差,不利于我的项目保护。clang-format反对的代码格调有google、llvm、Chromium
Mozilla、WebKit,咱们我的项目应用google格调。

装置clang-format

  • ubuntu装置

间接从apt仓库装置即可

sudo apt-get install clang-format
  • centos装置

centos 的yum仓库中并没有clang-format的安装包,须要更新repo源:

sudo yum install centos-release-scl-rh

之后下载clang-format:

sudo yum install llvm-toolset-7-git-clang-format

因为clang-format装置的地位不在零碎的PATH变量中,所以这个时候在命令行还找不到clang-format命令。咱们须要更新path变量,将clang-format的执行文件夹增加到path变量中:

  1. 找到clang-format执行文件夹

    sudo find / -name *clang-format*
    .../opt/rh/llvm-toolset-7/root/usr/bin/clang-format...
  2. 编辑~/.bashrc文件,更新path变量

    export PATH=$PATH:/opt/rh/llvm-toolset-7/root/usr/bin

创立clang-format文件

输出以下命令就会依照google的格局在在以后门路下生成.clang-format文件。

clang-format -style=google -dump-config > .clang-format

大家只有探讨确认clang-format的具体内容,而后在我的项目根目录中退出这个文件,代码的格调问题就解决了。

vscode反对clang-format

配置在vscode保留文件后主动进行格式化

在扩大商店中搜寻装置clang-format插件

关上设置面板,之后在输入框输出clang-format,在「工作区」tab上找到style选项,批改为「file」,示意依照咱们本人定义的.clang-format文件进行格式化

关上设置面板,在输入框中输出save,在「工作区」tab上把「format on save」选项勾选上

代码查看工具clang-tidy

clang-tidy是一个性能非常弱小的代码查看工具,能帮忙咱们现代化代码,进步代码的可读性

clang-tidy的装置

  • ubuntu装置

    sudo apt-get install clang-tidy
  • centos装置

    (1)sudo yum install centos-release-scl(2)sudo yum install llvm-toolset-7(3)sudo yum install llvm-toolset-7-clang-analyzer llvm-toolset-7-clang-tools-extra(4)scl enable llvm-toolset-7 'clang -v'(5)scl enable llvm-toolset-7 'lldb -v'(6)scl enable llvm-toolset-7 bash

clang-tidy应用

// 列出所有的check$ clang-tidy -list-checks -checks='*'// 找出simple.cc中所有没有用到的using declarations. 前面的`--`示意这个文件不在compilation database外面,能够间接独自编译;$ clang-tidy -checks="-*,misc-unused-using-decls" path/to/simple.cc --// 找出simple.cc中所有没有用到的using declarations并主动fix(删除掉)$ clang-tidy -checks="-*,misc-unused-using-decls" -fix path/to/simple.cc --// 找出a.c中没有用到的using declarations. 这里须要path/to/project/compile_commands.json存在$ clang-tidy -checks="-*,misc-unused-using-decls" path/to/project/a.cc

如果在被剖析的文件前面没有"--", clang-tidy会从目录下查找compliation database,这个database就是compile_commands.json文件,外面蕴含该我的项目中所有的编译单元的编译命令。
在应用之前要导出这个文件。目前曾经有工具帮咱们做了这项工作。

  • 如果是cmake的我的项目,通过cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON path/to/llvm/sources命令导出;

    cmake版本须要大于3.5
  • 如果是GYP我的项目,通过ninja -C out/D -t compdb cc cxx objc objcxx > compile_commands.json;
  • 如果是make我的项目,应用Bear工具;

除了通过“-checks=”来设定查看规定,还能够在我的项目主目录之下增加.clang-tidy文件,在外面编写我的项目的查看规定,这种形式更加适宜对整个我的项目进行定制化的规定编写。.clang-tidy文件并不是必须放在主目录之下,只是通常放在主目录之下不便对整个我的项目进行查看。

# .clang-tidyChecks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,-readability-identifier-naming'# Note that the readability-identifier-naming check is disabled, there are too# many violations in the codebase and they create too much noise in clang-tidy# results.# Naming settings are kept for documentation purposes and allowing to run the# check if the users would override this file, e.g. via a command-line arg.CheckOptions:  - key:             readability-identifier-naming.ClassCase    value:           CamelCase  - key:             readability-identifier-naming.EnumCase    value:           CamelCase  - key:             readability-identifier-naming.FunctionCase    value:           camelBack  - key:             readability-identifier-naming.MemberCase    value:           CamelCase  - key:             readability-identifier-naming.ParameterCase    value:           CamelCase  - key:             readability-identifier-naming.UnionCase    value:           CamelCase  - key:             readability-identifier-naming.VariableCase    value:           CamelCase

下面的应用办法中,一次只能剖析一个文件,如何一次性剖析整个我的项目的文件呢?clang-tidy提供了run_clang_tidy.py脚本,通过多过程的办法对整个我的项目文件进行剖析。(具体应用办法可参考上面的cmake写法)

cmake实现代码工程化

随着我的项目越来越简单,模块越来越多,咱们持续手动写makefile去构建我的项目显然不太适合,为了方便管理、构建简单我的项目,应用cmake作为构建工具是个不错的抉择。cmake是一个跨平台、开源的构建工具,能够不便的产生可移植的makefile,简化手动写makefile的工作量。

应用cmake生成makefile文件并编译一个分以下流程:

  1. 在根目录及每个模块目录下编写CMakeLists.txt
  2. 在根目录创立一个build文件夹
  3. 进入build目录,执行cmake …/ 生成整个我的项目的makefile
  4. 执行make和make install进行编译和装置。
cmake的命令较多,具体教程可参考https://www.cnblogs.com/ybqjy...

cmake实际

CProxy的代码目录构造如下

├── client│   ├── xxx.cpp│   ├── ...├── lib│   ├── xxx.cpp│   ├── ...├── server│   ├── xxx.cpp│   ├── ...

server目录是CProxy服务端目录,client目录是CProxy客户端目录,server和client别离能构建出可执行的程序;lib目录则寄存一些被server和client调用的库函数。

首先,咱们先在我的项目根目录上创立一个CMakeLists.txt

# cmake_minimum_required:指定了以后工程反对的cmake最小版本cmake_minimum_required(VERSION 3.1)# project:指定工程名称project(CProxy)# CMake 中有一个变量 CMAKE_BUILD_TYPE ,能够的取值是 Debug、Release、RelWithDebInfo和 MinSizeRel。# 当这个变量值为 Debug 的时候,CMake 会应用变量 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_C_FLAGS_DEBUG 中的字符串作为编译选项生成 Makefile; 当变量值为Release时,则会应用CMAKE_CXX_FLAGS_RELEASE 和 CMAKE_C_FLAGS_RELEASE 中的字符串作为编译选项生成 Makefile。SET(CMAKE_BUILD_TYPE "Debug")# 启用GDBSET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")# 启用优化(1~3)SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")# 设置 c++ 编译器,这里应用clang++进行编译set(CMAKE_CXX_COMPILER "clang++")set(CMAKE_CXX_STANDARD 11)set(CMAKE_CXX_STANDARD_REQUIRED True)set(CMAKE_CXX_FLAGS -g -Wall)message(STATUS "CMAKE_CXX_FLAGS: " "${CMAKE_CXX_FLAGS}")string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")message(STATUS "CMAKE_CXX_FLAGS: " "${CMAKE_CXX_FLAGS}")# include_directories:将指定目录增加到编译器的头文件搜寻门路之下,指定的目录被解释成以后源码门路的相对路径。# 将工程根目录增加进来后,在server和client中能通过"lib/xxx"引入lib目录下的头文件include_directories(${PROJECT_SOURCE_DIR})# 增加子目录,并构建该子目录。# 会执行lib、server、client三个目录中的CMakeLists.txtadd_subdirectory(lib)add_subdirectory(server)add_subdirectory(client)

下面的CMakeLists.txt增加了lib、server、client三个子目录,所以须要在这三个目录中也增加CMakeLists.txt

// lib/CMakeLists.txtset(lib    Buffer.cpp    EventLoopThread.cpp    EventLoopThreadPool.cpp    Util.cpp    EventLoop.cpp    Channel.cpp    Epoll.cpp    Msg.cpp    CtlConn.cpp    ProxyConn.cpp)# 将${lib}变量指定的源文件生成链接文件add_library(lib ${lib})# target_link_libraries:将指标文件与库文件进行链接# 应用多线程须要引入pthread库,所以将pthread库链接到上一步创立的lib指标文件中target_link_libraries(lib pthread)
// client/CMakeLists.txt# 将client目录下的所有源文件都存储到SOURCE_DIR变量中。 aux_source_directory(./ SOURCE_DIR)# 将${SOURCE_DIR}中的所有源文件编译成Client可执行文件add_executable(Client ${SOURCE_DIR})# 生成可执行文件须要链接lib库target_link_libraries(Client lib)
// Server/CMakeLists.txtaux_source_directory(./ SOURCE_DIR)add_executable(Server ${SOURCE_DIR})target_link_libraries(Server lib)

在根目录创立build目录,并执行cmake .. 生成整个我的项目的makefile

mkdir buildcd buildcmake ..

在build目录下执行make进行编译

make

clang-tidy在cmake中的配置

为了不便clang-tidy在我的项目中的应用,能够在根目录的CMakeLists.txt增加如下配置

# 用于输入clang-tidy须要用到的compile_commands.json文件# 这一行须要放在add_subdirectory/aux_source_directory之前set(CMAKE_EXPORT_COMPILE_COMMANDS ON)set(CLANG_SEARCH_PATH "/usr/local/bin" "/usr/bin" "/usr/local/opt/llvm/bin" "/usr/local/opt/llvm@8/bin" "/usr/local/Cellar/llvm/8.0.1/bin")if (NOT DEFINED CLANG_TIDY_BIN)    # attempt to find the binary if user did not specify    find_program(CLANG_TIDY_BIN            NAMES clang-tidy clang-fidy-8            HINTS ${CLANG_SEARCH_PATH})endif ()if ("${CLANG_TIDY_BIN}" STREQUAL "CLANG_TIDY_BIN-NOTFOUND")    message(WARNING "couldn't find clang-tidy.")else ()    message(STATUS "found clang-fidy at ${CLANG_TIDY_BIN}")endif ()# 增加clang-tidy命令add_custom_target(clang-tidy COMMAND python ${CMAKE_SOURCE_DIR}/run-clang-tidy.py                              # run LLVM's clang-tidy script-clang-tidy-binary ${CLANG_TIDY_BIN} # using our clang-tidy binary-p ${CMAKE_BINARY_DIR}      # using cmake's generated compile commands)

执行cmake获取到Makefile后,在build目录下执行make clang-tidy, 即可对整个我的项目进行代码剖析。

ccache减速编译

随着我的项目代码量越来越多,编译破费的工夫会很长,在调试代码时,咱们可能只改了一行代码,每次要编译个几分钟。这个时候就轮到ccache退场了。它将在第一遍编译时多花几秒钟,但接下来就会使编译成倍(5-10倍)的提速。

ccache 的基本原理是通过将头文件高速缓存到源文件之中而改良了构建性能,因此通过缩小每一步编译时增加头文件所须要的工夫而进步了构建速度。

ccache装置

yum install ccache

联合cmake应用

在根目录的CMakeLists.txt加上上面这段代码

find_program(CCACHE_FOUND ccache)if(CCACHE_FOUND)    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)    set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) # Less useful to do it for linking, see edit2endif(CCACHE_FOUND)

从新进行编译,会发现第一遍还是比拟久,但之后的编译速度就会变的很快了。

文章波及到的代码文件可间接查看CProxy,欢送fork and star!

如果本文对你有用,点个赞再走吧!或者关注我,我会带来更多优质的内容。