Skip to content
cccskills
FreePublished on GitHub

luamake

Luamake 构建系统指南——用于当前项目的 `luamake` / `make.lua` / Ninja 生成流程。

当用户需要编写、修改、排查或理解 `make.lua`、目标定义、`lm:conf`、`deps` / `objdeps`、代码生成、Lua C 模块、Bee 运行时集成,或需要解决当前项目中由 `luamake` 驱动的构建问题时,使用此 skill。

即使用户没有明确提到 `luamake`,但上下文明显是在处理本项目的构建脚本、构建目录、目标依赖或 `luamake` 生成的 Ninja 流程,也应使用此 skill。

不要把它用于纯通用的 C/C++ 编译知识、与本项目无关的 CMake / xmake / Bazel / Meson 问题,或仅讨论编译器理论而未涉及 `luamake` / `make.lua` 的请求。

The English summary is being prepared. Showing the original description.

See how to install

Files included (10)

  • SKILL.md11.7 KB
  • references/advanced/bee_runtime.md2.3 KB
  • references/advanced/lua_embed.md14.1 KB
  • references/best_practices/bp_codegen.md4.8 KB
  • references/best_practices/bp_compilation.md678 B
  • references/best_practices/bp_dependency.md4.2 KB
  • references/best_practices/bp_lua_and_test.md1.1 KB
  • references/core/advanced_api.md6.1 KB
  • references/core/path_management.md4.7 KB
  • references/core/platform_config.md4.2 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Luamake Build System

基于 Lua 的构建系统,生成 Ninja 构建文件。

快速开始

local lm = require "luamake"

lm:exe "myapp" {
    sources = { "src/*.c", "!src/test.c" },
    includes = "include",
    defines = { "DEBUG", "VERSION=1.0" },
}
luamake          # 构建
luamake clean    # 清理
luamake rebuild  # 重建

目标类型

API说明输出
lm:exe可执行文件app.exe / app
lm:dll动态库lib.dll / lib.so / lib.dylib
lm:lib静态库lib.lib / lib.a
lm:source_set源码集(不链接,用于复用,通过 deps 引用)无
lm:lua_srcLua C 模块(静态嵌入到 lm:lua_exe)无
lm:lua_dllLua C 模块(动态加载)module.dll / module.so
lm:lua_exe内嵌 Lua 的可执行文件app.exe / app
lm:lua_embedLua 嵌入资源(按命名组嵌入 Lua 文件,生成 source_set;自动导出 includes/objdeps)无(source_set)
lm:phony伪目标(聚合依赖)无

目标属性

源文件

属性说明示例
sources源文件"src/*.cpp", { "a.cpp", "b.cpp" }
includes包含目录"include", { "include", "3rd" }
sysincludes系统包含目录(抑制警告)"/usr/local/include"
defines预处理器定义{ "DEBUG", "VER=1" }
objdeps对象依赖(编译前必须生成)"generated_header"

objdeps 用法:当源文件依赖代码生成产物(如生成的头文件)时,需用 objdeps 声明依赖的目标名,确保生成步骤在编译前完成。deps 只控制链接顺序,不能保证编译前生成文件。

lm:rule "gen_header" { ... }  -- 生成头文件的规则
lm:exe "app" {
    sources = "src/*.cpp",
    objdeps = "gen_header",  -- 编译 src/*.cpp 前先执行 gen_header
}

注意:lm:lua_embed 目标会自动导出 includes 和 objdeps,通过 deps 依赖它的目标无需手动声明这两项。详见下方 lm:lua_embed 用法。

链接

属性说明示例
links链接库{ "pthread", "ws2_32" }
linkdirs库搜索目录"lib", { "lib", "/usr/lib" }
ldflags链接器标志"-Wl,--as-needed"
frameworksmacOS/iOS 框架{ "Foundation", "Cocoa" }
deps目标依赖"lib1", { "lib1", "lib2" }

编译

属性说明示例
flags编译器标志{ "-Wall", "-O2" }
cflagsC 编译器标志"-std=c11"
cxxflagsC++ 编译器标志"-std=c++20"
confs引用命名配置"myconfig"

注意:cflags/cxxflags 直接传递给编译器命令行。在 lm:conf 中可用 c = "c11" / cxx = "c++20" 作为简写,luamake 会自动转换为对应编译器的标准标志(如 MSVC 的 /std:c11)。

特殊目标用法

lm:source_set — 将源文件组织为可复用的源码集,通过 deps 引用,不单独链接:

-- 定义共享源码集
lm:source_set "common" {
    includes = "include",
    sources = { "src/common/*.cpp" },
}

-- 多个目标复用同一组源文件
lm:exe "app1" { deps = "common", sources = "src/app1.cpp" }
lm:exe "app2" { deps = "common", sources = "src/app2.cpp" }

lm:lua_src — 将 Lua C 模块静态嵌入到 lm:lua_exe 中:

lm:lua_src "mymodule" {
    sources = "src/mymodule.c",
}

lm:lua_exe "app" {
    deps = "mymodule",
    sources = "src/main.cpp",
}

lm:lua_embed — 将 Lua 文件按命名组嵌入到 C 源码中,生成一个 source_set 供其他目标依赖。data 下每个 key 是一个组,组名直接成为生成的 lua_embed_bundle 结构体的字段名。每组可独立设置 bytecode = true。bee_glue = true 启用 bee 胶水层,约定 data.preload 注入 _PRELOAD、data.main[1] 作为入口。自动向依赖方导出 includes 和 objdeps,通过 deps 依赖时无需手动声明。完整规则(分组语义、pattern 语法、字节码取舍、bee_glue 契约、无胶水时的接入姿势)见 references/advanced/lua_embed.md:

lm:lua_embed "myembed" {
    bee_glue = true,
    data = {
        main    = { bytecode = true, "src/main.lua" },
        preload = { bytecode = true, { dir = "lualib" } },
        data    = { { name = "config.json", file = "assets/config.json" } },
    },
}

lm:lua_src "glue" {
    deps     = "myembed",       -- 自动获取 includes 和 objdeps
    includes = "3rd/bee.lua",
    sources  = "src/glue.cpp",
}

lm:lua_exe "app" { deps = { "glue", "myembed" }, sources = "src/main.cpp", }


**`lm:phony`** — 聚合多个目标为一个命名依赖,方便统一引用:

```lua
lm:phony "all_libs" {
    deps = { "libfoo", "libbar", "libqux" },
}

lm:exe "app" {
    deps = "all_libs",
    sources = "main.cpp",
}

配置 (lm:conf)

lm:conf 有两种用法,行为完全不同,不要混淆:

匿名配置:lm:conf { ... } — 立即生效,影响全局

不带名称调用时,属性立即应用到当前工作区的所有后续目标,相当于设置全局默认值。

-- 所有参数均为可选,按项目实际需要填写
lm:conf {
    c = "c11",        -- C 标准:"c89", "c99", "c11", "c17"
    cxx = "c++20",    -- C++ 标准:"c++11", "c++14", "c++17", "c++20"
    visibility = "hidden",  -- 符号可见性:"hidden"(默认隐藏)或 "default"(默认可见)
}

-- 以下目标自动继承上面的配置
lm:exe "app1" { sources = "src/app1.cpp" }
lm:exe "app2" { sources = "src/app2.cpp" }

适用场景:项目中大部分目标共享相同的编译标准、模式等基础配置时使用。

命名配置:lm:conf "name" { ... } — 按需引用,不自动生效

带名称调用时,属性不会立即生效,仅存储起来,需要目标通过 confs 属性显式引用。

-- 定义命名配置(不会自动应用到任何目标)
lm:conf "mylib" {
    defines = "MYLIB_API",
    includes = "3rd/mylib",
}

-- 通过 confs 引用,只有这个目标会使用该配置
lm:exe "app" {
    confs = "mylib",
    sources = "main.cpp",
}

适用场景:多个目标需要共享同一组特定配置(如第三方库的头文件路径和宏定义),但不希望污染全局时使用。

如何选择

场景用法
设置项目范围的 C/C++ 标准、构建模式等lm:conf { ... }
为特定的几个目标共享一组 includes/defineslm:conf "name" { ... } + confs = "name"
只有一个目标需要特定配置直接写在目标属性里,无需 conf

内置变量

路径变量

变量说明示例
$builddir构建目录(默认 build,可自定义)build
$bindir二进制输出目录build/bin
$objdir对象文件目录build/obj
$bin$bindir 别名
$obj$objdir 别名
$in输入文件 (规则中)
$out输出文件 (规则中)

自定义构建目录:当项目已使用 build 目录时,可在脚本开头修改构建目录:

lm.builddir = "_build"   -- 构建产物将输出到 _build/ 目录

$bindir 和 $objdir 默认基于 $builddir,修改后会自动跟随变化。

全局变量

变量说明示例值
lm.os目标 OS"windows", "linux", "macos", "ios", "android"
lm.compiler编译器"msvc", "gcc", "clang"
lm.arch架构"x86_64", "x86", "arm64"
lm.mode构建模式"debug", "release"
lm.workdir工作目录项目根目录

开发工作流

编写或修改 make.lua 构建脚本后,必须运行构建命令验证脚本的正确性:

# 1. 运行构建,验证脚本是否有语法错误或配置问题
luamake

# 2. 如果构建失败,根据错误信息修复脚本后重新运行
luamake

# 3. 如果需要从干净状态重建(排除增量构建的干扰)
luamake rebuild

注意事项

  • Windows 平台:必须使用 PowerShell 运行 luamake 命令,不要使用 Git Bash。
  • 每次修改 make.lua 后都要运行 luamake 确认构建成功,不要只写脚本不验证。
  • 关注构建输出中的警告和错误信息,它们通常指向配置问题(如路径错误、缺少依赖等)。
  • 如果构建失败,优先分析错误信息,修复后再次运行验证,直到构建通过。

最佳实践

主题文档包含内容
依赖管理references/best_practices/bp_dependency.mddeps 定义顺序、源码集复用、增量源码集、动态模块发现
条件编译与静态分析references/best_practices/bp_compilation.md条件编译、静态分析集成
代码生成与 objdepsreferences/best_practices/bp_codegen.md代码生成管道、objdeps 用法
Lua 模块与测试references/best_practices/bp_lua_and_test.mdLua C 模块、内置测试框架

其他详细文档

主题文档
Bee 运行时库(API 参考来源、模块列表、Meta 文件用法)references/advanced/bee_runtime.md
lm:lua_embed 权威参考(分组 / pattern / bytecode / bee_glue / 自定义接入)references/advanced/lua_embed.md

Bee 运行时库

luamake lua script.lua 运行脚本时预加载 bee 库。API 参考来源及模块列表详见 references/advanced/bee_runtime.md。

适用边界

优先在以下场景使用本 skill:

  • 当前仓库明确使用 luamake 或通过 make.lua 定义构建目标。
  • 用户正在修改 make.lua、排查 luamake 报错,或理解 deps、objdeps、lm:conf、目标类型、构建目录等机制。
  • 用户讨论的问题与当前项目的 Ninja 生成流程、Bee 集成或 Lua C 模块构建直接相关。

以下场景通常不应使用本 skill:

  • 与当前项目无关的通用 C/C++ 编译、链接、优化理论问题。
  • 纯 CMake、xmake、Bazel、Meson 等其他构建系统的问题。
  • 只是在问编译器语法、语言标准或平台 API,而没有落到 luamake / make.lua 的构建脚本上。

故障排除

问题解决方案
"no source files found"检查 glob 模式,确认 rootdir,检查文件扩展名
Windows 链接错误添加系统库:links = { "ws2_32", "iphlpapi", "user32" }
交叉编译问题使用平台特定配置,检查 lm.compiler
缺少生成文件添加 objdeps 确保生成后再编译
build 目录冲突项目已使用 build 目录时,用 lm.builddir = "_build" 修改构建目录
找不到头文件检查 includes 路径,使用绝对路径或 $builddir
Ninja 构建失败删除 build/ 目录重新构建

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

Report a problem with this skill