关于后端:day03-C项目开发配置最佳实践vscode远程开发配置格式化代码检查cmake管理配置

5次阅读

共计 8089 个字符,预计需要花费 21 分钟才能阅读完成。

教程阐明

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-tidy
Checks: '-*,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")
# 启用 GDB
SET(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.txt
add_subdirectory(lib)
add_subdirectory(server)
add_subdirectory(client)

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

// lib/CMakeLists.txt
set(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.txt
aux_source_directory(./ SOURCE_DIR)
add_executable(Server ${SOURCE_DIR})
target_link_libraries(Server lib)

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

mkdir build
cd build
cmake ..

在 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 edit2
endif(CCACHE_FOUND)

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

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

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

正文完
 0