
在 Mojo 开源仓库中使用 Bazel 构建编译器、运行代码与调试工具链【免费下载链接】mojoThe Modular Platform (includes MAX Mojo)项目地址: https://gitcode.com/GitHub_Trending/mo/mojo本文是基于 Modular 平台开源仓库Mojo 编程语言与 MAX 运行时的开发者指南重点讲解如何在开源仓库中借助 Bazel 完成 Mojo 编译器的本地构建、单文件运行、标准库测试以及kgen/kgen-translate等底层工具的使用。读完本文你将掌握build-mojo与prebuilt-mojo两种构建模式的取舍、bazelw包装脚本与常用别名、从源码构建编译器到运行任意.mojo文件的完整命令链并能准确区分哪些 monorepo 工作流在开源仓库中不可用。背景开源仓库与 Modular monorepo 的差异Mojo/docs/compiler/目录下的多数文档描述的是 Modular 内部 monorepo 的工具与工作流它们与开源仓库的用法并不完全一致。WorkingInOSRepo.md 就是专门为在开源仓库中工作的人写的“差异说明”哪些命令可以直接使用、哪些需要额外加参数、哪些目标完全不存在。本文以该文档为骨架结合仓库中的 Bazel 配置与源码给出可直接复制的实操命令。在开始之前请确保本机已具备 Bazel 工作所需的基础环境macOS 上需要较新版本的 Xcode 或 Command Line ToolsLinux 上需要对应的 C/C 工具链详见 bazel/docs/usage.md。仓库根目录的 bazelw 脚本会自动下载受支持的 Bazel 版本当前为 Bazelisk 1.27.0并在首次运行时校验 SHA 校验和因此你不需要自行安装 Bazel。使用 Bazel两种构建模式Modular 的构建系统基于 Bazel整个仓库的构建操作都通过根目录的bazelw脚本转发给 Bazel。构建 Mojo 相关目标时bazel以--configmode区分两种模式模式含义适用场景build-mojo需要时从源码构建 Mojo 编译器修改 Mojo 编译器本身Parser、LIT/KGEN Dialect、Pass 等prebuilt-mojo使用预构建的mojo包只修改 Mojo 标准库或 MAX 加速器库这两种模式的实际开关定义在仓库根目录的 .bazelrc 中build:build-mojo --//:use_prebuilt_mojo_toolchainfalse build:prebuilt-mojo --//:use_prebuilt_mojo_toolchaintrue也就是说build-mojo让 Bazel 使用仓库源码编译出的工具链prebuilt-mojo则切换到预构建工具链。需要特别注意的是prebuilt-mojo模式下 Bazel 会自动下载当前 nightly 版本的 mojo而不是你机器上全局安装的版本因此测试结果可能与本地环境略有差异。从源码构建 Mojo 编译器耗时较长如果只是修改标准库代码使用prebuilt-mojo会快得多bazel/docs/usage.md 对此有明确建议。从源码结构看//Mojo:mojo只是一个指向 Mojo/tools/mojo/BUILD.bazel 中mojo-full目标的别名见 Mojo/BUILD.bazel该二进制打包了mojo驱动及其全部子命令build、run、debug、doc、format、precompile、repl、demangle等由driver_option_tablegen为每个子命令生成选项表并链接了mojo//:std标准库依赖。固化构建配置local.bazelrc每次都敲--configbuild-mojo很啰嗦。可以在仓库根目录创建一个local.bazelrc该文件已被.gitignore忽略不会污染仓库build --configbuild-mojo这样后续所有bazel命令都会自动带上该配置。注意 .bazelrc 在文件末尾通过try-import %workspace%/local.bazelrc引入本地配置因此本地配置可以覆盖默认值。Bazel 别名速查Mojo 编译器文档中大量使用以下别名指代常见 Bazel 命令其中REPO_PATH是本地仓库根目录的绝对路径别名等价命令bbREPO_PATH/bazelw buildbrREPO_PATH/bazelw runbtREPO_PATH/bazelw test即使你不定义这些别名记住它们也有助于阅读后续的编译器开发文档如 Passes and IR 相关章节。构建与运行的三个核心命令1. 构建 Mojo 编译器与标准库./bazelw build --configbuild-mojo //Mojo:mojo该命令会从源码编译 Mojo 编译器及标准库产出物位于bazel-bin目录。//Mojo:mojo是仓库顶层对外暴露的编译器入口目标。2. 用本地构建的编译器运行单个 Mojo 文件./bazelw run --configbuild-mojo //Mojo:mojo -- run main.mojo--之后的内容会透传给mojo可执行程序本身run main.mojo等价于直接执行mojo run main.mojo。这是验证编译器改动最直接的方式——你修改的每一行编译器代码都会反映在本次运行中。3. 构建并运行标准库测试./bazelw test --configbuild-mojo //Mojo/stdlib/...//Mojo/stdlib/...是一个递归通配目标会展开为Mojo/stdlib目录下所有可测试的 Bazel 目标。标准库的测试源码位于 Mojo/stdlib/test/其 BUILD 文件中的测试规则mojo_test、mojo_filecheck_test定义了如何编译执行这些测试mojo_test使用testing模块做断言更易调试mojo_filecheck_test则用 FileCheck 校验输出详见 bazel/docs/usage.md。配置别名后的简化形式若已在local.bazelrc中固化build-mojo并定义了bb/br/bt别名上述三条命令可简化为bb //Mojo:mojo br //Mojo:mojo -- run main.mojo bt //Mojo/stdlib/...⚠️ 重要限制本地编译器不能构建 MAX 目标[!NOTE] 你不能用本地构建的编译器去构建任何 MAX 目标请改用预构建编译器--configprebuilt-mojo。另外在提交 PR 之前务必用预构建编译器再测试一遍你的标准库改动。原因在于从源码构建的编译器对应的是仓库当前 checkout 的版本而 MAXModular Accelerated Xecution 运行时与模型服务目标依赖的是 nightly 预构建工具链的稳定行为。因此涉及 MAX 的构建一律使用--configprebuilt-mojo这也是 bazel/docs/usage.md 中推荐的标准库开发模式。使用 kgen / kgen-translate 等底层工具Mojo 还提供若干底层工具用于查看编译器生成的中间表示IR其中最有代表性的是kgen和kgen-translate。这些工具对应Mojo/tools/下的独立 Bazel 目标例如 Mojo/tools/kgen-translate/BUILD.bazel 将kgen-translate构建为一个链接了 MojoParser、LITDialect、KGENDialect、Transforms 等编译器组件的二进制。为什么需要 -I Mojo/stdlib在 monorepo 内部这些工具可以直接引用已安装的标准库而在开源仓库中标准库位于仓库内因此运行这些工具时需要显式加上-I Mojo/stdlib标志把标准库源码目录加入搜索路径。以 Passes and Intermediate Representations 中生成 LIT Dialect 的指令为例monorepo 的写法是br //Mojo/tools/kgen-translate -- -import-mojo main.mojo开源仓库的等价写法是./bazelw run //Mojo/tools/kgen-translate -- -import-mojo -I Mojo/stdlib main.mojo该命令不会为你构建标准库——-I Mojo/stdlib只是让工具能找到标准库源码进行解析。因此请先按上文“构建 Mojo 编译器与标准库”一节构建好标准库再运行本命令。命令成功后main.mojo会被解析为lit方言的 MLIR 输出。以def foo(arg: Int): pass加def main(): foo(5)为例你会看到lit.fn main()、kgen.param.constant等高层 IR 结构详见 Mojo/docs/compiler/manual/PassesAndIR.md这是理解 Mojo 编译管线Parse → LIT → KGEN → LLVM的入口。开源仓库中不支持的工作流monorepo 中存在一些在开源仓库里没有对应实现的目标与流程阅读文档时如果看到以下引用请知悉其状态名称monorepo 中的作用开源仓库中的状态start-modular.shmonorepo 环境初始化脚本无等价物不要试图寻找或运行//:install构建并安装目标创建有状态的开发环境把构建产物安装进PATH以便直接运行工具不支持。可以从构建输出目录bazel-bin手动拷贝产物到PATH中的某个目录但每次重新构建编译器后都必须手动更新这些拷贝换句话说开源仓库的推荐做法是始终通过./bazelw run //Mojo:mojo -- ...来使用你构建的编译器而不是把bazel-bin里的二进制“安装”成系统命令。下一步深入编译器内部本文覆盖了在开源仓库中构建、运行与测试 Mojo 的完整工作流。接下来可以继续阅读Mojo Compiler Walkthrough编译器整体架构总览从 Parsing/Type Checking 到 Elaboration、Lowering to LLVM 的六个阶段Mojo Compiler Dev Manual面向编译器修改者的开发手册其中 Passes and Intermediate Representations 详细讲解 LIT、KGEN、LLVM 各层 IR 与 Pass 的转换关系bazel/docs/usage.md仓库级 Bazel 使用指南涵盖//:repro一次性脚本、linter 运行//:lint、//:format以及mojo_library/mojo_binary/mojo_test等 BUILD 规则的定义方式。掌握本文的命令后你就可以在开源仓库中自由迭代 Mojo 编译器与标准库代码并通过kgen-translate观察每一次改动对中间表示的影响了。【免费下载链接】mojoThe Modular Platform (includes MAX Mojo)项目地址: https://gitcode.com/GitHub_Trending/mo/mojo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考