CMake构建学习笔记16-使用VS进行CMake项目的开发
文章目录
- 1. 概论
- 2. 详论
- 2.1 创建工程
- 2.2 加载工程
- 2.3 配置文件
- 2.4 工程配置
- 2.5 调试执行
- 3. 项目案例
- 4. 总结
1. 概论
在之前的系列博文中,我们学习了如何构建第三方的依赖库,也学习了如何去组建自己的CMake项目,尤其是学习了CMake的核心配置文件CMakeLists.txt如何编写。长期以来,CMakeLists.txt这个文件都是C/C++项目额外编写的,然后使用CMake指令或者GUI工具配置成Windows下的MSVC工程,或者Linux下的Makefile文件。这样做虽然对比之前需要不同的平台下要使用不同的工程有了长足的进步,但是还可以再进一步,那就是直接在IDE中使用CMake工程进行开发,这样无疑对C/C++程序开发的效率有质的提升。
从Visual Studio 2017开始,Microsoft Visual Studio(简称VS)就开始支持CMake工程的导入。所谓CMake工程,指的就是不再需要建立传统的MSVC项目,例如.sln或者.vcxproj工程文件,而是直接使用CMakeLists.txt作为工程配置文件来进行加载,进行进行构建和开发的工作。不仅是VS,目前其他IDE比如Visual Studio Code、Qt Creator、IntelliJ IDEA、 CLion都能直接支持CMake工程的导入。但是,作为初学者,笔者还是建议从Microsoft Visual Studio入手进行CMake项目的开发,毕竟号称宇宙第一的IDE不是白叫的。以笔者的观点来看,Microsoft Visual Studio的确实有点重,编辑器也不是最美观的,UI操作也不一定是最人性化的,但是其提供的调试功能却是最优秀且不可或缺的,尤其适合商业中的生产力环境。这里笔者就以Visual Studio 2019 为例,详细讲解一下如何进行CMake项目的开发,以提升我们的C/C++程序开发效率。
2. 详论
2.1 创建工程
启动Visual Studio 2019,弹出的启动页面,如下图1所示:

点击右下方“创建新项目”按钮,进入“创建新项目”页面,如下图2所示:

选择“CMake项目”的模板,如果没有看到可以搜索一下模板。点击“下一步”按钮,进入“配置新项目”页面,如下图3所示:

在“配置新项目”页面填入项目名称和位置,点击“创建”按钮,就进入了Visual Studio 2019的主要工作页面,如下图4所示:

2.2 加载工程
关闭Visual Studio 2019,模拟一下直接加载现有CMake工程的情况。再次启动Visual Studio 2019,一般在图1所示的启动页面中可以看到上次加载过的历史记录,点击就可以再次进行加载了。但是如何没有历史记录,就点击“继续但无需代码”按钮,直接进入主页面。在菜单栏中依次选择文件->打开->CMake按钮,如下图5所示:

此时会弹出“打开CMake项目”对话框,选中项目中的CMakeList.txt文件,CMake项目就是通过这个核心配置文件来打开的,如下图6所示:

记住一定要通过这种方式打开CMakeList.txt文件才会打开CMake项目,如果直接将CMakeList.txt文件拖入到Visual Studio 2019主页面中只会文本形式显示CMakeList.txt。
2.3 配置文件
接下来再正式进行开发之前,我们需要先搞定一个配置文件CMakePresets.json。CMakeList.txt具有非常多的配置项,或者需要传入的外部参数,需要使用一个配置文件来进行管理。不过麻烦就麻烦在这里,CMakePresets.json是CMake 3.20引入的,是个相对较新的功能,Visual Studio 2019并没有一开始就对接这个配置文件,而是使用自己设计的CMakeSettings.json文件作为CMake构建项目的配置。目前,这两种配置文件Visual Studio 2019都支持,但是更推荐使用CMakePresets.json,因为更加标准化,符合CMake的规范,可以被多种IDE和构建工具识别和支持。
具体来说,如果程序主页面,尤其是主页面的工具栏与下图7有所不同:

那么可以在菜单栏依次选择工具->选项->CMake->常规,勾选“首次使用CMake预设值进行配置、构建和测试”的单选框,如下图8所示:

点击工具栏的配置下拉菜单,选择“管理配置”按钮,如下图9所示:

此时Visual Studio 2019就会自动创建CMakeSettings.json配置文件,如下图10所示:

