Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: implement mcpplibs.capi.lua — C++23 module binding for Lua C API
- Add src/capi/lua.cppm (module interface) and src/capi/lua.cpp (implementation)
- Wrap lua.h, lauxlib.h, lualib.h in mcpplibs::capi::lua namespace
- Types: State, Number, Integer, CFunction, L_Reg, L_Buffer, etc.
- Constants: status codes, type tags, operators, GC options, hook masks
- Functions: 100+ bindings covering state, stack, push/access, tables,
  globals, calls, coroutines, GC, debug, auxiliary library, standard libs
- Use extern C wrapper header to fix GCC C++ modules linkage issue
- 97 comprehensive Google Test cases covering all API categories
- 4 examples: basic, table, function, eval
- Update xmake.lua, CMakeLists.txt, CI workflow, README, architecture docs
- Design docs and task breakdown in docs/pr/
- Remove old templates.cppm placeholder module

Co-authored-by: SPeak <sunrisepeak@d2learn.org>
  • Loading branch information
cursoragent and Sunrisepeak committed Feb 26, 2026
commit f7761cf2a63201f2d560da39f20b5fbf0ac43cdb
16 changes: 12 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,14 @@ jobs:
xmake -y -vv -j$(nproc)

- name: Test
run: xmake run templates_test
run: xmake run capi_lua_test

- name: Run examples
run: xmake run basic
run: |
xmake run basic
xmake run table
xmake run function
xmake run eval

build-macos:
runs-on: macos-14
Expand Down Expand Up @@ -90,7 +94,11 @@ jobs:
xmake -y -vv -j$env:NUMBER_OF_PROCESSORS

- name: Test
run: xmake run templates_test
run: xmake run capi_lua_test

- name: Run examples
run: xmake run basic
run: |
xmake run basic
xmake run table
xmake run function
xmake run eval
27 changes: 27 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Cursor Cloud specific instructions

### Project overview

C++23 module binding for Lua C API: `import mcpplibs.capi.lua;`. Uses xmake as primary build system, GCC 15.1 for C++23 module support.

### Environment

- **xlings** provides both xmake and GCC 15.1; install via `curl -fsSL https://raw.githubusercontent.com/d2learn/xlings/refs/heads/main/tools/other/quick_install.sh | XLINGS_NON_INTERACTIVE=1 bash`
- After installing xlings, run `xlings install gcc@15.1 -y` to get GCC 15.1
- PATH must include `$HOME/.xlings/bin` and `$HOME/.xlings/subos/current/bin`

### Build, test, run

Standard commands documented in `README.md`:
- `xmake f -m release -y` to configure
- `xmake -y -j$(nproc)` to build
- `xmake run capi_lua_test` to run tests (97 tests)
- `xmake run basic|table|function|eval` to run examples

### Important caveats

- **GCC C++ modules + C headers**: Lua headers must be wrapped with explicit `extern "C"` via `src/capi/lua_headers.h` in the global module fragment. Without this, GCC applies C++ name mangling to the C functions and linking fails. This is a GCC 15.1 behavior with C++ modules.
- **Interface + implementation split**: The module uses `.cppm` for declarations and `.cpp` for definitions. Functions cannot be `inline` in the `.cppm` because GCC would inline them at the import site where the Lua C declarations are not available, causing link errors.
- **Lua dependency**: xmake auto-downloads Lua via `add_requires("lua")`. Both `tests/xmake.lua` and `examples/xmake.lua` must include their own `add_requires("lua")` and `add_packages("lua")`.
- **Test target**: The test target is named `capi_lua_test` (not `templates_test` from the original template).
- **mcpp style**: Follow [mcpp-style-ref](https://github.com/mcpp-community/mcpp-style-ref). See `.agents/skills/mcpp-style-ref/SKILL.md` for details.
40 changes: 30 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,46 @@ set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "a9e1cf81-9932-4810-974b-6eccaf14e457")
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_MODULE_STD 1)

project(mcpplibs-templates VERSION 1.0.0 LANGUAGES CXX)
project(mcpplibs-capi-lua VERSION 1.0.0 LANGUAGES CXX)

