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…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...