从这个文件可以看到默认的windows-default配置其实是Debug模式,我们可以将其增加一个RelWithDebInfo模式,也就是Release带调试信息模式,CMakePresets.json具体的内容为:
{"version": 2,"configurePresets": [{"name": "linux-default","displayName": "Linux Debug","description": "面向适用于 Linux 的 Windows 子系统(WSL)或远程 Linux 系统。","generator": "Ninja","binaryDir": "${sourceDir}/out/build/${presetName}","cacheVariables": {"CMAKE_BUILD_TYPE": "Debug","CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"},"vendor": {"microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Linux" ] },"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" }}},{"name": "windows-default","displayName": "Windows x64 Debug","description": "面向具有 Visual Studio 开发环境的 Windows。","generator": "Ninja","binaryDir": "${sourceDir}/out/build/${presetName}","architecture": {"value": "x64","strategy": "external"},"cacheVariables": {"CMAKE_BUILD_TYPE": "Debug","CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"},"vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } }},{"name": "RelWithDebInfo","displayName": "Windows x64 RelWithDebInfo Shared Library","description": "面向具有 Visual Studio 开发环境的 Windows。","generator": "Ninja","binaryDir": "${sourceDir}/out/build/${presetName}","architecture": {"value": "x64","strategy": "external"},"cacheVariables": {"CMAKE_BUILD_TYPE": "RelWithDebInfo","CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"},"vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } }}]
}
添加这段配置并Ctrl+S保存之后,工具栏的配置下拉菜单就会多了RelWithDebInfo这个选项,将其选中,如下图11所示:

注意,有的时候因为两种配置方式的冲突问题,会导致一些异常现象,比如工具栏的配置菜单不太一样。如果遇到这种情况可以推出Visual Studio 2019,清理工程的中间生成文件,再重新加载工程试试。
2.4 工程配置
再接下来的步骤不要急着去编写源代码文件,要先完成CMakeLists.txt的编写。新建工程的CMakeLists.txt会有一段默认的内容,如下所示:
# CMakeList.txt: ZipTest 的 CMake 项目,在此处包括源代码并定义
# 项目特定的逻辑。
#
cmake_minimum_required (VERSION 3.8)project ("ZipTest")# 将源代码添加到此项目的可执行文件。
add_executable (ZipTest "ZipTest.cpp" "ZipTest.h")# TODO: 如有需要,请添加测试并安装目标。
如果我们学习过上一篇博文的话就会理解这段配置代码文件,推荐读者复习一下。这里要说的关键是,在修改CMakeLists.txt文件之后,需要Ctrl+S保存一下,Visual Studio 2019就会自动进行工程配置,可以在输出窗口看到一些输出信息:
1> 已为配置“RelWithDebInfo”启动 CMake 生成。
1> 环境设置:
1> CommandPromptType=Native
1> DevEnvDir=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\
1> ExtensionSdkDir=C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs
1> Framework40Version=v4.0
1> FrameworkDir=C:\windows\Microsoft.NET\Framework64\
1> FrameworkDIR64=C:\windows\Microsoft.NET\Framework64
1> FrameworkVersion=v4.0.30319
1> FrameworkVersion64=v4.0.30319
1> HTMLHelpDir=C:\Program Files (x86)\HTML Help Workshop
1> IFCPATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\ifc\x64
1> IGCCSVC_DB=AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAggkwNDDGDkq0HFOUjEsXQAQAAAACAAAAAAAQZgAAAAEAACAAAADxjk35GiqLjZDHeYjx5dq8wxmbU7aEbBW9J68TO/bzIwAAAAAOgAAAAAIAACAAAADdM3gyHGrxXOwEEyHmxfe9ocZnP6CM0OTQGZYVZKgQWmAAAAC8xGVDuFoU062/gozauvaMPUmsT8FAuEXoLnI9lTwHVT6XWpjF7lVBoYB+vxo1dgIUAtW0nl1wZSUg9KRxmYpIicPPLm7B+twKXEdbaDMIu55E10uazKjjvoHY/4KYu+tAAAAAoK95FWIYAE3f+YLjfb3S77+ZMJXFw69cRlxyTYekzkyfOFdUcCY94ahV+XHEgao2y8e/zT+q2zHU0SqXho0LDQ==
1> INCLUDE=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\ATLMFC\include;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um;C:\Program Files (x86)\Windows Kits\10\include\10.0.22000.0\ucrt;C:\Program Files (x86)\Windows Kits\10\include\10.0.22000.0\shared;C:\Program Files (x86)\Windows Kits\10\include\10.0.22000.0\um;C:\Program Files (x86)\Windows Kits\10\include\10.0.22000.0\winrt;C:\Program Files (x86)\Windows Kits\10\include\10.0.22000.0\cppwinrt
1> LIB=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\ATLMFC\lib\x64;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\lib\x64;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64;C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\um\x64
1> LIBPATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\ATLMFC\lib\x64;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\lib\x64;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\lib\x86\store\references;C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.22000.0;C:\Program Files (x86)\Windows Kits\10\References\10.0.22000.0;C:\windows\Microsoft.NET\Framework64\v4.0.30319
1> NETFXSDKDir=C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\
1> Path=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\\Extensions\Microsoft\IntelliCode\CLI;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VC\VCPackages;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\bin\Roslyn;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Team Tools\Performance Tools\x64;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\\x64;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64\;C:\Program Files (x86)\HTML Help Workshop;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\devinit;C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64;C:\Program Files (x86)\Windows Kits\10\bin\x64;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\\MSBuild\Current\Bin;C:\windows\Microsoft.NET\Framework64\v4.0.30319;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Program Files\HP\OMEN-Broadcast\Common;C:\Program Files\CMake\bin;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\TortoiseGit\bin;C:\Work\3rdparty\bin;C:\SoftWare\Qt\Qt5.12.5\5.12.5\msvc2017_64\bin;C:\File\MyGitHub\GISBasic\3rdParty\bin;C:\Program Files\dotnet\;C:\Work\eGova3rdParty\protobuf\bin;C:\Program Files\Java\jdk1.8.0_271\bin;C:\Program Files\KTX-Software\bin;C:\SoftWare\sonar-scanner-msbuild;C:\Program Files\Cppcheck;C:\SoftWare\sonar-scanner-msbuild\sonar-scanner-4.7.0.2747\bin;C:\SoftWare\apache-ant-1.10.8\bin;C:\Program Files (x86)\pcsuite\;C:\SoftWare\apache-maven-3.6.2\bin;C:\Program Files\7-Zip;C:\Program Files\Git\cmd;C:\SoftWare\nvm;C:\Program Files\nodejs;C:\SoftWare\Python\Python311\Scripts\;C:\SoftWare\Python\Python311\;C:\Users\Charlee\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Microsoft VS Code\bin;C:\Users\Charlee\AppData\Local\GitHubDesktop\bin;C:\Users\Charlee\AppData\Roaming\npm;C:\SoftWare\nvm;C:\Program Files\nodejs;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VC\Linux\bin\ConnectionManagerExe
1> PROMPT=$P$G
1> UCRTVersion=10.0.22000.0
1> UniversalCRTSdkDir=C:\Program Files (x86)\Windows Kits\10\
1> VCIDEInstallDir=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VC\
1> VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\
1> VCToolsInstallDir=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\
1> VCToolsRedistDir=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Redist\MSVC\14.29.30133\
1> VCToolsVersion=14.29.30133
1> VS160COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\
1> VSCMD_ARG_app_plat=Desktop
1> VSCMD_ARG_HOST_ARCH=x64
1> VSCMD_ARG_no_logo=1
1> VSCMD_ARG_TGT_ARCH=x64
1> VSCMD_DEBUG=5
1> VSCMD_VER=16.11.29
1> VSINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\
1> WindowsLibPath=C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.22000.0;C:\Program Files (x86)\Windows Kits\10\References\10.0.22000.0
1> WindowsSdkBinPath=C:\Program Files (x86)\Windows Kits\10\bin\
1> WindowsSdkDir=C:\Program Files (x86)\Windows Kits\10\
1> WindowsSDKLibVersion=10.0.22000.0\
1> WindowsSdkVerBinPath=C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\
1> WindowsSDKVersion=10.0.22000.0\
1> WindowsSDK_ExecutablePath_x64=C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64\
1> WindowsSDK_ExecutablePath_x86=C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\
1> __devinit_path=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\devinit\devinit.exe
1> __DOTNET_ADD_64BIT=1
1> __DOTNET_PREFERRED_BITNESS=64
1> __VSCMD_PREINIT_PATH=C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Program Files\HP\OMEN-Broadcast\Common;C:\Program Files\CMake\bin;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\TortoiseGit\bin;C:\Work\3rdparty\bin;C:\SoftWare\Qt\Qt5.12.5\5.12.5\msvc2017_64\bin;C:\File\MyGitHub\GISBasic\3rdParty\bin;C:\Program Files\dotnet\;C:\Work\eGova3rdParty\protobuf\bin;C:\Program Files\Java\jdk1.8.0_271\bin;C:\Program Files\KTX-Software\bin;C:\SoftWare\sonar-scanner-msbuild;C:\Program Files\Cppcheck;C:\SoftWare\sonar-scanner-msbuild\sonar-scanner-4.7.0.2747\bin;C:\SoftWare\apache-ant-1.10.8\bin;C:\Program Files (x86)\pcsuite\;C:\SoftWare\apache-maven-3.6.2\bin;C:\Program Files\7-Zip;C:\Program Files\Git\cmd;C:\SoftWare\nvm;C:\Program Files\nodejs;C:\SoftWare\Python\Python311\Scripts\;C:\SoftWare\Python\Python311\;C:\Users\Charlee\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Microsoft VS Code\bin;C:\Users\Charlee\AppData\Local\GitHubDesktop\bin;C:\Users\Charlee\AppData\Roaming\npm;C:\SoftWare\nvm;C:\Program Files\nodejs
1> __VSCMD_script_err_count=0
1> HOMEPATH=\Users\Charlee
1> DriverData=C:\Windows\System32\Drivers\DriverData
1> COMPUTERNAME=LAPTOP-K38HMG48
1> CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
1> POSTGIS_GDAL_ENABLED_DRIVERS=ENABLE_ALL
1> ProgramW6432=C:\Program Files
1> OneDrive=C:\Users\Charlee\OneDrive
1> __PSLockDownPolicy=0
1> RegionCode=APJ
1> DEVECOSTUDIO_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\devecostudio.vmoptions
1> VisualStudioEdition=Microsoft Visual Studio Enterprise 2019
1> WEBIDE_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\webide.vmoptions
1> ServiceHubLogSessionKey=3AFDCD75
1> PROCESSOR_REVISION=b701
1> PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 183 Stepping 1, GenuineIntel
1> PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
1> PkgDefApplicationConfigFile=C:\Users\Charlee\AppData\Local\Microsoft\VisualStudio\16.0_36d14652\devenv.exe.config
1> JETBRAINS_CLIENT_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\jetbrains_client.vmoptions
1> PROJ_LIB=C:\Program Files\PostgreSQL\16\share\contrib\postgis-3.4\proj
1> CURL_CA_BUNDLE=C:\Program Files\PostgreSQL\16\ssl\certs\ca-bundle.crt
1> TMP=C:\Users\Charlee\AppData\Local\Temp
1> DATAGRIP_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\datagrip.vmoptions
1> TEMP=C:\Users\Charlee\AppData\Local\Temp
1> LOCALAPPDATA=C:\Users\Charlee\AppData\Local
1> PUBLIC=C:\Users\Public
1> eGova3rdParty=C:\Work\3rdparty
1> GDAL_DATA=C:\Program Files\PostgreSQL\16\gdal-data
1> PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\windows\system32\WindowsPowerShell\v1.0\Modules
1> ProgramData=C:\ProgramData
1> JAVA_HOME=C:\Program Files\Java\jdk1.8.0_271
1> USERDOMAIN=LAPTOP-K38HMG48
1> platformcode=M7
1> PROCESSOR_LEVEL=6
1> NUMBER_OF_PROCESSORS=32
1> PHPSTORM_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\phpstorm.vmoptions
1> STUDIO_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\studio.vmoptions
1> VSAPPIDDIR=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\
1> ProgramFiles(x86)=C:\Program Files (x86)
1> FPS_BROWSER_USER_PROFILE_STRING=Default
1> CommonProgramFiles=C:\Program Files (x86)\Common Files
1> VS140COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\
1> USERDOMAIN_ROAMINGPROFILE=LAPTOP-K38HMG48
1> VisualStudioDir=C:\Users\Charlee\Documents\Visual Studio 2019
1> IGCCSVC_DB=AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAggkwNDDGDkq0HFOUjEsXQAQAAAACAAAAAAAQZgAAAAEAACAAAADxjk35GiqLjZDHeYjx5dq8wxmbU7aEbBW9J68TO/bzIwAAAAAOgAAAAAIAACAAAADdM3gyHGrxXOwEEyHmxfe9ocZnP6CM0OTQGZYVZKgQWmAAAAC8xGVDuFoU062/gozauvaMPUmsT8FAuEXoLnI9lTwHVT6XWpjF7lVBoYB+vxo1dgIUAtW0nl1wZSUg9KRxmYpIicPPLm7B+twKXEdbaDMIu55E10uazKjjvoHY/4KYu+tAAAAAoK95FWIYAE3f+YLjfb3S77+ZMJXFw69cRlxyTYekzkyfOFdUcCY94ahV+XHEgao2y8e/zT+q2zHU0SqXho0LDQ==
1> GISBasic=C:\File\MyGitHub\GISBasic\3rdParty
1> VSLS_SESSION_KEEPALIVE_INTERVAL=0
1> MAVEN_HOME=C:\SoftWare\apache-maven-3.6.2
1> ProgramFiles=C:\Program Files (x86)
1> RUBYMINE_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\rubymine.vmoptions
1> APPCODE_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\appcode.vmoptions
1> FPS_BROWSER_APP_PROFILE_STRING=Internet Explorer
1> VSSKUEDITION=Enterprise
1> OnlineServices=Online Services
1> ThreadedWaitDialogDpiContext=-4
1> IDEA_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\idea.vmoptions
1> WEBSTORM_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\webstorm.vmoptions
1> GOLAND_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\goland.vmoptions
1> NVM_SYMLINK=C:\Program Files\nodejs
1> NVM_HOME=C:\SoftWare\nvm
1> SESSIONNAME=Console
1> VisualStudioVersion=16.0
1> SystemRoot=C:\windows
1> CommonProgramW6432=C:\Program Files\Common Files
1> ZES_ENABLE_SYSMAN=1
1> LOGONSERVER=\\LAPTOP-K38HMG48
1> VSAPPIDNAME=devenv.exe
1> USERPROFILE=C:\Users\Charlee
1> MSBuildLoadMicrosoftTargetsReadOnly=true
1> QtMsBuild=C:\Users\Charlee\AppData\Local\QtMsBuild
1> POSTGIS_ENABLE_OUTDB_RASTERS=1
1> VSLANG=2052
1> RIDER_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\rider.vmoptions
1> APPDATA=C:\Users\Charlee\AppData\Roaming
1> HOMEDRIVE=C:
1> DATASPELL_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\dataspell.vmoptions
1> GATEWAY_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\gateway.vmoptions
1> CLION_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\clion.vmoptions
1> JETBRAINSCLIENT_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\jetbrainsclient.vmoptions
1> USERNAME=Charlee
1> PROCESSOR_ARCHITEW6432=AMD64
1> EFC_20336=1
1> PROCESSOR_ARCHITECTURE=x86
1> OS=Windows_NT
1> ComSpec=C:\windows\system32\cmd.exe
1> PYCHARM_VM_OPTIONS=C:\SoftWare\ideaI-windows\2023\vmoptions\pycharm.vmoptions
1> SystemDrive=C:
1> windir=C:\windows
1> ALLUSERSPROFILE=C:\ProgramData
1> 命令行: "C:\windows\system32\cmd.exe" /c "%SYSTEMROOT%\System32\chcp.com 65001 >NUL && "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe" -G "Ninja" -DCMAKE_BUILD_TYPE:STRING="RelWithDebInfo" -DCMAKE_INSTALL_PREFIX:STRING="C:/Work/ZipTest/out/install/RelWithDebInfo" -DCMAKE_MAKE_PROGRAM="C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\Ninja\ninja.exe" "C:\Work\ZipTest" 2>&1"
1> 工作目录: C:/Work/ZipTest/out/build/RelWithDebInfo
1> [CMake] -- Configuring done
1> [CMake] -- Generating done
1> [CMake] -- Build files have been written to: C:/Work/ZipTest/out/build/RelWithDebInfo
1> 已提取 CMake 变量。
1> 已提取源文件和标头。
1> 已提取代码模型。
1> 已提取工具链配置。
1> 已提取包含路径。
1> CMake 生成完毕。
这个配置工程的步骤一定不能少,且要保证看到“CMake生成完毕”的提示。如果生成中断的话,可以在输出日志中看到出错的地方并进行修改。本质上来说,CMakeLists.txt只是个文本文件而已,要通过这一步将构建的环境准备好,生成一些缓存文件和中间文件,从而便于构建工具链识别进行下一步作业。
2.5 调试执行
在保证CMake配置工程完毕之后,就可以进行调试运行了。这一步的功能就无缝对接MSVC项目了,例如编辑代码,F7生成,F5调试,Ctrl+F5执行,F9断点,F10逐过程调试以及F11逐语句调试。不过有一点要注意,就是要选择启动项,不然可能无法运行项目。具体可以在工具栏的选择启动项下拉菜单中,如下图12所示:

我们当然要选中ZipTest.exe这个目标,不过一定要注意,只有当CMake生成完毕以后才会出现这个选项。如果没有这个选项,那就说明之前的CMake生成没有成功。
另外一个很实用的功能是,在CMake生成成功以后,可以切换到CMake目标项目。具体通过“解决资源管理器视图”的工具栏上的“在解决方案和可用视图之间切换”按钮进入,如下图13所示:

这个视图看起来有点像MSVC工程了,比文件夹视图简洁介多了。更重要的是由这个视图的右键菜单功能更实用一点,比如“设为启动项”按钮也可以实现上面的选择启动项功能。另外还有“添加”功能,与MSVC项目的“添加”功能类似,可以新建源代码文件加入到CMake工程中。不过这个功能是通过修改CMakeList.txt文件来实现的,读者可以自己试用一下。

其实笔者感觉这个CMake目标视图是想像MSVC工程一样,集成更多的常用GUI操作的功能,使得开发编程的效率更高。不过目前这些还只是半成品,比如这个“添加”功能是可以实现源代码文件的添加了,但是对应修改CMakeList.txt的内容不一定是我们想要的,关于这一点读者可以试用一段时间之后再领会。目前很多常用的IDE功能还是需要我们自己编辑CMakeList.txt文件来实现,尽管如此,已经可以帮助我们提升很大一部分开发效率了。
3. 项目案例
默认的Hello CMake案例还是太简单了,我们还是将上一篇的调用libzip压缩文件和文件夹的案例用上。项目目录如下:
ZipTest
│ main.cpp
│ CMakeLists.txt
| CMakePresets.json
main.cpp的内容如下:
#include <zip.h>#include <filesystem>
#include <fstream>
#include <iostream>using namespace std;void CompressFile2Zip(std::filesystem::path unZipFilePath,const char* relativeName, zip_t* zipArchive) {std::ifstream file(unZipFilePath, std::ios::binary);file.seekg(0, std::ios::end);size_t bufferSize = file.tellg();char* bufferData = (char*)malloc(bufferSize);file.seekg(0, std::ios::beg);file.read(bufferData, bufferSize);//第四个参数如果非0,会自动托管申请的资源,直到zip_close之前自动销毁。zip_source_t* source =zip_source_buffer(zipArchive, bufferData, bufferSize, 1);if (source) {if (zip_file_add(zipArchive, relativeName, source, ZIP_FL_OVERWRITE) < 0) {std::cerr << "Failed to add file " << unZipFilePath<< " to zip: " << zip_strerror(zipArchive) << std::endl;zip_source_free(source);}} else {std::cerr << "Failed to create zip source for " << unZipFilePath << ": "<< zip_strerror(zipArchive) << std::endl;}
}void CompressFile(std::filesystem::path unZipFilePath,std::filesystem::path zipFilePath) {int errorCode = 0;zip_t* zipArchive = zip_open(zipFilePath.generic_u8string().c_str(),ZIP_CREATE | ZIP_TRUNCATE, &errorCode);if (zipArchive) {CompressFile2Zip(unZipFilePath, unZipFilePath.filename().string().c_str(),zipArchive);errorCode = zip_close(zipArchive);if (errorCode != 0) {zip_error_t zipError;zip_error_init_with_code(&zipError, errorCode);std::cerr << zip_error_strerror(&zipError) << std::endl;zip_error_fini(&zipError);}} else {zip_error_t zipError;zip_error_init_with_code(&zipError, errorCode);std::cerr << "Failed to open output file " << zipFilePath << ": "<< zip_error_strerror(&zipError) << std::endl;zip_error_fini(&zipError);}
}void CompressDirectory2Zip(std::filesystem::path rootDirectoryPath,std::filesystem::path directoryPath,zip_t* zipArchive) {if (rootDirectoryPath != directoryPath) {if (zip_dir_add(zipArchive,std::filesystem::relative(directoryPath, rootDirectoryPath).generic_u8string().c_str(),ZIP_FL_ENC_UTF_8) < 0) {std::cerr << "Failed to add directory " << directoryPath<< " to zip: " << zip_strerror(zipArchive) << std::endl;}}for (const auto& entry : std::filesystem::directory_iterator(directoryPath)) {if (entry.is_regular_file()) {CompressFile2Zip(entry.path().generic_u8string(),std::filesystem::relative(entry.path(), rootDirectoryPath).generic_u8string().c_str(),zipArchive);} else if (entry.is_directory()) {CompressDirectory2Zip(rootDirectoryPath, entry.path().generic_u8string(),zipArchive);}}
}void CompressDirectory(std::filesystem::path directoryPath,std::filesystem::path zipFilePath) {int errorCode = 0;zip_t* zipArchive = zip_open(zipFilePath.generic_u8string().c_str(),ZIP_CREATE | ZIP_TRUNCATE, &errorCode);if (zipArchive) {CompressDirectory2Zip(directoryPath, directoryPath, zipArchive);errorCode = zip_close(zipArchive);if (errorCode != 0) {zip_error_t zipError;zip_error_init_with_code(&zipError, errorCode);std::cerr << zip_error_strerror(&zipError) << std::endl;zip_error_fini(&zipError);}} else {zip_error_t zipError;zip_error_init_with_code(&zipError, errorCode);std::cerr << "Failed to open output file " << zipFilePath << ": "<< zip_error_strerror(&zipError) << std::endl;zip_error_fini(&zipError);}
}int main() {//压缩文件// CompressFile("C:/Data/Builder/Demo/view.tmp",// "C:/Data/Builder/Demo/view.zip");//压缩文件夹CompressDirectory("C:/Data/Builder/Demo", "C:/Data/Builder/Demo.zip");return 0;
}
CMakeLists.txt的内容如下:
# 输出cmake版本提示
message(STATUS "The CMAKE_VERSION is ${CMAKE_VERSION}.")# cmake的最低版本要求
cmake_minimum_required (VERSION 3.9)# 工程名称、版本、语言
project (ZipTest VERSION 0.1 LANGUAGES CXX)# cpp17支持
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 查找依赖库
find_package(libzip REQUIRED)# 将源代码添加到此项目的可执行文件。
add_executable (${PROJECT_NAME} "main.cpp")# 链接依赖库
target_link_libraries(${PROJECT_NAME} PRIVATE libzip::zip)
CMakePresets.json的内容如下:
{"version": 2,"configurePresets": [{"name": "linux-default","displayName": "Linux Debug","description": "面向适用于 Linux 的 Windows 子系统(WSL)或远程 Linux 系统。","generator": "Ninja","binaryDir": "${sourceDir}/out/build/${presetName}","cacheVariables": {"CMAKE_BUILD_TYPE": "Debug","CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"},"vendor": {"microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Linux" ] },"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" }}},{"name": "windows-default","displayName": "Windows x64 Debug","description": "面向具有 Visual Studio 开发环境的 Windows。","generator": "Ninja","binaryDir": "${sourceDir}/out/build/${presetName}","architecture": {"value": "x64","strategy": "external"},"cacheVariables": {"CMAKE_BUILD_TYPE": "Debug","CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"},"vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } }},{"name": "RelWithDebInfo","displayName": "Windows x64 RelWithDebInfo Shared Library","description": "面向具有 Visual Studio 开发环境的 Windows。","generator": "Ninja","binaryDir": "${sourceDir}/out/build/${presetName}","architecture": {"value": "x64","strategy": "external"},"cacheVariables": {"CMAKE_BUILD_TYPE": "RelWithDebInfo","CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"},"vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } }}]
}
请务必注意,我们这里使用的是CMake比较推荐和比较新的目标链接机制来引入libzip库,关于这一点请务必复习上一篇博文的内容。这里要说的是如果find_package(libzip REQUIRED)失败,那么可能需要指定依赖库的安装目录,具体是在CMakePresets.json文件中的RelWithDebInfo配置中增加CMAKE_PREFIX_PATH,笔者这里使用的GISBasic环境变量指向的目录。至于libzip如何构建安装?可以参考本系列之前的博文。
{"name": "RelWithDebInfo","displayName": "Windows x64 RelWithDebInfo Shared Library","description": "面向具有 Visual Studio 开发环境的 Windows。","generator": "Ninja","binaryDir": "${sourceDir}/out/build/${presetName}","architecture": {"value": "x64","strategy": "external"},"cacheVariables": {"CMAKE_BUILD_TYPE": "RelWithDebInfo","CMAKE_PREFIX_PATH": "$env{GISBasic}","CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"},"vendor": {"microsoft.com/VisualStudioSettings/CMake/1.0": {"hostOS": ["Windows"]}}
}
4. 总结
好了,使用Visual Studio 2019进行CMake项目的开发的步骤和注意事项就是以上内容了。其实笔者也很想使用Visual Studio 2022甚至更新的版本来进行CMake项目的开发,不过受限于工作的环境没有进行升级。如果有试用的读者欢迎进行留言,看看与Visual Studio 2019对比有哪些区别或者提升。
相关文章:
CMake构建学习笔记16-使用VS进行CMake项目的开发
文章目录 1. 概论2. 详论2.1 创建工程2.2 加载工程2.3 配置文件2.4 工程配置2.5 调试执行 3. 项目案例4. 总结 1. 概论 在之前的系列博文中,我们学习了如何构建第三方的依赖库,也学习了如何去组建自己的CMake项目,尤其是学习了CMake的核心配…...
数据结构中线性表的定义和特点
线性表:有n个数据特征相同的元素构成的有限序列。 特点: 除了第一个元素,最后一个元素,其余的元素都有唯一的前驱和唯一的后继。 案例引入: 一元多项式的运算: 可以将一元多项式p(x)抽象为一个有n1个系…...
【PyTorch单点知识】PyTorch中的自动混合精度(AMP)模块详解
文章目录 0. 前言1. 什么是自动混合精度?2. PyTorch AMP 模块3. 如何使用 PyTorch AMP3.1 环境准备3.2 代码实例3.3 代码解析 4. 结论 0. 前言 按照国际惯例,首先声明:本文只是我自己学习的理解,虽然参考了他人的宝贵见解及成果&a…...
数据结构 --- 哈希表
哈希表(Hash Table),也叫散列表,是一种根据关键码值(Key value)而直接进行访问的数据结构。 一、基本原理 哈希函数 哈希表通过一个特定的哈希函数,将关键码映射到表中的一个位置。这个位置通常…...
Linux相关:在阿里云下载centos系统镜像
文章目录 1、镜像站2、下载方式一2.1、第一步打开镜像站地址2.2 下载地址: https://mirrors.aliyun.com/centos/2.3、选择7版本2.4、镜像文件在isos文件夹中2.5、选择合适的版本 3、下载镜像快捷方式 1、镜像站 阿里云镜像站地址 2、下载方式一 2.1、第一步打开镜像站地址 2…...
24. 线模型对象
线模型Line渲染顶点数据 下面代码是把几何体作为线模型Line (opens new window)的参数,你会发现渲染效果是从第一个点开始到最后一个点,依次连成线。 // 线材质对象 const material new THREE.LineBasicMaterial({color: 0xff0000 //线条颜色 }); //…...
EasyExcel 快速入门
目录 一、 EasyExcel简介 官网链接: 代码链接: 二、 EasyExcel快速上手 引入依赖: 设置Excel相关注解 编写对应的监听类: 简单写入数据: 简单读取数据: 不需要使用监听器: 需要使…...
Sparse4D v1
Sparse4D: Multi-view 3D Object Detection with Sparse Spatial-Temporal Fusion Abstract 基于鸟瞰图 (BEV) 的方法最近在多视图 3D 检测任务方面取得了重大进展。与基于 BEV 的方法相比,基于稀疏的方法在性能上落后,但仍然有很多不可忽略的优点。为了…...
速盾:你知道高防 IP 和高防 CDN 的区别吗?
在当今网络安全形势日益严峻的情况下,网站的安全防护成为了企业和个人关注的焦点。高防 IP 和高防 CDN 作为两种常见的网络安全防护手段,被广泛应用于网站的安全防护中。那么,高防 IP 和高防 CDN 有什么区别呢?防护网站哪个更好呢…...
HTML和CSS网页制作成品
HTML和CSS网页制作成品 一、引言 1. 背景介绍 在当今数字化时代,网页已成为信息传递和交流的重要媒介。HTML和CSS作为网页制作的基石,对于构建美观、功能丰富的网站至关重要。本文将详细介绍如何使用HTML和CSS来制作一个网页成品。 2. 目的和重要性 …...
Ai+若依(集成easyexcel实现excel表格增强)
EasyExcel 介绍 官方地址:EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 官网 Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一…...
钻机、塔吊等大型工程设备,如何远程维护、实时采集运行数据?
在建筑和工程领域,重型设备的应用不可或缺,无论是在道路与桥梁建设、高层建筑施工,还是在风电、石油等能源项目的开发中,都会用到塔吊、钻机等大型机械工程设备。 随着数字化升级、工业4.0成为行业发展趋势,为了进一步…...
【AutoX.js】选择器 UiSelector - 查找包名
文章目录 原文:https://blog.c12th.cn/archives/38.html选择器 UiSelector - 查找包名笔记直接查找包名双层判断(推荐)查找最外层控件的子控件 最后 原文:https://blog.c12th.cn/archives/38.html 选择器 UiSelector - 查找包名 笔记 AutoX.js UiSelec…...
ERP进销存多仓库管理系统源码 带完整的安装代码包以及搭建部署教程
系统概述 ERP进销存多仓库管理系统是一款专为中小企业量身定制的集成化管理软件,它集成了采购管理、销售管理、库存管理、财务管理以及多仓库协同作业等核心模块。通过统一的平台,企业可以实时掌握商品从入库到出库的全过程,实现库存的自动化…...
数据清洗-缺失值填充-对XGBoost参数优化填充
目录 一、安装所需的python包二、采用XGboost算法进行缺失值填充2.1可直接运行代码2.2以某个缺失值数据进行实战2.2.1 代码运行过程截屏:2.2.2 填充后的数据截屏:三、网格搜索(Grid Search)对 XGBoost 模型的超参数进行优化原理介绍3.1 说明3.2 参数优化的原理1. 网格搜索(…...
Qt_按钮类控件
目录 1、QAbstractButton 2、设置带图标的按钮 3、设置带有快捷键的按钮 4、QRadioButtion(单选按钮) 4.1 QButtonGroup 5、QCheckBox 结语 前言: 按钮类控件是Qt中最重要的控件类型之一,该类型的控件可以通过鼠标的点击…...
union 的定义和基本结构以及用途
在 C 语言中,union(联合体) 是一种数据结构,它允许多个成员共享相同的内存空间。换句话说,联合体中的所有成员都存储在同一块内存区域,不同的成员会占用相同的内存地址,但在同一时刻只能保存一个…...
混合整数规划及其MATLAB实现
目录 引言 混合整数规划的基本模型 混合整数规划的求解方法 MATLAB中的混合整数规划实现 示例:多变量系统的混合整数规划 表格总结:混合整数规划的求解方法与适用场景 结论 引言 混合整数规划(Mixed Integer Programming, MIP…...
【数据结构】6——图1,概念
数据结构6——图1,概念 文章目录 数据结构6——图1,概念基本概念图的分类图的表示方法 基本概念 由 顶点(Vertex) 和 边(Edge) 组成的集合。顶点表示图中的点,而边表示顶点之间的连接。记为 G …...
技术周总结 09.09~09.15周日(C# WinForm WPF)
文章目录 一、09.09 周一1.1) 问题01: Windows桌面开发中,WPF和WinForm的区别和联系?联系:区别: 二、09.12 周四2.1)问题01:visual studio的相关快捷键有哪些?通用快捷键编辑导航调试窗口管理 2…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...
基于 HTTP 的单向流式通信协议SSE详解
SSE(Server-Sent Events)详解 🧠 什么是 SSE? SSE(Server-Sent Events) 是 HTML5 标准中定义的一种通信机制,它允许服务器主动将事件推送给客户端(浏览器)。与传统的 H…...
