Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
22 changes: 22 additions & 0 deletions .agents/docs/2026-10-13-add-pybind11-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Add compat.pybind11

The upstream revision 6254086d96062249c5153c17eab6b4437dd1589f identifies
itself as 3.2.0a0, not released 3.2.0. The index version is therefore
3.2.0-dev.6254086. Its archive hash was checked twice; license BSD-3-Clause.

Form B: original header-only include/ plus a generated C anchor. The descriptor
identity and path are compat.pybind11 and pkgs/c/compat.pybind11.lua. No optional
compiled sources exist, so there are no package features. Plain-string GLOBAL
URLs retain the documented CN fallback.

Python is a consumer SDK dependency, not vendored into pybind11. The example
declares xim:python 3.13.12 and asks mcpp::xpkg_dir for its actual payload.
Headers, library and standard library all come from that SDK, avoiding system
Python multiarch configuration and mixed-libc failures. It selects python313.lib
on Windows and python3.13 on Unix; The SDK runtime directory lets mcpp deploy the matching Python DLLs on Windows.
It never invents Python configuration macros or uses Linux-only link syntax.

The example embeds Python, evaluates a sum and calls a C++ function from
Python, asserting both results. Local validation with CI-pinned mcpp
2026.10.1.2 and gcc 16.1.0: `mcpp test -p pybind11`:
`test result ok. 1 passed; 0 failed`.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ the online index; open a PR and confirm CI is green.
A PR runs lint and tests only the workspace members that depend on the changed descriptors; after the merge,
`deploy-site` publishes the site.

Additional example: [`compat.pybind11`](pkgs/c/compat.pybind11.lua) — Header-only Python bindings; [`consumer test`](tests/examples/pybind11/mcpp.toml).
Additional example: [`compat.etl`](pkgs/c/compat.etl.lua) — Header-only; [`consumer test`](tests/examples/etl/mcpp.toml).
Additional example: [`compat.richdem`](pkgs/c/compat.richdem.lua) — C++ sources, serial terrain analysis; [`consumer test`](tests/examples/richdem/mcpp.toml).

Expand Down
1 change: 1 addition & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ agent(如 Claude Code)即可:

提交 PR 后,CI 执行 lint,并只测试依赖了被修改描述符的 workspace 成员;合并后,`deploy-site` 发布站点。

新增示例: [`compat.pybind11`](pkgs/c/compat.pybind11.lua) — Header-only Python bindings; [`消费测试`](tests/examples/pybind11/mcpp.toml)。
新增示例: [`compat.etl`](pkgs/c/compat.etl.lua) — Header-only; [`消费测试`](tests/examples/etl/mcpp.toml)。
新增示例: [`compat.richdem`](pkgs/c/compat.richdem.lua) — C++ sources, serial terrain analysis; [`消费测试`](tests/examples/richdem/mcpp.toml)。