# Find Lua
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_check_modules(LUA QUIET lua5.4 lua-5.4 lua54 lua)
endif()
if(NOT LUA_FOUND)
find_package(Lua QUIET)
if(LUA_FOUND)
set(LUA_INCLUDE_DIRS ${LUA_INCLUDE_DIR})
set(LUA_LIBRARIES ${LUA_LIBRARIES})
endif()
endif()

# Library
add_library(mcpplibs-templates STATIC)
add_library(mcpplibs-capi-lua STATIC)

file(GLOB_RECURSE MODULE_SOURCES "src/*.cppm")
file(GLOB_RECURSE MODULE_SOURCES "src/capi/*.cppm")

target_sources(mcpplibs-templates
target_sources(mcpplibs-capi-lua
PUBLIC
FILE_SET CXX_MODULES FILES
${MODULE_SOURCES}
)

if(LUA_FOUND)
target_include_directories(mcpplibs-capi-lua PUBLIC ${LUA_INCLUDE_DIRS})
target_link_libraries(mcpplibs-capi-lua PUBLIC ${LUA_LIBRARIES})
endif()

# Test
add_executable(templates_test tests/main.cpp)
target_link_libraries(templates_test PRIVATE mcpplibs-templates)
add_executable(capi_lua_test tests/main.cpp)
target_link_libraries(capi_lua_test PRIVATE mcpplibs-capi-lua)

enable_testing()
add_test(NAME mcpplibs-templates-test COMMAND templates_test)
add_test(NAME mcpplibs-capi-lua-test COMMAND capi_lua_test)

# Example
add_executable(basic examples/basic.cpp)
target_link_libraries(basic PRIVATE mcpplibs-templates)
# Examples
foreach(example basic table function eval)
add_executable(${example} examples/${example}.cpp)
target_link_libraries(${example} PRIVATE mcpplibs-capi-lua)
endforeach()
110 changes: 77 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,45 @@
# mcpplibs templates
# mcpplibs capi-lua

> C++23 模块化库项目模板 - `import mcpplibs.templates;`
> Lua C API 的 C++23 模块化绑定 - `import mcpplibs.capi.lua;`

基于 C++23 模块的库项目模板,提供标准化的项目结构、构建配置和 CI/CD 流水线,帮助快速创建 mcpplibs 风格的模块化 C++ 库
将 Lua C API(`lua.h` / `lauxlib.h` / `lualib.h`)封装为 C++23 模块,让其他 mcpplibs 模块可以通过 `import` 直接使用 Lua,无需手动 `#include` C 头文件

## 特性

- **C++23 模块** — `import mcpplibs.templates;`
- **C++23 模块** — `import mcpplibs.capi.lua;`
- **1:1 映射** — 接口与 Lua C API 完全对应,零额外抽象
- **零开销** — 所有封装均为 `inline` 函数和 `constexpr` 常量
- **双构建系统** — 同时支持 xmake 和 CMake
- **CI/CD** — GitHub Actions 多平台构建(Linux / macOS / Windows)
- **标准化结构** — 遵循 [mcpp-style-ref](https://github.com/mcpp-community/mcpp-style-ref) 编码规范
- **开箱即用** — 包含示例、测试和架构文档
- **遵循 mcpp-style-ref** — 标准化命名和项目结构

## 项目结构
## 命名映射

```
mcpplibs-templates/
├── src/ # 模块源码
│ └── templates.cppm # 主模块接口
├── tests/ # 测试
│ ├── main.cpp
│ └── xmake.lua
├── examples/ # 示例
│ ├── basic.cpp
│ └── xmake.lua
├── docs/ # 文档
│ └── architecture.md
├── .github/workflows/ # CI/CD
│ └── ci.yml
├── xmake.lua # xmake 构建配置
├── CMakeLists.txt # CMake 构建配置
└── config.xlings # xlings 工具链配置
```
在 `mcpplibs::capi::lua` 命名空间内,去掉 C API 前缀避免冗余:

| C API | 模块内 | 示例 |
|---|---|---|
| `lua_State` | `State` | `lua::State*` |
| `lua_gettop()` | `gettop()` | `lua::gettop(L)` |
| `luaL_newstate()` | `L_newstate()` | `lua::L_newstate()` |
| `LUA_OK` | `OK` | `lua::OK` |
| `luaopen_base()` | `open_base()` | `lua::open_base(L)` |

## 快速开始

```cpp
import std;
import mcpplibs.templates;
import mcpplibs.capi.lua;

namespace lua = mcpplibs::capi::lua;

int main() {
mcpplibs::templates::hello_mcpp();
auto* L = lua::L_newstate();
lua::L_openlibs(L);

lua::L_dostring(L, "print('hello from Lua!')");

lua::close(L);
return 0;
}
```
Expand All @@ -57,8 +56,11 @@ xlings install

```bash
xmake build # 构建库
xmake run basic # 运行基础示例
xmake run templates_test # 运行测试
xmake run basic # 基本用法示例
xmake run table # 表操作示例
xmake run function # 函数注册示例
xmake run eval # 脚本求值示例
xmake run capi_lua_test # 运行测试
```

**使用 CMake**
Expand All @@ -69,27 +71,69 @@ cmake --build build
ctest --test-dir build
```

## 项目结构

```
mcpplibs-capi-lua/
├── src/ # 模块源码
│ └── capi/
│ └── lua.cppm # 主模块接口 (export module mcpplibs.capi.lua)
├── tests/ # 测试
│ ├── main.cpp # Google Test 测试套件
│ └── xmake.lua
├── examples/ # 示例
│ ├── basic.cpp # 基本用法
│ ├── table.cpp # 表操作
│ ├── function.cpp # 函数注册与回调
│ ├── eval.cpp # 脚本求值
│ └── xmake.lua
├── docs/ # 文档
│ ├── architecture.md # 架构文档
│ └── pr/
│ ├── design.md # 设计文档
│ └── tasks.md # 任务清单
├── .github/workflows/ # CI/CD
│ └── ci.yml
├── xmake.lua # xmake 构建配置
├── CMakeLists.txt # CMake 构建配置
└── config.xlings # xlings 工具链配置
```

## 集成到构建工具

### xmake

```lua
add_repositories("mcpplibs-index https://github.com/mcpplibs/mcpplibs-index.git")

add_requires("templates")
add_requires("capi-lua")

target("myapp")
set_kind("binary")
set_languages("c++23")
add_files("main.cpp")
add_packages("templates")
add_packages("capi-lua")
set_policy("build.c++.modules", true)
```

## 覆盖范围

封装了 Lua 5.4 C API 的核心功能:

- **类型** — `State`, `Number`, `Integer`, `CFunction`, `L_Reg`, `L_Buffer` 等
- **常量** — 状态码、类型标签、运算符、GC 选项、Hook 掩码等
- **状态管理** — `L_newstate`, `close`, `newthread`, `version` 等
- **栈操作** — `gettop`, `settop`, `pop`, `pushvalue`, `rotate`, `insert`, `remove`, `replace` 等
- **入栈/取值** — `pushnil/number/integer/string/boolean`, `tonumber/tointeger/tostring/toboolean` 等
- **表操作** — `newtable`, `getfield/setfield`, `gettable/settable`, `rawget/rawset`, `next` 等
- **函数调用** — `call`, `pcall`, `pushcfunction`, `pushcclosure` 等
- **辅助库** — `L_dostring`, `L_dofile`, `L_loadstring`, `L_ref/L_unref`, `L_setfuncs`, `L_error` 等
- **标准库** — `open_base`, `open_math`, `open_string`, `open_table`, `open_io`, `open_os` 等
- **调试** — `getstack`, `getinfo`, `sethook`, `gethook` 等

## 相关链接

- [mcpp-style-ref | 现代C++编码/项目风格参考](https://github.com/mcpp-community/mcpp-style-ref)
- [mcpplibs/cmdline | 命令行解析库](https://github.com/mcpplibs/cmdline)
- [mcpplibs/templates | 项目模板](https://github.com/mcpplibs/templates)
- [mcpp社区官网](https://mcpp.d2learn.org)
- [mcpp | 现代C++爱好者论坛](https://mcpp.d2learn.org/forum)
- [入门教程: 动手学现代C++](https://github.com/Sunrisepeak/mcpp-standard)
4 changes: 2 additions & 2 deletions config.xlings
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
xname = "mcpplibs-templates"
xname = "mcpplibs-capi-lua"

-- install by `xlings install`
xim = {
xmake = "3.0.4",
cmake = "4.0.2",
ninja = "1.12.1",
cpp = "", -- gcc15 or mingw13
}
}
Loading