ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CMake 3.29.7 Windows版:解压配置、VSCode开发与依赖库实战全解

CMake 3.29.7 Windows版:解压配置、VSCode开发与依赖库实战全解 简介CMake是广泛使用的跨平台构建工具3.29.7版本在Windows下的官方绿色安装包免安装、免配置适合C开发者快速搭建项目构建环境。压缩包共收录2000个文件其中1157个txt文本与843个html页面txt主要包含组件说明及许可信息html则集成命令帮助、生成器表达式、CTest等主题的完整参考文档打包体量约43.63MB精简易传输。作为官方版本文件来源可靠无需运行安装程序解压即可使用下载后仅需将bin目录加入环境变量即可在命令行直接调用cmake、ctest等工具。文档覆盖从基础命令到变量、预设、文件API等内容离线查阅很方便同时能作为配置与排查构建问题的快捷手册。目前已有609人学习下载需要稳定官方工具链的Windows平台C开发者可借此快速获得可用构建环境。1. 那个 zip 包解决什么问题从下载 cmake 到真正的构建系统当你把目光停在 cmake-3.29.7-windows-x86-64.zip 这个文件名上多半正被 C/C 的构建问题夹在中间IDE 里编译一切正常换到命令行就找不到头文件或者刚装完 MinGW等着 CMake 帮你把 OpenCV 这类大工程的构建脚本生成出来。这个 zip 不是普通压缩包而是官方交付的便携版构建工具。解压即用、不写注册表、适合离线环境与团队固定版本。文章围绕这一份文件把解压、配路径、选生成器、接 VSCode、编依赖库到缓存排错讲完顺带拆掉 Windows 上最容易踩的几个坑。适合刚转 CMake 的开发者也适合想用同一套版本把 CI 和本机拉齐的老手。2. 把 cmake-3.29.7-windows-x86-64.zip 接进 Windows 命令行解压路径与生成器取舍这一章只做一件事让cmake命令在 PowerShell 和 CMD 里都能被识别并且选对生成器。CMake 本身不编译代码它负责把你的工程转化成一整套构建脚本再由 make、ninja 或 Visual Studio 去执行。3.29.7 这套 zip 包里bin目录下有 cmake.exe、ctest.exe、cpack.exe 三个可执行文件share目录放模块与模板。下面按“解压 → 环境变量 → 文件校验 → 生成器 → 最小构建”推进。2.1 解压与校验先用哈希确认文件没坏再配 PATH下载完成后第一件事不是急着解压而是校验文件完整性。Windows 下没有原生 sha256sum我用 PowerShellGet-FileHash -Algorithm SHA256 -Path D:\Downloads\cmake-3.29.7-windows-x86-64.zip把它和官网公布的标准值对一下。很多人解压后出了问题第一反应是“版本坏了”其实一半是下载断流一半是 PATH 配错。校验能帮你排除第一种可能剩下只需专心对付环境变量。解压到哪个目录有讲究。我一般用D:\tools\cmake-3.29.7-windows-x86-64保持压缩包内那层目录名方便将来和 3.30、4.x 版本并存。解压后核对这个结构D:\tools\cmake-3.29.7-windows-x86-64\ ├── bin\cmake.exe ├── bin\ctest.exe ├── bin\cpack.exe ├── share\cmake-3.29\Modules\ └── doc\cmake-3.29\注意 PATH 要指向bin而不是外层目录。设置用户级环境变量的稳妥写法如下$env:Path ;D:\tools\cmake-3.29.7-windows-x86-64\bin [Environment]::SetEnvironmentVariable(Path, $env:Path, User)第一条命令只影响当前会话第二条把新 Path 持久化到注册表的用户环境变量里。为什么不用setx因为 setx 有 1024 字符截断风险机器里如果装过 JDK、MinGW、Anaconda 多个工具链Path 往往已经接近甚至超过这个长度setx 会截掉尾部导致下次重启后某些命令凭空消失。[Environment]::SetEnvironmentVariable读写注册表不截断。改完之后必须新开一个终端执行cmake --version看到 “cmake version 3.29.7” 这一行才算通。如果输出的是其他版本说明 PATH 里还有更早安装的 CMake 排在前头——这正是“明明装了 3.29.7跑出来却是老版本”的典型现场处理方式见 2.2 多版本切换。提示解压目录里如果多套了一层文件夹或者用“解压到当前目录”后把所有文件直接摊在 D 盘根目录都会让后续引用变得难维护。保持cmake-3.29.7-windows-x86-64这一层目录名是之后能区分多个版本的前提。2.2 生成器与编译器配对MinGW、MSVC 各走各的“铁轨”CMake 生成器决定了它“生成哪一种构建系统”。Windows 上最常用三种先看表生成器配套编译器configure 命令使用场景Visual Studio 17 2022MSVCcl.execmake ..默认团队用 .sln、需要 MS 调试器MinGW MakefilesMinGW-w64 GCCcmake -G MinGW Makefiles ..轻量命令行、跨平台代码、CINinjaMSVC 或 GCCcmake -G Ninja ..增量构建快配 clang 也舒服很多人第一步就栽在这里把 MinGW Makefiles 和 MSVC 编译器混用configure 虽然能过但编译时报一堆“无法打开包括文件”。选择依据其实简单你希望用什么编译代码就选对应的生成器。如果装了 Visual Studio 2017–2022又只想用命令行那么打开“开发者 PowerShell”再运行 cmake 更省心cl 环境会被自动加载如果用的是 MSYS2 或独立 MinGW-w64选 MinGW Makefiles并且确保mingw64\bin在 PATH 里靠前。这一代 3.29.7 的另一个常见场景是系统中存在多个 CMake 版本。打开新的 PowerShell执行where.exe cmake结果里有几个路径就说明有几份 CMake 在抢。解决方式不是删文件而是把 3.29.7 的bin目录调整到 PATH 列表最前。GUI 路径是“系统设置 → 编辑环境变量 → Path”上移即可命令行方式则需要重新生成一份以它为第一个条目的用户 Path。这里还要多说一句不要混用 MSYS2 里usr/bin下的 gcc 和原生 MinGW-w64 的头文件。usr/bin下那个 gcc 是 POSIX 链接的过渡版本专门给 MSYS2 自己的包用的直接喂给 CMake 做原生 Windows 编译经常会在编译器探测阶段就失败。如果非要用 MSYS2就在它的 “MINGW64” 环境里跑 cmake才是稳定的组合。2.3 最小构建跑通从 CMakeLists.txt 到 exe 的三条命令一切配置就绪后用一个最小 C 工程验证。新建D:\tmp\demo放两个文件D:\tmp\demo ├── CMakeLists.txt └── main.cCMakeLists.txt写三行cmake_minimum_required(VERSION 3.29) project(demo C) add_executable(demo main.c)然后依次执行mkdir -p build cd build cmake -G MinGW Makefiles -DCMAKE_C_COMPILERgcc .. cmake --build . ./demo.exe第一条命令创建构建目录第二条带两个关键参数-G指定生成器-DCMAKE_C_COMPILERgcc显式告诉 CMake 用哪个 C 编译器。为什么显式指定因为 PATH 里如果同时存在 MSVC 和 GCCCMake 的编译器探测顺序不总如你预期显式传递是效率最高的解法。第三条cmake --build .是通用构建入口它读缓存里的生成器自动调用 mingw32-make 或 ninja不需要你手动敲 make。最后运行生成的 exe看到输出即链路全通。如果这里失败按“现象 → 原因”自查找不到 cmake就回头查 PATH提示“Could not find a compiler”就查 gcc 是否在 PATH 且位数正确乱码则多半是源文件编码问题Windows 下建议统一用 UTF-8 保存。这套自查习惯往后所有真实项目都会用到。也可以看一眼 build 目录里有没有CMakeCache.txt存在说明 configure 已完成之后编译失败就和 CMake 本体无关了。补充一个老工程升版本的话题CMake 升级后经常会对cmake_minimum_required(VERSION 3.2)这类老工程打印 “Compatibility with CMake 3.5 will be removed in a future version” 的提醒。这是 policy 机制在起作用不是致命错误。如果因此报错可以用cmake -DCMAKE_POLICY_VERSION_MINIMUM3.5临时兜底但更推荐顺手把最低版本提到 3.16 以上。3.29.7 完全有能力承担这个策略更新。3. 在 VSCode 里驱动 3.29.7kit 配置、状态栏按钮与双通道调试VSCode 里做 C/C 的人迟早要面对那个问题底部状态栏应该有 Configure 按钮吗按钮出不出来不是 CMake 3.29.7 决定的而是由 CMake Tools 扩展的三层状态机决定kit编译器 variant构建类型 build dir构建目录。把这台状态机拆开它就能变成你能掌控的东西。3.1 Kit 与 CMake 本体分家为什么配置文件里要写两处cmake.cmakePath指向 CMake 可执行文件Select a Kit选的是编译器两者是不同维度。很多新手只改前者不选 kitconfigure 时 CMake 会“猜测”编译器一旦猜错后续所有行为都显得很迷。推荐在工程根目录的.vscode/settings.json里锁死关键项{ cmake.cmakePath: D:\\tools\\cmake-3.29.7-windows-x86-64\\bin\\cmake.exe, cmake.generator: MinGW Makefiles, cmake.buildDirectory: ${workspaceFolder}/build }三行配置分别回答三个问题用哪份 CMake、生成什么构建系统、构建目录放哪。cmake.generator显式写出来后扩展会尽量避免自动探测和弹选择框。buildDirectory推荐固定在工程目录下避免每次打开工程跑出个新目录。设置好之后命令面板执行 “CMake: Select a Kit”会列出一批编译器。你应该能看到带 “GCC for x86_64” 字样的 kit它来自 PATH 里的 MinGW-w64。若列表为空先执行 “CMake: Scan for Kits” 重新扫描。这里有个交叉编译的特例如果做 STM32 一类嵌入式开发kit 里必须指向 arm-none-eabi-gcc 而不是本机 GCC否则 configure 阶段即使过了编译也一定会失败在 startup 文件和链接脚本上。错误信息往往莫名其妙但根因就一个kit 选错了编译器。3.2 Configure 按钮不亮或变灰三个启动条件逐一过状态栏 CMake 徽标上那个 Configure 按钮通常在你打开含 CMakeLists.txt 的文件夹后自动出现。如果不亮按顺序排查。第一个条件扩展是否扫描到了 kit。执行 “CMake: Scan for Kits” 后在输出通道里观察有没有 kit 被写入。第二个条件cmake.cmakePath是否真实存在。把 settings.json 里的路径复制到终端执行D:\tools\cmake-3.29.7-windows-x86-64\bin\cmake.exe --version如果报错就说明路径错了。此时扩展会静默回退到内置 CMake你看到的 Configure 按钮还在但它用的根本不是 3.29.7。第三个条件是否选中了有效的 variant。默认是 Release/Debug 二选一底部状态栏“当前构建类型”上点击可切换如果 variant 列表为空也要先运行一次 configure。最直接的修复手段是执行 “CMake: Delete Cache and Reconfigure”。这个命令清掉缓存并重新 configure本质就是删除 CMakeCache.txt 后再次调用 cmake。如果 Delete Cache 后按钮仍然灰着打开输出面板过滤 “CMake/Build”看最后几行日志。我见过最隐蔽的一类情形是杀毒软件把 CMake 生成编译器测试程序时的临时 exe 拦截了日志里会提示找不到生成的临时文件问题却不在编译配置。这种场景把 build 目录加进杀毒排除项即可。3.3 用 tasks 与命令行做双通道状态栏排错不如回到终端状态栏按钮解决问题快但排错不如命令行直观。我会在集成终端里手动执行一遍配置和构建把完整输出打在眼前cmake -S . -B build -G MinGW Makefiles -DCMAKE_BUILD_TYPEDebug cmake --build build --verbose-S . -B build是 CMake 3.13 以后推荐的简短语法指定源码目录为当前目录、构建目录为 build--verbose强制输出底层 gcc 调用你能看到具体是哪个源文件、哪一行编译错误。想把这套过程固化到 F5 调试流程里可以写一份.vscode/tasks.json{ version: 2.0.0, tasks: [ { label: cmake build, type: shell, command: cmake --build build --verbose, group: build, problemMatcher: [$gcc] } ] }launch.json 里的 preLaunchTask 指向这个 task就能做到“按 F5 先构建再启动调试”。参数细节在problemMatcher选$gcc会把 GCC 格式的报错解析到“问题”面板如果用 MSVC 则需要换成$msCompile否则报错无法在 IDE 里正确识别路径。这套习惯同样适用于嵌入式调试——launch.json 里配好调试器后就能逐行观察交叉编译出来的源码了。4. 用 3.29.7 编译真实依赖库OpenCV/Eigen 场景与三个必调参数空工程跑通不代表能投入真实项目。CMake 真正值钱的地方有三块找到外部依赖库、控制库与可执行程序的构建形态、把安装路径管理成闭环。这一章用 Eigen 和 OpenCV 两个典型依赖讲透前者只有头文件后者是模块多到眼花的大库正好覆盖“轻依赖”与“重依赖”两种场景。4.1 find_package 的查找机制Eigen 场景与 CMAKE_PREFIX_PATHEigen 是一个 header-only 的线性代数库。下载的 eigen-3.4.0 解压后源码里带Eigen、unsupported、cmake三个目录。在 CMakeLists.txt 里写find_package(Eigen3 3.4 REQUIRED) target_link_libraries(calc PRIVATE Eigen3::Eigen)这里用导入目标Eigen3::Eigen而不是手动 include 路径省事且不会拼错变量名。如果报 “Could not find Eigen3”原因几乎都是 CMake 不知道去哪找。find_package会沿标准前缀路径搜索prefix/include/eigen3、share/eigen3/cmake等位置第三方下载的 Eigen 往往不在标准路径里所以要用-DCMAKE_PREFIX_PATH指路cmake -S . -B build -DCMAKE_PREFIX_PATHD:/libs/eigen-3.4.0CMAKE_PREFIX_PATH本质上是一个“搜索起点清单”之后多个find_package都会共享它。而在 3.29.7 里CMake 在 find 失败时会在报错信息里列出它搜过的所有路径这是极大的排错改善——它不是只丢一句“找不到”而是告诉你它去了哪里找过你比对一下自己的路径是否在其中就能立即知道方向。如果路径里有空格配置时务必把整个-D参数用引号引起来cmake -S . -B build -DCMAKE_PREFIX_PATHD:/Program Files/eigen-3.4.0这个小坑在 Windows 路径里非常常见尤其是默认装在C:\Program Files下的库。4.2 三个必调参数CMAKE_BUILD_TYPE、BUILD_SHARED_LIBS、CMAKE_INSTALL_PREFIX第一个参数是CMAKE_BUILD_TYPE。在单值生成器MinGW Makefiles、Ninja下CMake 只能在配置阶段确定一次构建类型。设置-DCMAKE_BUILD_TYPERelease后CMake 会在编译命令里加入-O2 -DNDEBUGDebug 对应-g -O0。常见坑是不设置它导致 Release 包性能差、Debug 包没有符号。这不是 3.29.7 特有的问题但它在这版的配置概要输出中会把默认构建类型显示得更明显。第二个参数是BUILD_SHARED_LIBS。很多库工程的 CMakeLists.txt 里写add_library(foo foo.c)——不写 STATIC 或 SHARED此时 CMake 会参考全局变量BUILD_SHARED_LIBSON 生成动态库OFF 生成静态库。在 OpenCV 源码中把它设为 OFF就相当于告诉它“我只想要静态库”部署时不用带一堆 dll。但它只对遵守约定的库生效如果对某个库不放心可以在它的 CMakeCache 里找对应的WITH_*或BUILD_*开关。OpenCV 这类大工程完整配置的命令常写成下面这样我习惯在 Windows 上用 CMD 分节换行便于阅读cmake -S opencv -B build-opencv -G MinGW Makefiles ^ -DBUILD_SHARED_LIBSOFF ^ -DBUILD_EXAMPLESOFF ^ -DBUILD_LISTcore,imgproc,imgcodecs ^ -DCMAKE_BUILD_TYPERelease ^ -DCMAKE_INSTALL_PREFIXD:/local/opencv第三行CMAKE_INSTALL_PREFIX决定cmake --install的落点。这里的^是 Windows CMD 的换行符PowerShell 里要用反引号。如果不做 GUI 和视频处理-DBUILD_LISTcore,imgproc,imgcodecs能把构建规模缩得很小从不痛不痒的几小时降到几十分钟。OpenCV 的 configure 阶段非常耗时所以参数一次写全比较重要每改一个参数重配一次的成本足够让人抓狂。编译完成后安装cmake --install build-opencv --prefix D:/local/opencv--prefix可以覆盖配置期的CMAKE_INSTALL_PREFIX适合把同一份构建临时装到不同位置。安装后的目录包含include和对应的lib而这又为下一次find_package(OpenCV)提供prefix——正好接回 4.1 的闭环。4.3 CMake GUI命令行看变量累GUI 看变量清楚cmake-gui.exe就在 bin 目录里是可视化排错的最后手段。它接受源码目录与构建目录第一次 Configure 后把所有缓存变量分组列出新增变量标红。当命令行报错看不出具体是哪个变量值非法时GUI 能让你一眼看到CMAKE_PREFIX_PATH是否被正确填选。GUI 的核心价值不是做配置而是“检查现状”。它和命令行共享同一个 CMakeCache.txtGUI 里改完点 Generate缓存就更新命令行再跑就基于新缓存两个入口不存在竞争。在大型依赖库配置时我通常先用 GUI 试几个变量确认无错通过后再把相同参数转写到命令行脚本。这个“先图形后脚本”的流程比抄网上一段不知背景的命令行要靠谱得多。GUI 的 File 菜单里有 “Delete Cache”对应命令行的--fresh正好接上最后一章的缓存管理主题。5. 避坑清单cmake-3.29.7-windows-x86-64.zip 在 Windows 上的 6 个翻车姿势这一章专门收坑。每一条都是实际的“现象 → 原因 → 解决”三段式可当速查表用。5.1 cmake --version 显示的不是 3.29.7或者提示找不到命令现象刚配置完 PATH新开终端里跑cmake --version要么提示“不是内部或外部命令”要么显示一个更老的版本号。原因前者多半是 PATH 指到了解压根目录而没指到bin子目录后者是有其他 CMake 安装路径排在 3.29.7 前面。解决先看一眼 PATH 里的具体条目保证D:\tools\cmake-3.29.7-windows-x86-64\bin存在且排在最前。随后重开终端再不行就用where.exe cmake查看实际命中顺序。容易忽视的一点在 PowerShell 里改了环境变量之后当前窗口不会自动重载必须新开标签页。5.2 CMake Error at CMakeDetermineCompilerId.cmake:9编译器探测失败现象configure 阶段报错指向Modules/CMakeDetermineCompilerId.cmake:9有时附带 “CMAKE_C_COMPILER not set”。原因CMake 尝试编译编译器识别程序时失败通常是 gcc/cl 不在 PATH或 PATH 里的 gcc 来自 MSYS2 的usr/bin。那个路径下的是 POSIX 环境链接的 GCC专为 MSYS2 自身准备的不适合直接喂给 CMake 做原生 Windows 编译。解决确保 PATH 里mingw64/bin在usr/bin前面并在 configure 命令里显式给-DCMAKE_C_COMPILERgcc -DCMAKE_CXX_COMPILERg。若用 MSYS2更稳的组合是进它的 “MINGW64” 环境里跑而不是在纯 CMD 里调它的 gcc。凡是 CMakeDetermineCompilerId 报错九成不是 CMake 问题是编译器环境不干净。5.3 解压时提示文件损坏或 zip 出现伪加密需要密码现象7-Zip 打开 cmake-3.29.7-windows-x86-64.zip 时弹密码框一些精简版解压工具直接报错崩溃。原因一部分中转平台会在 zip 头里把加密位误置为“加密”但数据并未加密也就是常说的“zip 伪加密”另一种则是真的下载不完整。解决先用Get-FileHash -Algorithm SHA256计算下载文件的哈希和官网值对比不一致就是下载坏了哈希一致仍提示密码则换用支持“移除伪加密标志”的工具比如 7-Zip 里打开压缩包后在文件上右键清除加密标志再解压。它不影响最终解压出的 cmake.exe但这关会拦住不少第一次下载的人不值得在上面耗太久。5.4 Ninja 报 multiple rules generate而 CMake 3.29.7 以前能过现象使用 Ninja 生成器时构建报build.ninja: multiple rules generate build/foo.o。原因两个不同 target 编译同一源文件且所有目标都指向同一个 object 路径。Ninja 把路径作为 object 的唯一键不允许一个路径被重复生成Make 系生成器因为目录规则不同有时能混过去。3.29 对 Ninja 的依赖跟踪更严格旧版掩盖的问题更容易暴露。解决给两个 target 设置不同的OBJECT_OUTPUT_DIRECTORY或错开源文件路径或避免同名源文件被两个 target 引用。同时建议把RUNTIME_OUTPUT_DIRECTORY与ARCHIVE_OUTPUT_DIRECTORY分开确保 exe 和 lib 不落到同一路径。统一落到build\bin与build\lib两个目录是常见做法。这种报错其实是好事尽早暴露依赖冲突。5.5 Qt5 的 qt5config.cmake:9 报错编译器不匹配的连锁反应现象工程里写了find_package(Qt5 COMPONENTS Core Gui Widgets)报错指向QT_DIR/5.9.4/msvc2017_64/lib/cmake/Qt5/Qt5Config.cmake:9附近。原因Qt5 的 CMake 配置文件内部会用CMAKE_CXX_COMPILER_ID与“编译 Qt 时使用的编译器”比对不一致时直接抛错。你用的是 MinGW却引进了 MSVC 版 Qt或者反之。解决要么换用 MinGW 版 Qt 包要么整个工程改用 MSVC 开发者命令行重新 configure 并清缓存。这是典型的“编译器与三方库 ABI 不匹配”不要试图手工改Qt5Config.cmake该改的是生成器和编译器选择。同一条经验适用于 OpenCV——库用什么编译器编的你的 target 最好也用同一系列编译器否则链接期会出现一堆 undefined reference。5.6 VSCode 里报 CMAKE_TOOLCHAIN_FILE not found或找不到 vcpkg 的库现象VSCode 状态栏 configure 失败日志里有 “CMAKE_TOOLCHAIN_FILE: path does not exist” 或 “Could not find a package configuration file”。原因vcpkg 这类包管理器通过 toolchain 文件注入依赖路径若cmake.cmakeArgs或configureSettings里的绝对路径写错或VCPKG_ROOT没设CMake 就拿不到依赖。解决在集成终端执行echo $env:VCPKG_ROOT检查变量在.vscode/settings.json的cmake.configureSettings里加cmake.configureSettings: { CMAKE_TOOLCHAIN_FILE: D:/vcpkg/scripts/buildsystems/vcpkg.cmake }改完后执行一次 “CMake: Delete Cache and Reconfigure”。隐藏点在于斜杠方向Windows 原生路径里 CMake 一般接受正斜杠写成D:/vcpkg/比D:\vcpkg\少很多转义问题。6. 把缓存与干净重建管成肌肉记忆3.29.7 的 --fresh 与多构建目录最后讲一个能救命的习惯如何让 CMake 忘记旧状态。CMake 的缓存文件叫CMakeCache.txt它记录 configure 阶段的所有答案生成器、编译器、开关值。当你改了编译器、换了生成器、或把某个-D参数删掉时新参数未必能覆盖旧缓存里的答案——CMake 对缓存变量的处理是“已有缓存值时不再重新计算”这就是“我改了变量却总不生效”的根源。3.29.7 在命令行里提供干净解法cmake --fresh -S . -B build--fresh在本次配置前删除缓存与 CMakeFiles 目录等于把这个 build 目录重置回裸状态。与手动删 build 的差别在于你不需要离开当前命令行还可以继续使用同一组-D参数。不过它不会清掉你自己放在 build 目录里的杂文件所以更彻底的做法仍是偶尔手动删整个目录。我的模板流程固定是一条三条rm -rf build cmake -S . -B build -G MinGW Makefiles -DCMAKE_BUILD_TYPERelease cmake --build build --config Release这组命令保证每一次都是全新配置、全新编译不在旧缓存上打补丁。日常同时需要 Debug 与 Release 时我会固定建build-debug、build-release两个目录把构建类型分别锁死互不干扰。要快速查看当前缓存的某个变量值用cmake -LA build | findstr CMAKE_BUILD_TYPE-LA参数会列出所有缓存变量并附带说明配合 findstr 做过滤排查参数是否真正写入缓存非常高效。这套习惯对 3.29.7 和以后任何版本都适用缓存不是黑匣子而是你可以随时读写的决策记录。学会在 configure 失败时先读 CMakeCache.txt再谈调参也是我从一次次“凭感觉打 -D 参数”的翻车里总结出来的固定动作希望帮到你。本文还有配套的精品资源点击获取
返回列表