Panda3D 构建体系解析:cmake/macros 目录中的 CMake 宏模块
游戏开发图形学【免费下载链接】panda3dPowerful, mature open-source cross-platform game engine for Python and C, developed by Disney and CMU项目地址https://gitcode.com/gh_mirrors/pa/panda3d点击查看免费下载Panda3D 的 CMake 构建脚本把大量可复用的“构建逻辑”封装成一个个独立的.cmake模块集中放在 cmake/macros 目录中。这些模块并不是通用的第三方库而是深度依赖 Panda3D 自身变量与目录结构的内部构件从 bison/flex 解析器生成、unity build 合成源文件到 Python 绑定生成Interrogate和“元库”metalib聚合它们共同支撑起整个工程的编译、绑定与打包流程。读完本篇你将理解每个宏的输入输出、典型调用方式以及它们在 Panda3D 构建链中扮演的角色并能在 CMakeLists.txt 中定位到实际调用点。一、目录定位为什么这些模块“不可独立使用”cmake/macros/README.md 明确声明了该目录的使用边界该目录用于存放 CMake 模块这些模块在项目外使用可能是“不安全”的。这些模块可能依赖 Panda3D 特定的 CMake 变量、Panda3D 的目录结构或其他依赖关系。它们并不打算被其他项目直接 include不过你可以自由地复制或改编它们以满足自己的需要。这一点决定了本目录与 cmake/modulesFindXxx.cmake查找第三方库的本质区别macros 里的函数会读取PROJECT_VERSION、BUILD_METALIBS、IS_DIST_BUILD、PANDA_CFG_INTDIR等仅在 Panda3D 工程内定义的全局变量因此直接搬走往往无法正常工作。根 CMakeLists.txt 先通过CMAKE_MODULE_PATH把 macros 目录加入模块搜索路径再逐个include这些宏set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macros/) ... include(PackageConfig) # Defines package_option include(PerConfigOption) # Defines per_config_option include(AddBisonTarget) # Defines add_bison_target function include(AddFlexTarget) # Defines add_flex_target function include(BuildMetalib) # Defines add_component_library AND add_metalib include(CompositeSources) # Defines composite_sources function include(Python) # Defines add_python_target AND install_python_package include(Interrogate) # Defines target_interrogate AND add_python_module include(RunPzip) # Defines run_pzip function include(Versioning) # Hooks add_library to apply VERSION/SOVERSION注意加载顺序并非随意Versioning放在最后是因为它要覆盖overrideCMake 原生的add_library命令必须在所有会创建库的调用可用前完成钩子安装。下面逐一拆解各宏。二、Versioning自动为共享库打版本号cmake/macros/Versioning.cmake 通过重新定义add_library来“劫持”所有共享库的创建过程function(add_library target_name) _add_library(${target_name} ${ARGN}) get_target_property(type ${target_name} TYPE) if(type STREQUAL SHARED_LIBRARY) set_target_properties(${target_name} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) endif() endfunction(add_library)关键实现细节有三点它把真实命令改名调用的_add_libraryCMake 内部保留原名再包裹一层从而无侵入地给每个目标追加属性只有TYPE为SHARED_LIBRARY的目标才设置版本静态库/对象库不受影响主版本号VERSION取完整的PROJECT_VERSION而SOVERSION只保留主.次两个分量这符合 Linux 动态库 soname 的常见约定——小版本patch变化不需要改变 soname。PROJECT_VERSION来自根 CMakeLists.txt 中从setup.cfg解析出的版本号并通过project(Panda3D VERSION ${_version})注入保证库文件版本与 Python 包版本一致。三、AddBisonTarget / AddFlexTarget解析器生成与预编译回退Panda3D 的多个格式解析器Egg、DC 文件、VRML、X 文件等用 bison语法.yxx与 flex词法.lxx编写。AddBisonTarget.cmake 和 AddFlexTarget.cmake 封装了对应的自定义命令。用法与参数两者签名一致add_bison_target(output_cxx input_yxx [DEFINES output_h] [PREFIX prefix]) add_flex_target(output_cxx input_lxx [DEFINES output_h] [PREFIX prefix] [CASE_INSENSITIVE])DEFINES output_h让 bison 生成.h语法规则、flex 生成--header-file同时把该头文件加入输出集合list(APPEND outputs ${arg})PREFIX prefix对应 bison 的-p与 flex 的-P前缀用于避免多个解析器全局符号冲突CASE_INSENSITIVE仅 flex追加-i参数使词法匹配大小写不敏感。实际调用见各格式解析器的 CMakeLists.txtadd_bison_target(parser.cxx parser.yxx DEFINES parser.h PREFIX eggyy) add_flex_target(lexer.cxx lexer.lxx CASE_INSENSITIVE PREFIX egyy)其他调用点包括 dcparser、vrml、xfile。无 bison/flex 时的预编译回退这两个宏最实用的特性是回退机制。当HAVE_BISON/HAVE_FLEX为假时宏不会报错而是寻找同名.prebuilt文件并用cmake -E copy拷贝为最终产物if(HAVE_BISON) add_custom_command(OUTPUT ${outputs} COMMAND ${BISON_EXECUTABLE} ...) else() # 对每个输出查找 ${output}.prebuilt 并用 copy 命令替代 ... list(APPEND commands COMMAND ${CMAKE_COMMAND} -E copy ${prebuilt_file} ${output}) add_custom_command(OUTPUT ${outputs} ${commands} DEPENDS ${depends}) endif()仓库中确实提供了这些预编译产物作为兜底例如 parser.cxx.prebuilt、dcParser.cxx.prebuilt、vrmlParser.cxx.prebuilt 等共 12 个.prebuilt文件。这意味着即便构建机器未安装 bison/flex工程仍可通过预生成源码继续编译。另外AddFlexTarget.cmake在 MSVC 下还会给产物追加YY_NO_UNISTD_H1编译定义解决 flex 生成代码在 Windows 头文件缺失unistd.h的问题。四、BuildMetalib组件库与“元库”聚合BuildMetalib.cmake 是理解 Panda3D 库组织方式的核心。它定义了“库中库”metalibrary概念——metalib 自身不含独立代码而是把多个组件库的对象“摊平”flatten进一个共享库。它提供两个函数add_component_library与add_metalib。add_component_library用法类似add_library并支持关键字add_component_library(target [SYMBOL building_symbol] [SOURCES] [[NOINIT]/[INIT func [header]]])目标名若以p3开头会自动剥离前缀默认初始化函数为init_libname、头文件为config_name.hNOINIT可抑制这一默认SYMBOL类似 CMake 的DEFINE_SYMBOL只在构建库本身时定义构建链接方时不定义关键分支在BUILD_METALIBS为真时组件库被创建为OBJECT库供 metalib 用$TARGET_OBJECTS:...吸收对象并强制开启POSITION_INDEPENDENT_CODE、把INTERFACE_INCLUDE_DIRECTORIES指向组件源码目录为假时退化为普通add_library。真实调用例如 p3dcparser、p3dtoolbase。add_metalibadd_metalib(target [source1 source2] [INCLUDE header.h ...] [INIT initfunc [initheader.h] [EXPORT type name expr]] [COMPONENTS component1 ...])在 metalib 模式下add_metalib会对每个COMPONENTS组件通过$TARGET_OBJECTS:${component}直接消费其对象文件而不是链接它用生成表达式generator expression把组件的COMPILE_DEFINITIONS、INTERFACE_INCLUDE_DIRECTORIES、LINK_OPTIONS等“摊平”到 metalib并过滤掉仅指向其他组件或项目内部路径的引用若指定了INIT则基于 cmake/templates/metalib_init.cxx.in 与metalib_init.h.in自动生成一个 init 源文件依次调用各组件的初始化函数并安装对应头文件EXPORT type name expr会以extern C形式导出一个不带装饰的 C 符号返回表达式expr类型type——这是让 Python 绑定层拿到特定管线的关键。典型例子 panda/metalibs/pandagl/CMakeLists.txtadd_metalib(pandagl ${MODULE_TYPE} INCLUDE ${PANDAGL_PIPE_INCLUDE} INIT init_libpandagl pandagl.h EXPORT int get_pipe_type_pandagl ${PANDAGL_PIPE_TYPE}::get_class_type().get_index() COMPONENTS ${PANDAGL_LINK_TARGETS})而核心元库 panda/metalibs/panda/CMakeLists.txt 则把p3chan p3char p3collide ... p3tform等二十多个组件聚合进panda并按条件HAVE_AUDIO、HAVE_FREETYPE等追加组件。五、CompositeSourcesUnity Build 与合成源文件CompositeSources.cmake 实现了“合成源文件”unity build把多个.cxx拼接成单个_compositeN.cxx一次性编译以显著缩短构建时间。相关缓存变量包括CMAKE_UNITY_BUILD # 默认 ON CMAKE_UNITY_BUILD_BATCH_SIZE # 默认 30每批合成的源文件数 COMPOSITE_SOURCE_EXTENSIONS # 默认 .cxx;.mm;.c COMPOSITE_SOURCE_EXCLUSIONS # 跳过合成的目标列表CI 用composite_sources(target sources_var)的核心逻辑若 CMake ≥ 3.16直接改用原生的CMAKE_UNITY_BUILD*仅对非.cxx源文件设置SKIP_UNITY_BUILD_INCLUSION YES注释说明 3.16.2 及更早版本对多语言支持有缺陷故只允许.cxx进入原生 unity否则按扩展名分组、按BATCH_SIZE分批跳过GENERATED、HEADER_FILE_ONLY、SKIP_UNITY_BUILD_INCLUSION源文件每批通过 cmake/scripts/MakeComposite.cmake 生成target_compositeN.ext并把原始源文件标记为HEADER_FILE_ONLY仍可在 IDE 中查看但不参与编译同时打WRAP_EXCLUDE YES避免被 Interrogate 重复扫描。调用点如 contrib/src/ai/CMakeLists.txt、direct/src/interval/CMakeLists.txt。六、InterrogateC 到 Python 的绑定生成Interrogate.cmake 是 Panda3D 把 C 暴露给 Python 的关键提供target_interrogate、interrogate_sources与add_python_module三级函数。target_interrogate(target [ALL] [EXTENSIONS ...])本身不运行 interrogate只是把要扫描的源文件、扩展文件通过IGATE_SOURCES/IGATE_EXTENSIONS属性挂到目标上并记录TARGET_SRCDIR/TARGET_BINDIRinterrogate_sources(target output database language_flags)真正运行interrogate生成outfile.cxx与dbfile.in。它会按 INTERROGATE_EXCLUDE_REGEXES 过滤掉.I/.N/.c/.lxx/.yxx/_src.*等文件并自动为同名.N指令文件添加依赖add_python_module(module [lib...] [LINK ...] [IMPORT ...] [INIT ...]编排上述流程调用interrogate_module生成module_module.cxx并通过add_python_target建立 Python 模块目标。它精心处理了“把编译定义、包含路径同步传给 Interrogate使其与编译器用相同方式预处理源码”的问题包括用check_type_size(long)判断 64 位并追加-D_LP64用生成表达式抽取INTERFACE_INCLUDE_DIRECTORIES从CMAKE_CXX_FLAGS*中用正则[/-]D[ \t]*[A-Za-z0-9_]抠出-D定义。真实调用如 panda3d.core、panda3d.egg、panda3d.bullet。IMPORT让模块初始化时依赖另一个 Python 模块LINK则指定链接库与前文列出的库分离。七、PackageConfig第三方包选项与导出PackageConfig.cmake 为 Panda3D 的第三方依赖提供统一的“开关 导入目标”抽象核心是PKG::NAME接口库。package_optionpackage_option(package_name package_doc_string [DEFAULT ON | OFF] [IMPORTED_AS CMake::Imported::Target ...] [FOUND_AS find_name] [LICENSE license])未显式指定DEFAULT时普通构建默认启用所有“找到”的第三方包分发构建IS_DIST_BUILD会额外校验LICENSE若许可证不在PANDA_DIST_USE_LICENSES白名单内则强制默认关闭防止无意中违反第三方许可证——这是注释里强调的“避免意外违反第三方许可”的规则每次调用都会创建PKG::NAME INTERFACE IMPORTED GLOBAL目标即使包未找到也会建“空壳”因此下游可无条件target_link_libraries(... PKG::NAME)通过生成表达式把包包含目录对 Interrogate 隐藏强制绑定层依赖仓库内parser-inc而非系统头文件。package_status / show_packages / export_packages / export_targetspackage_status注册描述与备注show_packages汇总打印“ 已启用 / ! 启用但没找到 / - 未找到或未请求”的报告export_packages(filename)生成可包含的 CMake 文件逐包导出PKG::目标属性并手动递归展开非传递的INTERFACE_LINK_LIBRARIESexport_targets(set [NAMESPACE ...] [COMPONENT ...])生成并安装Panda3DsetTargets.cmake供下游find_package使用。八、PerConfigOption 与 RunPzip构建配置与模型打包per_config_optionPerConfigOption.cmake 的per_config_option(name help [Config1 ...])让选项“按配置”生效单配置生成器下依据CMAKE_BUILD_TYPE是否落在给定配置列表中决定option默认 ON/OFF多配置生成器下为CMAKE_CONFIGURATION_TYPES中每个配置各建一个name_CONFIG选项若该变量已被显式定义则退化为普通option。run_pzipRunPzip.cmake 的run_pzip(target source destination glob)把匹配glob的资源批量打包成 Panda3D 的.pz二进制格式。逻辑为递归 glob 出文件若host_pzip目标存在则对每个文件调用host_pzip -o dest.pz src生成.pz否则回退为copy_if_different直接拷贝最后用add_custom_target(... ALL DEPENDS ...)聚合。根 CMakeLists.txt 用它把 models 下的*.egg打包为内置模型资源。九、小结这些宏如何串成一条构建链结合 cmake/macros/README.md 的定位与 cmake/README.md 的构建入口这套宏模块在 Panda3D 中形成了一条清晰链路package_option/per_config_option先确定“要编译哪些第三方库、哪些配置项”add_bison_target/add_flex_target生成各格式解析器源码缺失工具时用.prebuilt兜底composite_sources把组件源文件 unity 合成加速编译add_component_libraryadd_metalib把组件聚合为对外共享的 metalibtarget_interrogateadd_python_module生成 Python 绑定模块Versioning在add_library层统一给共享库打上 sonamerun_pzip把内置模型打包为.pzexport_packages/export_targets则负责把可安装结果导出给下游。由于这些函数普遍依赖BUILD_METALIBS、PROJECT_VERSION、PANDA_CFG_INTDIR、IS_DIST_BUILD等 Panda3D 全局状态脱离本工程环境直接引用它们往往不可用如需移植应按 README 的建议“复制并改写”后再适配自身变量与目录结构。赞分享游戏开发图形学【免费下载链接】panda3dPowerful, mature open-source cross-platform game engine for Python and C, developed by Disney and CMU项目地址https://gitcode.com/gh_mirrors/pa/panda3d点击查看免费下载相关推荐CMake 策略 CMP0195Swift 模块在构建树中使用模块目录结构CMake 策略 CMP0195Swift 模块在构建树中使用模块目录结构 导读 CMP0195 是 CMake 4.1 引入的一项构建策略它改变了 CMa构建工具开发工具CLIF´ CMake 构建系统完全指南从旧 Make 系统迁移到模块化 CMake 构建F´ CMake 构建系统完全指南从旧 Make 系统迁移到模块化 CMake 构建 导读 F´F Prime飞行软件与嵌入式系统框架早期版本附带了一套专嵌入式系统编程3步解锁Flomo到Obsidian迁移告别笔记碎片化的完整方案3步解锁Flomo到Obsidian迁移告别笔记碎片化的完整方案 你是否曾经在Flomo中积累了数百条灵感碎片却苦于无法将它们系统化整理到Obsidian的知识管理数据集成上一篇Maccy macOS 剪贴板历史开源工具实用手册三步找回你复制过的内容下一篇Uperf Game Turbo 完整指南如何让你的安卓手机流畅如新创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