Expand Down
1 change: 1 addition & 0 deletions mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ members = [
"tests/examples/nanosvg",
"tests/examples/nanodbc",
"tests/examples/plf-hive",
"tests/examples/pybind11",
"tests/examples/spirv-reflect",
"tests/examples/vulkan-memory-allocator",
"tests/examples/wamr",
Expand Down
50 changes: 50 additions & 0 deletions pkgs/c/compat.pybind11.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
-- Form B inline descriptor for pybind11, a header-only library for creating
-- Python bindings from C++.
--
-- Python headers and libraries come from a matching consumer Python SDK.
-- The example declares xim:python and uses its payload rather than host Python.
package = {
spec = "1",
namespace = "compat",
name = "pybind11",
description = "Seamless operability between C++11 and Python",
licenses = {"BSD-3-Clause"},
repo = "https://github.com/pybind/pybind11",
type = "package",

xpm = {
linux = {
["3.2.0-dev.6254086"] = {
url = "https://github.com/pybind/pybind11/archive/6254086d96062249c5153c17eab6b4437dd1589f.tar.gz",
sha256 = "4a77778750ae4bd27d29dd328902b03a7efb9c3468c6f23180fa39d80c05f635",
},
},
macosx = {
["3.2.0-dev.6254086"] = {
url = "https://github.com/pybind/pybind11/archive/6254086d96062249c5153c17eab6b4437dd1589f.tar.gz",
sha256 = "4a77778750ae4bd27d29dd328902b03a7efb9c3468c6f23180fa39d80c05f635",
},
},
windows = {
["3.2.0-dev.6254086"] = {
url = "https://github.com/pybind/pybind11/archive/6254086d96062249c5153c17eab6b4437dd1589f.tar.gz",
sha256 = "4a77778750ae4bd27d29dd328902b03a7efb9c3468c6f23180fa39d80c05f635",
},
},
},

mcpp = {
language = "c++23",
import_std = false,
c_standard = "c11",
include_dirs = { "*/include" },
generated_files = {
["mcpp_generated/pybind11_anchor.c"] = [==[
int mcpp_pybind11_headers_anchor(void) { return 0; }
]==],
},
sources = { "mcpp_generated/pybind11_anchor.c" },
targets = { ["pybind11"] = { kind = "lib" } },
deps = {},
},
}
33 changes: 33 additions & 0 deletions tests/examples/pybind11/build.mcpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <cstdio>
#include <filesystem>
#include <fstream>
#include <string>

import mcpp;

int main() {
namespace fs = std::filesystem;
const fs::path python = mcpp::xpkg_dir("xim", "python");
if (python.empty() || !fs::is_directory(python)) {
std::fputs("the declared xim:python SDK is unavailable\n", stderr);
return 1;
}
const bool windows = std::string(mcpp::target_os()) == "windows";
const fs::path headers = python / "include" / (windows ? "" : "python3.13");
const fs::path libraries = python / (windows ? "libs" : "lib");
if (!fs::exists(headers / "Python.h")) return 1;
mcpp::include_dir(headers.string().c_str());
mcpp::link_search(libraries.string().c_str());
mcpp::link_lib(windows ? "python313" : "python3.13");
mcpp::runtime_search_dir((python / (windows ? "" : "lib")).string().c_str());
// Resolve the standard library in the same SDK when embedding Python.
const fs::path config_dir = fs::absolute(".mcpp/python-sdk");
fs::create_directories(config_dir);
std::ofstream config(config_dir / "python_sdk.h");
config << "#define MCPP_PYTHON_HOME R\"SDK(" << python.generic_string() << ")SDK\"\n";
config.close();
if (!config) return 1;
mcpp::include_dir(config_dir.string().c_str());
mcpp::rerun_if_changed("build.mcpp");
return 0;
}
12 changes: 12 additions & 0 deletions tests/examples/pybind11/mcpp.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "pybind11-tests"
version = "0.1.0"

[dependencies.compat]
pybind11 = "3.2.0-dev.6254086"

[indices]
compat = { path = "../../.." }

[xlings.workspace]
"xim:python" = "3.13.12"
20 changes: 20 additions & 0 deletions tests/examples/pybind11/tests/embed.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <pybind11/embed.h>
#include <python_sdk.h>

int main() {
namespace py = pybind11;
PyConfig config;
PyConfig_InitPythonConfig(&config);
const PyStatus status = PyConfig_SetBytesString(&config, &config.home, MCPP_PYTHON_HOME);
if (PyStatus_Exception(status)) {
PyConfig_Clear(&config);
return 1;
}
py::scoped_interpreter interpreter(&config);
PyConfig_Clear(&config);
const int answer = py::eval("sum([1, 2, 3, 4])").cast<int>();
py::dict globals;
globals["double_value"] = py::cpp_function([](int value) { return 2 * value; });
py::exec("result = double_value(21)", globals);
return answer == 10 && globals["result"].cast<int>() == 42 ? 0 : 2;
}
Loading