macro_build

SKILL.md

仓颉宏包编译构建 Skill

1. 宏包编译规则

1.1 包规则

  • 宏须在 macro package 声明的包中
  • 宏包中仅宏定义可为 public;其他声明为包内部可见
  • 宏包可以重新导出宏包和非宏包的符号。非宏包不能重新导出宏包符号
  • 宏定义和调用在不同包中

2. 使用 cjc 编译

宏包须先编译,使用 --compile-macro 标志,然后编译调用包并链接宏包。

2.1 基本编译流程

# 步骤 1:编译宏包
cjc macros/m.cj --compile-macro --output-dir ./target

# 步骤 2:编译调用包并链接宏包
cjc src/demo.cj -o demo --import-path ./target

2.2 多模块场景

当宏包依赖其他非宏包时,须按依赖顺序编译:

cjc A.cj --compile-macro                    # 编译宏包
cjc B.cj --output-type=dylib -o libB.so     # 编译依赖库(Linux)
cjc C.cj --compile-macro -L. -lB            # 编译带依赖的宏包
cjc main.cj -o main -L. -lB                 # 编译主程序

2.3 不同平台的注意事项

平台 动态库扩展名 示例
Linux .so cjc B.cj --output-type=dylib -o libB.so
macOS .dylib cjc B.cj --output-type=dylib -o libB.dylib
Windows .dll cjc B.cj --output-type=dylib -o B.dll

3. 使用 cjpm 构建(推荐)

3.1 项目结构

my_project/
├── cjpm.toml              # 主项目配置
├── src/
│   └── main.cj            # 调用宏的代码
└── macros/                 # 宏模块
    ├── cjpm.toml           # 宏模块配置
    └── src/
        └── my_macros.cj    # 宏定义

3.2 宏模块 cjpm.toml

宏模块的 cjpm.toml 必须设置 compile-option = "--compile-macro"

[package]
cjc-version = "0.55.3"
name = "macros"
version = "1.0.0"
output-type = "static"
compile-option = "--compile-macro"

3.3 主项目 cjpm.toml

在主项目 cjpm.toml 中以本地路径依赖方式引用宏模块:

[package]
cjc-version = "0.55.3"
name = "my_project"
version = "1.0.0"
output-type = "executable"

[dependencies]
macros = { path = "./macros" }

3.4 构建与运行

cjpm build      # 自动按依赖顺序编译宏包和主包
cjpm run        # 构建并运行
cjpm test       # 运行测试

3.5 多宏模块项目结构

当项目包含多个宏模块时,可以组织为:

my_project/
├── cjpm.toml
├── src/
│   └── main.cj
├── macro_a/
│   ├── cjpm.toml          # compile-option = "--compile-macro"
│   └── src/
│       └── macro_a.cj
└── macro_b/
    ├── cjpm.toml          # compile-option = "--compile-macro"
    └── src/
        └── macro_b.cj

主项目 cjpm.toml

[dependencies]
macro_a = { path = "./macro_a" }
macro_b = { path = "./macro_b" }

4. 并行宏展开

  • 使用 --parallel-macro-expansion 标志启用并行宏展开
  • 警告:使用全局变量的宏在并行展开时不安全
  • 可通过 cjpm.tomlcompile-option 添加:
[package]
compile-option = "--parallel-macro-expansion"

5. 调试模式

  • --debug-macro 生成 .macrocall 临时文件显示完全展开的宏代码
  • 用于开发阶段排查宏展开结果是否符合预期
# cjc 直接使用
cjc src/demo.cj --debug-macro --import-path ./target

# cjpm 中通过 compile-option 使用
# cjpm.toml
[package]
compile-option = "--debug-macro"

6. 常见问题

6.1 编译顺序错误

  • 现象:编译调用包时报找不到宏定义
  • 原因:宏包未先编译或 --import-path 未正确指向宏包输出目录
  • 解决:确保先用 --compile-macro 编译宏包,再编译调用包。使用 cjpm 时工具会自动处理编译顺序

6.2 宏包中非宏符号导出

  • 现象:宏包中的辅助函数在外部不可见
  • 原因:宏包中仅宏定义可为 public
  • 解决:将辅助函数放到独立的非宏包中,宏包和调用包分别依赖该非宏包
Weekly Installs
3
First Seen
5 days ago
Installed on
opencode2
gemini-cli2
claude-code2
github-copilot2
codex2
kimi-cli2