instagram-private-api 私信排名收件人响应:DirectRepositoryRankedRecipientsResponseThread 接口全解析

instagram-private-api 私信排名收件人响应:DirectRepositoryRankedRecipientsResponseThread 接口全解析

后端 【免费下载链接】instagram-private-api NodeJS Instagram private API SDK. Written in TypeScript. 项目地址: https://gitcode.com/gh_mirrors/in/instagram-private-api 点击查看 免费下载 DirectRepositoryRankedRecipientsResponseThread 是 NodeJS 版 …

2026/10/15 21:08:13 阅读更多 →
Oozie安装排障手记:Hadoop生态协调器部署实战

Oozie安装排障手记:Hadoop生态协调器部署实战

1. 项目概述:为什么Oozie安装会变成“取经路”?Oozie不是个新东西,但每次在新环境里把它跑起来,都像重新考一次运维资格证。标题里那个“九九八十一”,真不是夸张——我去年在某高校大数据实验室部署一套教学用Hadoop生…

2026/10/15 21:08:13 阅读更多 →
八数码问题的BFS实现:状态建模、去重与路径回溯

八数码问题的BFS实现:状态建模、去重与路径回溯

简介:本资源是一份面向计算机专业学生与算法初学者的C语言实践教程,聚焦八数码问题的经典求解方法——宽度优先搜索(BFS)原理与代码实现。资源以详实的DOC文档形式呈现,完整解析状态建模、节点扩展逻辑、空格移动约束&…

