图形学图像处理【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images.项目地址https://gitcode.com/gh_mirrors/skia1/skia点击查看免费下载本篇技术指南以 infra/bots/README.recipes.md 为核心骨架系统讲解 Skia 开源仓库中基于 Chromium LUCI recipes 框架构建的持续集成CI自动化体系13 个 Recipe 模块build、checkout、docker、flavor、run、vars 等如何被 16 个正式 Recipecompile、test、perf、housekeeper 等编排成一次次的 Swarming 任务。读完本文你将理解 Skia 构建机器人Builder从拉取代码、编译产物到上传测试/性能结果的完整调用链掌握每个模块核心 API 的签名、参数与底层实现并知道如何阅读、运行与验证这套 Recipe 体系。Recipes 在 Skia 基础设施中的定位在深入 README.recipes.md 之前有必要先明确它服务的上层框架。根据 infra/bots/README.md 的说明Skia 的持续集成体系由以下几层构成Task任务通过 Swarming 在机器池中运行的最小自包含单元任务之间可以串联例如先编译测试二进制、再运行它们Job作业相关任务的集合用于圈定 DAG 的某一段例如作为 Try Job 的入口Recipes配方在 Swarming 任务内部执行具体工作的框架这正是本文的主题Isolate 文件决定 Swarming 任务触发时向机器人传输仓库的哪些部分Assets资产版本化的基础设施制品NDK、SDK、sysroot 等配套有重建/上传/下载脚本见 infra/bots/assets/。任务 DAG 的定义集中在tasks.json该文件永不手工编辑而是由 infra/bots/gen_tasks.go 依据 infra/bots/cfg.json 与 infra/bots/jobs.json 生成。任何改动这些输入后都需要重新生成$ go run infra/bots/gen_tasks.go # 重新生成 tasks.json $ go run infra/bots/gen_tasks.go --test # 一致性校验模式 # 等价形式 $ make -C infra/bots train $ make -C infra/bots testRecipe 体系的核心要素包括infra/bots/recipes.py用于运行和测试 recipes 的入口脚本recipes每种任务的入口点例如编译或运行测试recipe_modules被 recipes 共享的模块.recipe_depsrecipes 和模块可能依赖其他仓库如 depot_tools、recipe_engine的模块recipes.py会自动同步这些依赖。本文的关联文档 infra/bots/README.recipes.md 正是这套体系的自描述文档其首行注释AUTOGENERATED BY ./recipes.py test train表明它是通过 recipes 框架的训练train机制自动生成的 API 索引内容覆盖全部模块的 DEPS 依赖、类与方法签名以及所有 Recipe 及其内部函数。Recipe 模块Recipe Modules总览README.recipes.md 索引了 13 个 Recipe 模块它们构成 Skia CI 的积木库。按职责可划分为四类类别模块职责环境与变量vars、env、infra、git解析 Builder 名称、准备环境变量、定位 Go 工具链、配置 Git代码获取checkout、builder_name_schema通过 bot_update 或纯 git 拉取代码Builder 命名编解码构建与执行build、docker、run、flavor多平台编译、容器化构建、步骤执行与重试、设备抽象层结果上报gold_upload、gsutil、doxygen上传到 Gold 像素比对、GCS 存储、文档站点下面按此分类深入每个模块的源码实现。环境与变量类vars、env、infra、gitvars一切变量的源头vars模块的 SkiaVarsApi 是几乎所有 Recipe 依赖链的起点。其核心方法是setup()vars/api.py#L18负责准备变量读取 propertybuildername通过builder_name_schema.DictForBuilderName()将其解析为结构化字典builder_cfg依据builder_cfg[role]决定构建配置housekeeper角色固定使用Release其余默认Debug对应模块常量CONFIG_DEBUG/CONFIG_RELEASEWindows x86_64 会追加_x64后缀解析extra_config得到extra_tokens以SK开头的整段大写 token否则按下划线拆分根据patch_issue/patch_set/patch_ref等 property 判定is_trybot从而让下游区分 Try 构建与 CI 构建建立workdir、build_dir、cache_dir、swarming_out_dir、tmp_dir等关键目录并在default_env中注入CHROME_HEADLESS1与 depot_tools 路径。vars还提供只读属性is_linuxvars/api.py#L87通过 Builder 名称中是否含Ubuntu/Debian/Housekeeper判定、swarming_bot_id与swarming_task_idvars/api.py#L95、vars/api.py#L106后者通过执行资源脚本get_env_var.py读取 Swarming 注入的环境变量。该模块的 DEPS 依赖vars/init.py#L7覆盖bot_update、context、json、path、properties、raw_io、step等 recipe_engine 通用模块以及本仓库的builder_name_schema。env环境变量作用域env是最轻量的模块仅依赖recipe_engine/context。其 EnvApi 常被其他模块用于with self.m.env(...)临时注入环境变量例如docker模块运行容器时设置DOCKER_CONFIG。它的示例 Recipe 是 env/examples/full.py。infraGo 工具链定位infra模块InfraApi用于 CI 中运行 Go 程序如生成 tasks.json、执行 gen_tasks 相关工具。四个只读属性负责组装 Go 环境gorootinfra/api.py#L15Go 安装根目录go_bininfra/api.py#L46go可执行文件路径gopathinfra/api.py#L60GOPATH 路径go_envinfra/api.py#L50完整的 Go 环境变量字典。这些属性被 infra.py 等 Recipe 用于在git_init后执行 Go 任务。其示例 Recipe 为 infra/examples/full.py。git把 Git 加入 PATHgit模块的 GitApi 只有一个env()属性git/api.py#L10将 Git 加入 PATH。其文档字符串明确要求需要infra/git与infra/tools/git两个 CIPD 包按相对路径git安装。DEPS 仅含recipe_engine/path与env。这解释了为什么checkout模块在拉代码前要调用assert_git_is_from_cipd()——保证 CI 使用的是 CIPD 分发的受控 Git 版本。代码获取类builder_name_schema 与 checkoutbuilder_name_schemaBuilder 命名的编解码器Skia 的 Builder 名称不是随意字符串而是遵循builder_name_schema模块定义的规范见 builder_name_schema/builder_name_schema.py模块 api.py 中暴露了BUILDER_NAME_SCHEMA、BUILDER_NAME_SEP与五类角色常量BUILDER_ROLE_BUILD、BUILDER_ROLE_HOUSEKEEPER、BUILDER_ROLE_INFRA、BUILDER_ROLE_PERF、BUILDER_ROLE_TEST。模块 API 提供两个对称方法MakeBuilderName(**kwargs)api.py#L29由结构化字段生成规范名称DictForBuilderName(*args, **kwargs)api.py#L32把 Builder 名称解析回字典。vars.setup()正是通过DictForBuilderName把buildernameproperty 变成builder_cfg再推导出role、configuration、extra_tokens等下游变量——因此它是整条依赖链的第一块积木。checkout获取代码的两种方式checkout模块提供两种拉取策略CheckoutApibot_update(checkout_root, gclient_cacheNone, skip_patchFalse, override_revisionNone)checkout/api.py#L39默认策略走depot_tools的 gclient bot_update 流程。源码细节包括持久化 gclient 缓存默认指向vars.cache_dir.join(git)以repositoryproperty 作为主 solutiongot_revision_mapping记录到got_revision若存在patch_ref且未skip_patch则构造patch_refs并始终patchTrue注释说明是为避免步骤名出现误导性的 (without patch)同时download_topicsTrue以拉取同一 Gerrit topic 的所有改动返回got_revisionproperty。git(checkout_root)checkout/api.py#L26无 DEPS 的纯 git 拉取先断言 Git 来自 CIPD再git checkout到指定revision若为 trybot则fetchpatch_ref、checkout FETCH_HEAD并rebase到目标 revision。辅助成员包括default_checkout_root属性checkout/api.py#L15即cache_dir/work持久化缓存签出目录与assert_git_is_from_cipd()checkout/api.py#L20执行资源脚本assert_git_cipd.py失败即中止。其 DEPScheckout/init.py#L7包含了bot_update、gclient、git、tryserver等 depot_tools 模块。构建与执行类build、docker、run、flavorbuild按 Builder 分发编译策略build模块文档描述为 Build Skia for various platforms。其 BuildApi 的构造函数根据 Builder 名称关键字分发编译实现build/api.py#L21-L45Builder 名称特征编译实现产物拷贝实现含Android且不含Flutterandroid.compile_fnandroid.copy_build_products含Chromebookchromebook.compile_fnchromebook.copy_build_products含EMCC且含PathKitpathkit.compile_fnpathkit.copy_build_products含EMCC其余canvaskit.compile_fncanvaskit.copy_build_products含CMakecmake.compile_fncmake.copy_build_products含Dockerdocker.compile_fndocker.copy_build_products其他默认default.compile_fndefault.copy_build_products对应子模块文件位于 build/ 目录android.py、canvaskit.py、chromebook.py、cmake.py、default.py、docker.py、pathkit.py。公开方法有两个__call__(checkout_root, out_dir)build/api.py#L47Compile the code调用分发得到的compile_fncopy_build_products(out_dir, dst)build/api.py#L51Copy selected build products to dst调用分发得到的copy_fn。该模块的 DEPSbuild/init.py#L7同时依赖 depot_tools 的gclient、recipe_engine 的context/file/path/step以及本仓库的docker、env、infra、run、vars——可以看出它是编译类 Recipecompile、sync_and_compile的核心。docker容器化构建的胶水层docker模块DockerApi让 Recipe 在 Docker 容器内运行脚本服务于perf_pathkit、test_canvaskit、test_lottie_web、test_pathkit等 Web/WASM 相关 Recipe。两个挂载常量MOUNT_SRC /SRC、MOUNT_OUT /OUT对应方法mount_src()与mount_out()docker/api.py#L24、docker/api.py#L27。核心方法是run(...)docker/api.py#L32签名参数含义参数说明name步骤名docker_image使用的镜像src_dir/out_dir源码与输出目录宿主侧script容器内要执行的脚本默认要求位于start_dirargs/docker_args传给脚本 / 附加给docker run的参数copies需预先拷入的{src, dst}文件列表recursive_read需要递归chmod ar的目录attempts失败重试次数match_directory_structure为 True 时保持目录结构挂载否则分别挂到/SRC、/OUT实现细节运行前先以get_uid_gid.py取得 uid/gid对out_dir显式chmod 777、对src_dir非递归chmod 755、对脚本chmod 0755并处理copies拷贝与recursive_read随后构造命令docker run --shm-size2gb --rm --user uid:gid --mount typebind,...并设置DOCKER_CONFIG/home/chrome-bot/.docker最后通过run.with_retry按attempts重试。该模块的 DEPSdocker/init.py#L8为file、path、raw_io、step、env、run。run步骤执行的统一出口run模块SkiaStepApi是所有 Recipe 执行命令的统一封装DEPS 为file、path、properties、step、env、vars。核心方法__call__(steptype, name, abort_on_failureTrue, fail_build_on_failureTrue, **kwargs)run/api.py#L69在vars.default_env环境下执行步骤失败时若fail_build_on_failureTrue则记录到_failed列表但不一定中止keep going but mark the build status failedabort_on_failureTrue才立即抛出。对应的check_failure()run/api.py#L25在阶段末尾统一抛出StepFailure列出所有失败步骤。with_retry(steptype, name, attempts, between_attempts_fnNone, ...)run/api.py#L81带重试的执行重试步骤名追加 (attempt N)成功后回滚之前记录的失败del self._failed[-attempt:]between_attempts_fn可在重试间隙执行清理。run_once(fn, *args, **kwargs)run/api.py#L35按函数名去重保证某操作在整个 Recipe 生命周期只执行一次如只做一次的清理。asset_version(asset_name, skia_dir, test_dataNone)run/api.py#L54读取infra/bots/assets/asset_name/VERSION文件内容测试时可用 propertytest_asset_name_version或默认值TEST_DEFAULT_ASSET_VERSION 42覆盖。flavor.install()正是靠它获取 skimage/skp/lottie-samples/svg/text_blob_traces 的版本号。便捷函数readfile(filename)、writefile(filename, contents)run/api.py#L40、run/api.py#L45、rmtree(path)run/api.py#L50以及只读属性failed_stepsrun/api.py#L31。flavor跨设备抽象层flavor模块是 Skia CI 中最能体现多平台支持力度的模块。其文档说明模块方法定义高层操作每种 flavor 对应一个DefaultFlavor子类可按平台覆盖——例如AndroidFlavor会重写主机与 Android 设备间的文件拷贝以及step通过 ADB 执行命令。支持的平台由 flavor/api.py#L38-L51 的判定函数给出is_android、is_chromebook、is_ios、is_valgrind分别看extra_tokens或builder_cfg[os]中的关键字。SkiaFlavorApi 的方法族get_flavor(vars_api, app_name)flavor/api.py#L55按 Builder 返回对应的 flavor 工具对象ChromebookFlavor、AndroidFlavor、iOSFlavor、ValgrindFlavor或DefaultFlavor对应子模块在 flavor/ 下android.py、chromebook.py、default.py、ios.py、valgrind.py。setup(app_name)flavor/api.py#L68初始化 flavor 对象暴露device_dirs/host_dirs。step(name, cmd, **kwargs)flavor/api.py#L74与device_path_join(*args)flavor/api.py#L77设备上执行命令与拼接路径。文件传输族copy_directory_contents_to_device/copy_directory_contents_to_host/copy_file_to_deviceflavor/api.py#L80-L86、create_clean_host_dir/create_clean_device_dirflavor/api.py#L89、flavor/api.py#L92、read_file_on_device/remove_file_on_deviceflavor/api.py#L95、flavor/api.py#L98。install(skpsFalse, imagesFalse, lottiesFalse, svgsFalse, resourcesFalse, texttracesFalse)flavor/api.py#L101按需把测试资产SKP 回放文件、测试图片、Lottie 动画、SVG、文本轨迹、resources 目录安装到设备。每个资产通过版本文件SKP_VERSION、SK_IMAGE_VERSION、LOTTIE_VERSION、SVG_VERSION、TEXTTRACES_VERSION见 flavor/api.py#L30-L34与设备端已装版本比对仅当版本不一致时才重新拷贝_copy_dir逻辑flavor/api.py#L125-L144设备端无版本文件则视为VERSION_NONE -1。cleanup_steps()flavor/api.py#L122委托给 flavor 对象的清理步骤如 Android 的 ADB 清理。其 DEPSflavor/init.py#L7覆盖context、file、json、path、platform、raw_io、step及本仓库env、run、vars。test、perf、perf_skottietrace等 Recipe 的 DEPS 都依赖它。结果上报类gold_upload、gsutil、doxygengold_upload像素比对结果上报gold_upload模块GoldUploadApi用于把测试生成的图像上传到 Skia Gold像素差异比对服务。唯一公开方法upload()gold_upload/api.py#L12注释明确Attempt to upload files to Gold且前置条件是vars与flavor模块已完成 setup。其 DEPSgold_upload/init.py#L7包含context、file、json、platform、properties、step、time以及本仓库的flavor、gsutil、run、vars——其中gsutil用于实际把数据写入 GCS。gsutilGCS 上传/下载封装gsutil模块GSUtilApi封装 Google Cloud Storage 操作其注释指出假定 PATH 上存在gsutil可执行文件且主要用于 Linux/Mac上传到 GCS 仅在这两类宿主上进行。两个方法__call__(step_name, *args)gsutil/api.py#L11以给定参数运行 gsutilcp(name, src, dst, extra_gsutil_argsNone, extra_argsNone, multithreadFalse)gsutil/api.py#L20上传或下载文件。参数含义name用于步骤名src/dst为本地绝对路径或gs://...路径extra_gsutil_args追加在cp命令之前extra_args追加在cp之后例如-Z表示上传后用 gzip 压缩、下载前解压multithreadTrue时使用gsutil -m并发拷贝如gsutil -m cp foo* gs://bar/dir。失败会自动重试多次。该模块被gold_upload、upload_dm_results等用于把产物送抵 GCS。doxygenAPI 文档生成与发布doxygen模块DoxygenApi只有一个方法generate_and_upload(skia_dir)doxygen/api.py#L10用于生成 Doxygen 文档并上传。它被housekeeperRecipe 调用DEPS 仅context、step、run非常轻量。RecipesCI 任务入口全景README.recipes.md 索引了 29 个 Recipe 条目16 个正式 Recipe 13 个examples/full示例 Recipe。每个 Recipe 以RunSteps(api)为入口配合若干辅助函数。按职能分组如下。编译类compile、sync_and_compilecompile核心编译 RecipeRunStepscompile.py#L26内部按流程调用checkout、build与run/varsDEPScompile.py#L11包含context、file、json、path、platform、properties、step及build、checkout、run、vars。sync_and_compile在 compile 基础上增加depot_tools/gitiles依赖sync_and_compile.py#L10适用于需要同步特定 Git 引用后再编译的场景RunSteps位于 sync_and_compile.py#L27。测试类test、test_canvaskit、test_lottie_web、test_pathkittest运行 DMSkia 的测试驱动程序的 Recipe。RunStepstest.py#L136与test_stepstest.py#L30注释 Run the DM test共同完成安装 flavor 资产、执行 DM、必要时上传 Gold。DEPS 包含env、flavor、gold_upload、run、vars等test.py#L13。test_canvaskit/test_lottie_web/test_pathkitWeb/WASM 测试三件套RunSteps分别在 test_canvaskit.py#L28、test_lottie_web.py#L29、test_pathkit.py#L29。三者 DEPS 结构一致test_canvaskit.py#L9、test_lottie_web.py#L9、test_pathkit.py#L9file、path、properties、step加checkout、docker、env、flavor、gold_upload、infra、run、vars——即先 checkout再在 Docker 容器中构建/测试结果上 Gold的流水线。性能类perf、perf_pathkit、perf_skottietrace、perf_skottiewasm_lottiewebperf运行 Skia 基准测试nanobench的 Recipe。perf_stepsperf.py#L31注释 Run Skia benchmarks与RunStepsperf.py#L104配合执行。DEPS 最重perf.py#L15file、json、path、platform、properties、raw_io、step、time加env、flavor、run、vars。perf_pathkitPathKitWASM 路径工具库性能测试RunStepsperf_pathkit.py#L27DEPS 含docker、infraperf_pathkit.py#L9。perf_skottietrace对 Lottie 文件开启 tracing 运行 DM 并解析输出。其perf_stepsperf_skottietrace.py#L37负责执行get_trace_match(lottie_filename, is_android)perf_skottietrace.py#L147返回匹配指定 Lottie 文件的 DM 正则parse_trace(trace_json, lottie_filename, api)perf_skottietrace.py#L162解析 trace JSON。文档对返回结构给出了明确示例{ frame_max_us: 100, frame_min_us: 90, frame_avg_us: 95, }其中单帧时间 seek 时间 render 时间且首次 seek 被忽略因为那是构造调用。RunSteps位于 perf_skottietrace.py#L191DEPS 见 perf_skottietrace.py#L17。perf_skottiewasm_lottiewebSkottie WASM 与 Lottie Web 渲染器的性能对比测试。RunStepsperf_skottiewasm_lottieweb.py#L85与parse_trace(trace_json, lottie_filename, api, renderer)perf_skottiewasm_lottieweb.py#L206同样产出frame_max_us/frame_min_us/frame_avg_us结构DEPS 见 perf_skottiewasm_lottieweb.py#L14。上传类upload_buildstats_results、upload_dm_results、upload_nano_resultsupload_dm_results把 DM 测试结果上传RunStepsupload_dm_results.py#L29依赖gsutil完成 GCS 传输upload_dm_results.py#L13。upload_nano_results上传 nanobench 性能结果RunStepsupload_nano_results.py#L21。upload_buildstats_results上传构建体积统计结果RunStepsupload_buildstats_results.py#L21。其他housekeeper、infra、compute_buildstatshousekeeper日常维护任务Doxygen 文档生成等RunStepshousekeeper.py#L24依赖checkout、doxygen、run、varshousekeeper.py#L13。infra基础设施维护任务RunStepsinfra.py#L28在git_init(repo_root, env)infra.py#L20初始化仓库后运行 Go 工具DEPS 为infra、vars及context、path、properties、stepinfra.py#L10。compute_buildstats计算并汇报构建体积。内部函数族compute_buildstats.py#L30-L265针对不同产物形态分析analyze_web_filecompute_buildstats.py#L139、analyze_cpp_libcompute_buildstats.py#L166、analyze_flutter_libcompute_buildstats.py#L194、analyze_wasm_filecompute_buildstats.py#L233以及keys_and_propscompute_buildstats.py#L115与make_treemapcompute_buildstats.py#L265。配套的分析脚本位于 infra/bots/buildstats/buildstats_cpp.py、buildstats_web.py、buildstats_wasm.py、buildstats_flutter.py、make_treemap.py。examples/full每个模块的活文档README.recipes.md 为每个 Recipe 模块都收录了一个examples/full示例 Recipe它们是阅读模块 API 的最佳活文档示例 Recipe位置演示内容build:examples/fullrecipe_modules/build/examples/full.py调用 build API 编译并拷贝产物builder_name_schema:examples/fullrecipe_modules/builder_name_schema/examples/full.pyBuilder 名称编解码往返checkout:examples/fullrecipe_modules/checkout/examples/full.pybot_update / git 两种签出docker:examples/fullrecipe_modules/docker/examples/full.pyDocker 容器内运行脚本doxygen:examples/fullrecipe_modules/doxygen/examples/full.py文档生成env:examples/fullrecipe_modules/env/examples/full.py环境变量注入flavor:examples/fullrecipe_modules/flavor/examples/full.py设备抽象操作含test_exceptionsfull.py#L17异常路径测试git:examples/fullrecipe_modules/git/examples/full.pyGit 环境gold_upload:examples/fullrecipe_modules/gold_upload/examples/full.pyGold 上传gsutil:examples/fullrecipe_modules/gsutil/examples/full.pyGCS 拷贝infra:examples/fullrecipe_modules/infra/examples/full.pyGo 环境run:examples/fullrecipe_modules/run/examples/full.py步骤执行含myfunc演示run_oncevars:examples/fullrecipe_modules/vars/examples/full.py变量初始化这些示例与各 Recipe 的.expected/*.json期望文件如 recipes/test.expected/共同构成 recipes 的可测试性recipes 框架的模拟simulation测试机制会执行示例 Recipe、产出步骤日志并与期望 JSON 比对保证任何对模块或 Recipe 的改动都不会静默破坏 CI 流程。如何运行与验证这套 Recipe 体系结合 infra/bots/README.md 与 README.recipes.md 首行注释实际工作流如下训练train修改了任何 recipe 或 recipe_module 后运行$ ./infra/bots/recipes.py test train它会重新生成 infra/bots/README.recipes.md即本文主题文档以及各.expected期望文件使 API 文档与实现保持同步。测试test运行$ ./infra/bots/recipes.py test执行全部模拟测试比对步骤输出与期望文件。本地运行单个 Recipe使用 infra/bots/run_recipe.py 配合 property 参数如buildername、repository、revision、patch_ref等在本地回放某个 Recipe适合调试新任务编排。生成任务 DAG改动 infra/bots/jobs.json、infra/bots/cfg.json 或 assets 后运行go run infra/bots/gen_tasks.go或make -C infra/bots train重新生成tasks.json并可用--test做一致性校验。结语从 infra/bots/README.recipes.md 这张自动生成的地图出发可以完整还原 Skia CI 的运转逻辑vars解析 Builder 名称并准备环境 →checkout拉取代码 →build按平台分发编译 →flavor把产物与测试资产部署到设备 →test/perf运行 DM 与 nanobench →gold_upload/gsutil把图像、性能与体积数据送往 Gold/GCSWeb 相关任务则通过docker模块在容器中完成。这套模块化、可模拟测试的设计使得 Skia 在多平台Android、Chromebook、iOS、Linux、Windows、WASM上的海量构建与测试任务能够在一个统一框架下稳定演进。对于想要阅读或扩展 Skia CI 的开发者建议按README.recipes.md 索引 → 对应api.py实现 → 对应examples/full.py→.expected期望文件的顺序研读即可快速上手。赞分享图形学图像处理【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images.项目地址https://gitcode.com/gh_mirrors/skia1/skia点击查看免费下载相关推荐Skia Recipes 自动化测试体系Swarming 任务中的 Recipe 本地运行与模拟测试训练指南Skia Recipes 自动化测试体系Swarming 任务中的 Recipe 本地运行与模拟测试训练指南 Skia 的持续集成CI自动化测试全部由一套图形学Skia Recipe Modules 开发指南理解 Skia 自动化测试的模块化 Recipe 体系Skia Recipe Modules 开发指南理解 Skia 自动化测试的模块化 Recipe 体系 导读 本文聚焦于 Skia 仓库中 infra/bot图形学Skia 自动化测试的 Recipe 体系详解模块 API 参考与 CI 实战指南Skia 自动化测试的 Recipe 体系详解模块 API 参考与 CI 实战指南 导读 infra/bots/README.recipes.md 是 Ski图形学上一篇RxBinding源码中的设计模式观察者模式的最佳实践下一篇3分钟掌握Mermaid Live Editor免费实时图表编辑器的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
深入Agent Reach体检探测机制:为什么“命令存在“不等于“渠道可用“ 深入Agent Reach体检探测机制:为什么"命令存在"不等于"渠道可用" 【免费下载链接】Agent-Reach 给你的 AI Agent 一键装上互联网能力。13 个平台(网页/GitHub/YouTube/小红书/B站/Twitter/Reddit 等)多后端路由ÿ… · 2026/9/25 4:16:46
i茅台预约脚本实战:从接口自动化到多账号调度 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 5:32:40
AI安全从目标定义开始:机器学习项目避坑指南 1. 为什么“明确目标”是AI安全的第一道防线做机器学习项目这些年,我越来越觉得,模型出问题往往不是算法不够先进,而是目标从一开始就没定清楚。你可能觉得这话有点老生常谈,但我见过太多团队在项目启动会上拍脑袋定一个“提升模型… · 2026/9/25 5:32:34
Oracle 11.2.0.4 PSU补丁安装全解析:单实例与RAC滚动 简介:面向 Oracle 数据库管理员与系统运维人员的 11.2.0.4 版本补丁集更新(PSU)压缩包,对应 2022 年 1 月发布的 p33477185 补丁,适用于 Linux x86-64 环境。该更新聚合了安全修复、性能优化与已知问题解决方案&#x… · 2026/9/25 5:32:28
Two.js 安全指南:客户端渲染库的 SVG 攻击面、CSP 加固与漏洞报告流程 图形学前端 【免费下载链接】two.js A renderer agnostic two-dimensional drawing api for the web 项目地址: https://gitcode.com/gh_mirrors/tw/two.js 点击查看 免费下载 Two.js 是一个渲染器无关的二维绘图 API,它会在浏览器中以 Canvas、SVG 或 … · 2026/9/25 5:32:22
PaddleSeg FastFCN 实战指南:JPU 联合金字塔上采样与语义编码模块的源码级解析 人工智能计算机视觉预训练 【免费下载链接】PaddleSeg Easy-to-use image segmentation library with awesome pre-trained model zoo, supporting wide-range of practical tasks in Semantic Segmentation, Interactive Segmentation, Panoptic Segmentation, Image Matting,… · 2026/9/25 5:32:22
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37