Luamake Build System

SkillDev tools

Guide to the Luamake build system—for the current project's `luamake` / `make.lua` / Ninja generation workflow. Use this skill when the user needs to write, modify, troubleshoot, or understand `make.lua`, target definitions, `lm:conf`, `deps` / `objdeps`, code generation, Lua C modules, Bee runtime

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Luamake Build System skill

What this skill tells your AI

The instructions your AI receives, as published by actboy168/luamake in skills/SKILL.md and read by ahel’s review.

基于 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 目标会自动导出 includesobjdeps,通过 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 = truebee_glue = true 启用 bee 胶水层,约定 data.preload 注入 _PRELOADdata.main[1] 作为入口。自动向依赖方导出 includesobjdeps,通过 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 报错,或理解 depsobjdepslm:conf、目标类型、构建目录等机制。
  • 用户讨论的问题与当前项目的 Ninja 生成流程、Bee 集成或 Lua C 模块构建直接相关。

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

  • 与当前项目无关的通用 C/C++ 编译、链接、优化理论问题。
  • CMakexmakeBazelMeson 等其他构建系统的问题。
  • 只是在问编译器语法、语言标准或平台 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/ 目录重新构建

Signals

GitHub stars
210
Forks
47
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
luamake
Source
github.com/actboy168/luamake