2026/10/15 21:07:12 阅读更多 →

最新新闻

VS2017 MFC打包部署实战:解决0xc000007b与DLL缺失问题

VS2017 MFC打包部署实战:解决0xc000007b与DLL缺失问题

1. 项目概述:为什么MFC打包部署至今仍是硬需求在某高校实验室带学生做工业控制界面开发时,我连续三年遇到同一个问题:学生写完功能完整的MFC程序,一到老师验收环节就卡在“打不开”——不是提示缺少MSVCP140.dll,就是报…

2026/10/15 22:58:24 阅读更多 →
STM32 ADC多通道采集必须用DMA的原理与实战

STM32 ADC多通道采集必须用DMA的原理与实战

简介:本资源是一份面向STM32F4系列嵌入式开发者的ADC多通道采集实战工程,聚焦模拟信号高速、低负载采集场景,特别适用于传感器阵列监测、工业数据采集等需兼顾实时性与CPU效率的应用。项目完整实现ADC多通道轮询配置、DMA自动搬运及传输完成中…

2026/10/15 22:58:24 阅读更多 →
上下文工程实战:从提示词优化到信息架构的完整指南

上下文工程实战:从提示词优化到信息架构的完整指南

1. 上下文工程到底在解决什么问题第一次听到“上下文工程”这个词,很多人会下意识觉得它只是“提示词优化”换了个马甲。但真上手做过几个基于大模型的应用之后,你会发现这两件事根本不在一个层面上。提示词优化关注的是“这一句话怎么写才让模型答得更好…

