MDCS仓库布局与构建链

来自MDCS wiki2
Artheru讨论 | 贡献2026年5月16日 (六) 22:00的版本 (Initial bilingual draft (auto-published))
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索


概述 / Overview

MDCS 由 7 个并列仓库组成;按依赖关系自底向上构建。本页详述各仓库职责、产物、构建顺序、引用程序集机制。

MDCS consists of 7 sibling repositories built bottom-up by dependency. This page details responsibilities, outputs, build order, and the reference-assembly mechanism.

仓库一览 / Repositories

仓库 / Repo 解决方案 / Solution 产物 / Output 角色 / Role
`D:\src\Fundamentals\` Fundamentals.sln FundamentalLib.dll, FundamentalLib2.dll, LessokajiProtect.dll, LessokajiLicencer.dll 通用类型 + IPC + 日志 + 许可
`D:\src\LessokajiWeaver\` LessokajiWeaver.sln LessokajiWeaver.Fody.dll, LessokajiWeaverUtilities.dll 编译期 IL 注入(Fody)
`D:\src\CycleGUI\` CycleGUI.sln CycleGUI.dll, libVRender.dll(C++/Vulkan), webVRender(WASM) 懒协程 UI 框架
`D:\src\M2\` M2.sln MedullaCore.dll, OfficialPlugins/*.dll 硬件抽象内核 + 一方插件(雷达 / 相机 / Cart)
`D:\src\Detour\` Detour.sln Detour.exe(.NET 4.8 GUI),DetourLite.exe(.NET 8 headless),DetourCore.dll 定位系统
`D:\src\Clumsy\` Clumsy.sln ClumsyCore.dll, ClumsyDance.dll 车载自动驾驶
`D:\src\Simple\` Simple.sln SimpleCore.dll, SimpleComposer.exe(Nancy HTTP) 车队管理

依赖图 / Dependency graph

                Fundamentals ◄────────── (everything)
                      ▲
                      │
                   CycleGUI ◄─ Detour ─── (M2, Clumsy, Simple use indirectly)
                      ▲           ▲
                      │           │
                      M2 ◄────── Clumsy ◄── Simple
                                    ▲
                                    └─── LessokajiWeaver (build-time only)

构建顺序 / Build order

自底向上 / Bottom-up:

  1. LessokajiWeaver — 构建时依赖(Fody 织入)
  2. Fundamentals — 用 Weaver
  3. CycleGUI — 用 Fundamentals;需 libVRender C++ 先构建
  4. M2 / MedullaCore — 用 Fundamentals + CycleGUI
  5. M2 / OfficialPlugins/\* — 用 MedullaCore
  6. Detour / DetourCore — 用 Fundamentals + CycleGUI
  7. Clumsy / ClumsyCoreClumsyDance
  8. Simple / SimpleCoreSimpleComposer

每个仓库独立 .sln;可单独 `dotnet build` / 在 IDE 打开。 Each repo has its own .sln; independently buildable.

引用程序集机制 / Reference-assembly mechanism

概念 / Concept

每个核心 DLL 同时产生一个 仅引用的程序集 `Ref<Name>.dll`,通过 [refasmer] 工具生成。

Each core DLL also emits a reference-only assembly (`Ref<Name>.dll`) via refasmer.

例如 `MedullaCore.dll` → `RefMedullaCore.dll`:后者只含 public/protected API 签名,没有方法体。 E.g. `MedullaCore.dll` → `RefMedullaCore.dll`: signature-only.

为什么 / Why

插件 csproj 引用 `Ref<Name>.dll`,不引用 impl DLL : Plugin csproj references the `Ref` assembly:

  • 插件构建不会拉入 Costura 织入的传递依赖(FodyWeavers.xml + LessokajiWeaver 等)。
  • 公共 API 由 Ref assembly 固定 —— `internal` 成员对插件不可见,强制良好的封装。
  • 插件 DLL 体积小、加载快。
  • No Costura transitives pulled into plugin builds.
  • Public API frozen by the Ref assembly; `internal` hidden from plugins — enforced encapsulation.
  • Smaller plugin DLLs, faster load.

生成 / Generation

每个核心 csproj 有 AfterBuild 目标调 refasmer,输出到 `<repo>/tools/Ref<Name>.dll`:

<Target Name="GenerateRefAssembly" AfterTargets="Build">
  <Exec Command="refasmer $(TargetPath) -o $(SolutionDir)tools\Ref$(AssemblyName).dll" />
</Target>

详见 `D:\src\M2\OfficialPlugins\CartActivator\CartActivator.csproj:47-54`。

更新流程 / Update flow

改动 `MedullaCore` 公共面 → 重新 build → 同时 rebuild Ref assembly → 把 两个 DLL(impl + ref)都提交到仓库。

Change `MedullaCore` public surface → build → rebuild Ref → commit both.

【注意】 插件 csproj 用旧 `Ref` 构建 不会出错,但运行时调新成员会 `MissingMethodException`。
A plugin built against the old Ref doesn't fail to compile but throws `MissingMethodException` at runtime when calling the new member.

`tools/` 目录约定 / `tools/` directory convention

每个仓库根有 `tools/` 子目录,存放 其它仓库的 Ref assembly + 二进制工具(refasmer.exe 等)。插件 csproj 通过相对 HintPath 引用 :

Each repo root has a `tools/` subdirectory containing reference assemblies from other repos + binary tools (refasmer.exe). Plugin csproj uses relative HintPaths:

<Reference Include="RefFundamentalLib">
  <HintPath>..\tools\RefFundamentalLib.dll</HintPath>
</Reference>

【发现】 `..\tools\` 是 仓库一致约定 —— 每个 MDCS 插件 csproj 都这么写。不要改成 NuGet 包;现有工具链不支持。 The `..\tools\` HintPath pattern is repo-wide. Don't try to NuGet-ify it.

Costura.Fody 胖 DLL 打包 / Fat DLL packaging

插件 / 客户端 exe 用 Costura.Fody把所有依赖打到一个 DLL 的 base64 资源里。最终客户只需要 1 个文件。 Plugins / client exes use Costura.Fody to embed all deps as base64 resources in one DLL. Customer deploys one file.

注意 :

  • 核心 DLL(MedullaCore, ClumsyCore, ...)不用 Costura。它们要被多个插件 共载,loose DLL 必要。
  • 插件 / 顶层 exe 用 Costura。简化部署。

Note: Core DLLs (MedullaCore, ClumsyCore, ...) must not use Costura — they need to be shared between plugins. Plugins / top-level exes use Costura for deployment simplicity.

LessokajiWeaver 编译期注入 / Compile-time IL injection

Fody 加上 `LessokajiWeaver.Fody.dll` 在编译后做 IL 重写。当前生效的规则 : Fody + `LessokajiWeaver.Fody.dll` rewrites IL post-compile. Active rules:

  • `[AsInitParam] / [AsUpperIO] / [AsLowerIO]` 字段 → 自动同步 DObject 的 property
  • `[ReplaceWithCompileInfo]` 字段 → 编译时戳 + git 哈希
  • `[Translatable] / [T(zh=, en=)]` 字段 → getter 按 `CultureInfo.CurrentUICulture` 分派

详见 LessokajiWeaver编译后处理工具如何使用LessokajiWeaver的多语言功能

跨平台 / Cross-platform

  • 多数仓库 .NET 6/8,部分 .NET Framework 4.8(旧 lidar driver / Detour.exe)。
  • Linux 支持 :Medulla, Detour (Lite), Clumsy, SimpleComposer 都可跑。
  • CycleGUI 的 libVRender 在 Linux 上有 build;Windows 是主战场。

仓库间集成测试 / Cross-repo integration

没有单一 mega-solution。集成测试靠: There's no monolithic solution. Integration tests rely on:

  1. 改动核心后重 build 所有受影响插件。
  2. 在仿真车 SimpleComposer 里跑完整任务序列。
  3. `D:\src\Fundamentals\Test\` 单元测试(DObject + DLog 等关键基础)。

仓库镜像 / Repo mirror

  • 内部 git:`git.lessokaji.com`(私有)。
  • 下载站:`dl.lessokaji.com`(编译产物)。
  • 认证 / 许可:`auth.lessokaji.com`。

相关页面 / See also