标题目录
面向所以平台的C++开发
本文仍然以Windows环境为例展开讨论,对于linux环境只做简单的介绍。
工具准备
window环境中C++的编译组件大体可分为两类:
- 一类是集成在VS中的MSVC,该组件
只能可以通过VS一起安装,也可以独立安装无IDE版并选择版本 - 另一类是诸如MinGW这类运行环境下的GCC或LLVM工具集,其中的环境和编译组件可以自行编译,也可以通过第三方组织或个人,如Qt(Qt Maintenance Tool)、WinIibs、niXman和lhmouse提供。
此外,我们还需要CMake、Ninja、vcpkg,以及新任宇宙集成开发环境VS Code
- 其中vcpkg可以通过github获取也可以通过VS安装
- VS Code需要必要的插件CMake Tools和C/C++ Extension Pack,这类插件都可在VSCode中直接安装
源码工程
创建/克隆工程源码文件
创建本地工程
- 建立一个包含CMakeLists.txt文件和include、src、apps、tests和build文件夹的经典CMake工程
peoject root folder .
├───.vscode
│ └───settings.json
├───3rdbinary
├───apps
│ └───CMakeLists.txt
├───include
├───src
│ └───CMakeLists.txt
├───tests
│ └───CMakeLists.txt
├───CMakeLists.txt
├───vcpkg-configuration.json
└───vcpkg.json
克隆项目
或者clone一个项目
git clone git@github.com:fmtlib/fmt.git
vcpkg的配置
vcpkg配置之前需要进行vs code中vcpkg环境的配置,打开.vscode->settings.json
文件,添加如下命令
"terminal.integrated.env.windows": {
"VCPKG_ROOT": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/vcpkg",
// 更新path变量中的路径
"Path": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/vcpkg;${env:PATH};${workspaceFolder}/3rdbinary/x64-mingw-dynamic/bin",
},
关于vcpkg的使用本人建议使用较新的“清单模式(manifest )”,而非已有的“经典模式”,之后的步骤如下:
- 在根目录下执行“初始化”命令
vcpkg new --application
- 添加基线并更新,个人理解为第三方库的软件源
vcpkg x-update-baseline --add-initial-baseline
vcpkg x-update-baseline
- 添加第三方库,如fmt、zlib等
vcpkg add port fmt gtest
- 在正式安装第三方库之前可以先看看vcpkg提供哪些平台
vcpkg help triplet
> vcpkg help triplet
Built-in Triplets:
arm-neon-android
arm64-android
arm64-uwp
arm64-windows
x64-android
x64-linux
x64-osx
x64-uwp
x64-windows-static
x64-windows
x86-windows
Community Triplets:
...
x64-freebsd
x64-ios
x64-linux-dynamic
x64-linux-release
x64-mingw-dynamic
x64-mingw-static
x64-openbsd
x64-osx-dynamic
x64-osx-release
x64-uwp-static-md
x64-windows-release
x64-windows-static-md
x64-windows-static-release
x64-xbox-scarlett-static
x64-xbox-scarlett
x64-xbox-xboxone-static
x64-xbox-xboxone
...
See https://learn.microsoft.com/vcpkg/users/triplets for more information.
- 在上一步可以看出存在许多类型,我们以
x64-mingw-dynamic
为例进行安装至3rdbinary
文件夹
vcpkg install --triplet x64-mingw-dynamic --x-install-root=./3rdbinary
- 至此所需要依赖的第三方库我们已经安装完毕!
CMake的配置
同样,在正式编写CMakeLists.txt
文件之前,需要在settings.json
进行配置
// 向cmake tools插件的一键启动生成的终端--CMake/Launch--中添加路径,保证一键运行的顺利进行
"cmake.environment": {
"Path": "${env:PATH};${workspaceFolder}/3rdbinary/x64-mingw-dynamic/bin;${workspaceFolder}/3rdbinary/x64-mingw-dynamic/debug/bin;"
},
// 指定构建的工具,可以使用 Visual Studio 17 2022、MinGW Makefiles、Unix Makefiles
"cmake.generator": "Ninja",
// 该参数下可以添加更多命令,如配置类型"CMAKE_BUILD_TYPE": "Release";启用线程数量"CMAKE_CXX_FLAGS": "/MP6"等
"cmake.configureSettings": {
// 该键是告诉CMake去这些路径下寻找Find***.cmake文件
"CMAKE_PREFIX_PATH": "${workspaceFolder}/3rdbinary/x64-mingw-dynamic/share/fmt;${workspaceFolder}/3rdbinary/x64-mingw-dynamic/share/gtest;"
// 当然你也可以如下方式配置,从而直接忽略以上的所有配置,但你将无法自己选择triplet,而只能使用 x64-windows
// 事情总是这样的,方便与定制不能兼得
// CMAKE_TOOLCHAIN_FILE="{yourVcpkgPath}/scripts/buildsystems/vcpkg.cmake"
},
- 之后我们需要写好各个层级的
CMakeLists.txt
文件
目标文件生成
源码编写
- 个人建议在
apps
文件夹写入口案例,src
文件夹写诸如函数、类这类的库文件,tests
写类、函数的测试文件 - 每个文件夹添加一个
CMakeLists.txt
文件,作为工程的子模块- 在根目录下的CMakeLists.txt添加
add_subdirectory(apps)
这些子模块
- 在根目录下的CMakeLists.txt添加
二进制目标生成方式
以下两种方式任选一种
-
GUI形式简单,可以点击
CMake Tools
工具的Build
按钮,如下图中数字1所在的框 -
command line
cd build
cmake --build .
- 编译完后可以点击按钮2进行运行
调试
- 调试程序注意事项:
- 最好在
Debug
模式下 - 不能将编译器的优化等级设置过高,编译出的程序必须带有调试信息
- 最好在
- GUI:直接启动调试
- 文件或命令行启动调试工具
这个具体说来需要定义调试工具,待调试的程序,以及启动程序时argv
中的参数等等等,属于调试高级使用方法。等待后续更新…
测试
同样存在基于GUI的直接运行和命令行形式的两种执行方式
- 注意事项:
- 开启允许调试
enable_testing()
- 开启允许调试
- GUI
- command line
ctest -R
其他
关于MinGW的选择
正如所看到通过vcpkg安装的包版本,本文用例使用的MinGW64环境下的GCC组件进行的编译。但对于许多程序或库的开发人员来说,他们并不会用该环境下的GCC编译器检测一边自己的源码,尤其涉及到许多与系统有关的宏命令时出错率增大。因此,你除非有必须使用MinGW64环境中GCC或LLVM工具的理由,否则对于实际开发理应首选各自环境下的亲儿子版本,即:
- Windows使用MSVC
- Linux使用GCC(
LLVM也行) - MacOS使用LLVM/Clang
当然若就是想体验MinGW64,还想获得尽可能多的第三方包或库的支持,可以考虑使用MSYS2、 Cygwin这类构建环境,这类环境不仅包含供GCC(严格来说,GNU组织下的多数工具)在Windows上运行的MinGW这类环境,还提供类似conda、pip、apt这样的包管理工具
关于非windows环境
linux
在linux,诸如Ubuntu、CentOS和Debian的发现版可以通过各自系统的软件安装指令获取不同版本的GCC或LLVM编译工具后按照前文的方式进行开发。若考虑工程很大可使用docker这类容器实现系统级别的隔离
MacOS
不清楚
注意事项
- GCC既可以使用
make
也可以使用ninja
进行管理项目的构建过程 - 是否可以使用
ninja
替代MSBuild
建立一个用MSVC编译组件编译的工程?- 太抽象了,但我还是试过,但没成功
- 或者说直接向CMake指定
cl.exe
编译器但选择Ninja
不能成功