2026/10/15 22:58:24 阅读更多 →
ResNet残差连接原理与PyTorch实现详解

ResNet残差连接原理与PyTorch实现详解

1. 项目概述:为什么ResNet不是“又一个CNN”,而是深度学习的分水岭ResNet的pytorch实现与解析——这八个字背后,藏着过去十年最硬核的一次模型架构突破。我带过不少刚接触CV的新手,他们第一次看到ResNet论文里那张“50层、101层甚…

2026/10/15 22:58:24 阅读更多 →
企业数据安全防护:零信任架构与行为分析实践

企业数据安全防护:零信任架构与行为分析实践

1. 企业数据安全现状与挑战去年某跨国零售企业遭遇的内部数据泄露事件,让整个行业都倒吸一口凉气——一位离职工程师利用未及时撤销的访问权限,带走了超过200万客户的消费记录。这起事件暴露出一个残酷现实:最危险的安全威胁往往来自企业内部…

2026/10/15 22:58:23 阅读更多 →
C语言笔试算法18题:内存与指针驱动的闭环训练体系

C语言笔试算法18题:内存与指针驱动的闭环训练体系

1. 这不是题库搬运,而是一套可闭环复用的C语言算法训练体系“18个笔试考试算法 C语言”——看到这个标题,很多人第一反应是:又一个刷题合集?点开就背代码?先别急着划走。我带过几十届校招辅导班,也参与过多…

2026/10/15 22:57:23 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →