当前位置: 首页 > Linux

【系列教程】C++项目开发配置最佳实践(vscode远程开发配置、格式化、代码检查、cmake管理配置)

时间:2023-04-06 03:17:17 Linux

首发地址day03C++项目开发配置最佳实践(vscode远程开发配置、格式化、代码检查,cmake管理配置)项目仓库地址https://github.com/lzs123/CProxy,欢迎fork和star!上一篇教程day01-从一个基础的socket服务说起day02真正的高并发依赖IO多路复用高并发网络服务器为后续的内网穿透项目打下了基础。工欲善其事,必先利其器。在继续说项目的具体实现之前,本课先带大家搭建和配置开发环境。vscode远程开发配置因为后面的项目中用到了epoll和splice,这些都是unix环境下的调用,所以还是需要在linux环境下开发。我选择vscode连接linux进行远程开发。选择vscode的原因仅在这里相对于clion,clion支持的全远程开发的基本原理是自动同步本地目录和远程服务器目录。写代码的时候,还是用本地环境,无法识别unix特有的头文件。vscode的远程开发是将开发者自己机器上的VSCode拷贝到目标机器(RemoteHost)上并作为服务运行,而本地的VSCode作为客户端,两者通过远程进行通信通信协议。协调配合,实际的开发工作主要在服务端完成。配置过程支持ssh公钥登录远程服务器。安装remote-ssh远程插件并重启。您可以在侧边栏中看到它。添加ssh目标点击“SSHTARGETS”旁边的“Configure”,选择编辑第一个文件(用户目录.ssh/config下)在文件中填写服务器连接信息如下,更多配置信息,点击这里添加远程工作区点击“RemoteServer”后面的连接按钮,会打开一个新的vscode窗口,等待连接远程服务器并完成一些初始化工作后,可以点击“打开文件夹”添加服务器的目录。安装C++扩展为了方便C++开发,我们需要添加C++扩展clang-format来格式化代码。在开发一个项目时,一般是由多个程序员共同开发和维护的。如果每个人的编码习惯不同,整个项目可能会很乱,可读性差,不利于项目维护。clang-format支持的代码风格包括google、llvm、ChromiumMozilla和WebKit。我们的项目使用的是google风格。安装clang-formatubuntu,直接从apt仓库安装。sudoapt-getinstallclang-formatcentos安装centos。yum仓库中没有clang格式的安装包。需要更新repo源:sudoyuminstallcentos-release-scl-rh然后下载clang-format:sudoyuminstallllvm-toolset-7-git-clang-format因为安装clang-format的位置不在系统的PATH变量,此时在命令行找不到clang-format命令。我们需要更新path变量,将clang-format执行文件夹添加到path变量中:找到clang-format执行文件夹sudofind/-name*clang-format*.../opt/rh/llvm-toolset-7/root/usr/bin/clang-format...编辑~/.bashrc文件,更新路径变量exportPATH=$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格式的配置。vscode保存文件后,会自动格式化。在扩展商店中搜索并安装clang-format插件打开设置面板,然后在输入框中输入clang-format,在“工作区”选项卡中找到样式选项,进行修改。是“文件”,意思是按照我们自己定义的.clang-format文件进行格式化。打开设置面板,在输入框中输入save,勾选“workspace”选项卡上的“formatonsave”选项。代码检查工具clang-tidyclang-tidy是一款非常强大的代码检查工具,可以帮助我们实现代码的现代化,提高代码的可读性clang-tidy安装ubuntu安装sudoapt-getinstallclang-tidycentos安装(一)sudoyum安装centos-release-scl(2)sudoyuminstallllvm-toolset-7(3)sudoyuminstallllvm-toolset-7-clang-analyzerllvm-toolset-7-clang-tools-extra(4)sclenablellvm-toolset-7'clang-v'(5)sclenablellvm-toolset-7'lldb-v'(6)sclenablellvm-toolset-7bashclang-tidyuse//列出所有检查$clang-tidy-list-checks-checks='*'//找出simple.cc中所有未使用的using声明。后面的`--`表示该文件不在编译数据库中,可以直接编译;$clang-tidy-checks="-*,misc-unused-using-decls"path/to/simple.cc--//查找simple.cc中所有未使用的using声明并自动修复(删除)$clang-tidy-checks="-*,misc-unused-using-decls"-fixpath/to/simple.cc--//查找a.c.中未使用的using声明。这里需要存在path/to/project/compile_commands.json$clang-tidy-checks="-*,misc-unused-using-decls"path/to/project/a.cc如果分析后的文件后面没有“--”,clang-tidy会从目录中搜索编译数据库。这个数据库就是compile_commands.json文件,里面包含了使用这个文件之前需要导出的工程中所有编译单元的编译命令。已经有工具可以为我们做到这一点。如果是cmake工程,使用cmake-DCMAKE_EXPORT_COMPILE_COMMANDS=ONpath/to/llvm/sources命令导出;cmake版本需要大于3.5。如果是GYP项目,使用ninja-Cout/D-tcompdbcccxxobjcobjcxx>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'#请注意,可读性标识符命名检查已禁用,代码库中有太多违规行为,它们会在clang-tidy#结果中产生太多噪音。#命名设置保留用于文档目的并允许运行the#检查用户是否会覆盖此文件,例如通过命令行arg.CheckOptions:-key:readability-identifier-naming.ClassCasevalue:CamelCase-key:readability-identifier-naming.EnumCasevalue:CamelCase-key:readability-identifier-naming.FunctionCasevalue:camelBack-key:readability-identifier-naming.MemberCase值:CamelCase-键:readability-identifier-naming.ParameterCase值:CamelCase-键:readability-identifier-naming.UnionCasevalue:CamelCase-key:readability-identifier-naming.VariableCasevalue:在上述使用CamelCase的方法中,一次只能分析一个文件。如何一次性分析整个项目的文件?clang-tidy提供了run_clang_tidy.py脚本,通过多进程的方式解析整个工程文件(具体用法参考下面cmake的写法)cmake实现代码工程随着工程越来越复杂,越来越多的模块多了,我们继续手动写makefile来构建工程显然是不合适的。为了方便管理和构建复杂的项目,使用cmake作为构建工具是一个不错的选择。cmake是一个跨平台的开源构建工具,可以轻松生成可移植的makefile,简化手动编写makefile的工作量。使用cmake生成makefile并编译子流程:在根目录和各个模块目录下写入CMakeLists.txt,在根目录下创建build文件夹,进入build目录,执行cmake.../生成makefile整个工程,执行make和makeinstall编译安装。cmake命令很多,详细教程可以参考https://www.cnblogs.com/ybqjy...cmake实践CProxy的代码目录结构如下├──client│├──xxx.cpp│├──...├──lib│├──xxx.cpp│├──...├──server│├──xxx.cpp│├──...server目录为CProxy服务器目录,client目录为CProxyclient目录,服务端和客户端可以分别构建可执行程序;lib目录存放了一些服务端和客户端调用的库函数。首先我们在项目根目录下创建一个CMakeLists.txt#cmake_minimum_required:指定当前项目支持的最低cmake版本cmake_minimum_required(VERSION3.1)#project:指定项目名称project(CProxy)#CMAKE_BUILD_TYPE中有一个变量CMake,可以取值有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_STANDARD11)set(CMAKE_CXX_STANDARD_REQUIREDTrue)set(CMAKE_CXX_FLAGS-g-Wall)message(STATUS"CMAKE_CXX_FLAGS:""CXX_FLAGS:""CXX_FLAGS:""${CMAKE_FLAGS)string(REPLACE";"""CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS}")message(STATUS"CMAKE_CXX_FLAGS:""${CMAKE_CXX_FLAGS}")#include_directories:将指定目录添加到编译器的头文件中文件搜索路径,指定目录解释为相对于当前源码路径。#添加项目根目录后,lib目录下的头文件可以在服务端和客户端通过"lib/xxx"导入。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.txtset(libBuffer.cppEventLoopThread.cppEventLoopThreadPool.cppUtil.cppEventLoop.cppChannel.cppEpoll.cppMsg.cppCtlConn.cppProxyConn.cpp)#${lib指定的源文件}变量生成链接文件add_library(lib${lib})#target_link_libraries:Linkthetargetfilewiththelibraryfile#使用多线程需要引入pthread库,所以将pthread库链接到上一步创建的libtarget文件中target_link_libraries(libpthread)//client/CMakeLists.txt#将client目录下的所有源文件存放到SOURCE_DIR变量中。aux_source_directory(./SOURCE_DIR)#将${SOURCE_DIR}中所有源文件编译成Client可执行文件add_executable(Client${SOURCE_DIR})#生成可执行文件需要链接lib库target_link_libraries(Clientlib)//Server/CMakeLists.txtaux_source_directory(./SOURCE_DIR)add_executable(Server${SOURCE_DIR})target_link_libraries(Serverlib)在根目录下创建build目录,执行cmake..生成整个项目的makefilemkdirbuildcdbuildcmake..在build目录下执行make即可compilemakeclang-cmake中tidy的配置为了方便项目中使用clang-tidy,可以在根目录下的CMakeLists.txt中添加如下配置#用于输出clang-的compile_commands.json文件tidy需要用到#这一行需要放在add_subdirectory/aux_source_directory之前/usr/local/opt/llvm@8/bin""/usr/local/Cellar/llvm/8.0.1/bin")if(NOTDEFINEDCLANG_TIDY_BIN)#如果用户未指定find_program(CLANG_TIDY_BIN)则尝试查找二进制文件命名clang-tidyclang-fidy-8提示${CLANG_SEARCH_PATH})endif()if("${CLANG_TIDY_BIN}"STREQUAL"CLANG_TIDY_BIN-NOTFOUND")message(WARNING"找不到clang-tidy。")else()message(STATUS"在${CLANG_TIDY_BIN找到clang-fidy}")endif()#添加clang-tidy命令add_custom_target(clang-tidyCOMMANDpython${CMAKE_SOURCE_DIR}/run-clang-tidy.py#运行LLVM的clang-tidyscript-clang-tidy-binary${CLANG_TIDY_BIN}#使用ourclang-tidybinary-p${CMAKE_BINARY_DIR}#使用cmake生成的编译命令)执行cmake获取Makefile,在build目录下执行makeclang-tidy分析整个项目的代码,ccache随项目一起加速编译code随着体积的增大,编译时间会变长。在调试代码的时候,我们可能只改一行代码,每次编译都要几分钟。这时候就轮到ccache登场了。第一次编译会花费几秒钟的时间,但随后会使编译速度呈指数级(5-10倍)。ccache的基本原理是通过将头文件缓存到源文件中来提高构建性能,从而通过减少在编译的每个步骤中添加头文件所需的时间来提高构建速度。ccache安装yuminstallccache结合cmake使用根目录下的CMakeLists.txt加上如下代码linking,看edit2endif(CCACHE_FOUND)重新编译,会发现第一遍还是比较长,但是后面的编译速度会变得很快。文中涉及的代码文件可以直接在CProxy中查看,欢迎fork和star!如果本文对您有用,请点个赞,走起!或者关注我,我会带来更多优质内容。