Skip to content

Commit 84e63a6

Browse files
authored
feat: add C++ bindings generation support and update related configur… (#103)
…ations Signed-off-by: Gordon Smith <GordonJSmith@gmail.com>
1 parent 112963a commit 84e63a6

File tree

7 files changed

+80
-2
lines changed

7 files changed

+80
-2
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@
2020
"[jsonc]": {
2121
"editor.defaultFormatter": "esbenp.prettier-vscode",
2222
"editor.formatOnSave": true
23-
}
23+
},
24+
"ecl.launchConfiguration": "no selection"
2425
}

package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@
161161
"title": "Generate C Bindings",
162162
"category": "WIT"
163163
},
164+
{
165+
"command": "wit-idl.generateBindingsCpp",
166+
"title": "Generate C++ Bindings",
167+
"category": "WIT"
168+
},
164169
{
165170
"command": "wit-idl.generateBindingsCSharp",
166171
"title": "Generate C# Bindings",
@@ -255,6 +260,9 @@
255260
{
256261
"command": "wit-idl.generateBindingsC"
257262
},
263+
{
264+
"command": "wit-idl.generateBindingsCpp"
265+
},
258266
{
259267
"command": "wit-idl.generateBindingsCSharp"
260268
},
@@ -284,6 +292,10 @@
284292
"command": "wit-idl.generateBindingsC",
285293
"when": "editorLangId == wit || witIdl.isWasmComponent"
286294
},
295+
{
296+
"command": "wit-idl.generateBindingsCpp",
297+
"when": "editorLangId == wit || witIdl.isWasmComponent"
298+
},
287299
{
288300
"command": "wit-idl.generateBindingsCSharp",
289301
"when": "editorLangId == wit || witIdl.isWasmComponent"

src/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ export function activate(context: vscode.ExtensionContext) {
666666
// Create individual language binding commands
667667
const generateRustBindingsCommand = createGenerateBindingsCommand("rust", "Rust");
668668
const generateCBindingsCommand = createGenerateBindingsCommand("c", "C");
669+
const generateCppBindingsCommand = createGenerateBindingsCommand("cpp", "Cpp");
669670
const generateCSharpBindingsCommand = createGenerateBindingsCommand("csharp", "CSharp");
670671
const generateGoBindingsCommand = createGenerateBindingsCommand("go", "Go");
671672
const generateMoonBitBindingsCommand = createGenerateBindingsCommand("moonbit", "MoonBit");
@@ -716,6 +717,7 @@ export function activate(context: vscode.ExtensionContext) {
716717
extractCoreWasmCommand,
717718
generateRustBindingsCommand,
718719
generateCBindingsCommand,
720+
generateCppBindingsCommand,
719721
generateCSharpBindingsCommand,
720722
generateGoBindingsCommand,
721723
generateMoonBitBindingsCommand,

wit-bindgen-wasm/Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wit-bindgen-wasm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ wasmparser = { version = "0.243", features = ["component-model"] }
2222
wit-parser = "0.243"
2323
wit-bindgen-core = "0.49"
2424
wit-bindgen-c = "0.49"
25+
wit-bindgen-cpp = "0.49"
2526
wit-bindgen-rust = "0.49"
2627
wit-bindgen-csharp = "0.49"
2728
wit-bindgen-moonbit = "0.49"

wit-bindgen-wasm/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ main();
6262
- `has_world_definition(content: string): boolean` - Check for world definitions
6363
- `version(): string` - Get package version
6464
- `generate_bindings(content: string, language: string, world_name?: string): string` - Generate language bindings (returns JSON with file map)
65+
- Supported languages: `rust`, `c`, `cpp` (or `c++`), `csharp` (or `c#`), `go`, `moonbit`
6566

6667
### Binary Safety Contract
6768

wit-bindgen-wasm/src/lib.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use wasmparser::{Parser, Payload};
1010
use wit_bindgen_core::Files;
1111
use wit_bindgen_rust as rust;
1212
use wit_bindgen_c as c;
13+
use wit_bindgen_cpp as cpp;
1314
use wit_bindgen_csharp as csharp;
1415
use wit_bindgen_moonbit as moonbit;
1516

@@ -226,14 +227,15 @@ impl WitBindgen {
226227
let files = match language.to_lowercase().as_str() {
227228
"rust" => self.generate_rust_bindings(content, world_name),
228229
"c" => self.generate_c_bindings(content, world_name),
230+
"cpp" | "c++" => self.generate_cpp_bindings(content, world_name),
229231
"csharp" | "c#" => self.generate_csharp_bindings(content, world_name),
230232
"go" => self.generate_go_bindings(content, world_name),
231233
"moonbit" => self.generate_moonbit_bindings(content, world_name),
232234
_ => {
233235
let mut error_files = HashMap::new();
234236
error_files.insert(
235237
"error.txt".to_string(),
236-
format!("// Unsupported language: {}\n// Supported languages: rust, c, csharp, go, moonbit", language)
238+
format!("// Unsupported language: {}\n// Supported languages: rust, c, cpp, csharp, go, moonbit", language)
237239
);
238240
error_files
239241
},
@@ -285,6 +287,49 @@ impl WitBindgen {
285287
Ok(result)
286288
}
287289

290+
/// Generate C++ bindings using wit-bindgen-cpp library
291+
fn generate_cpp_bindings(&self, content: &str, world_name: Option<String>) -> HashMap<String, String> {
292+
match self.generate_cpp_with_wit_bindgen(content, world_name.as_deref()) {
293+
Ok(files) => files,
294+
Err(e) => {
295+
console_error(&format!("wit-bindgen-cpp failed: {}", e));
296+
let mut error_files = HashMap::new();
297+
error_files.insert(
298+
"error.txt".to_string(),
299+
format!("C++ binding generation failed: {}", e)
300+
);
301+
error_files
302+
}
303+
}
304+
}
305+
306+
/// Generate C++ bindings using wit-bindgen-cpp library
307+
fn generate_cpp_with_wit_bindgen(&self, content: &str, world_name: Option<&str>) -> Result<HashMap<String, String>, anyhow::Error> {
308+
let inline_path = Path::new("inline.wit");
309+
let mut resolve = Resolve::default();
310+
let package_id = resolve.push_str(inline_path, content)
311+
.with_context(|| "Failed to parse WIT content for C++ binding generation")?;
312+
313+
let world_id = if let Some(world_name) = world_name {
314+
resolve.select_world(&[package_id], Some(world_name))?
315+
} else {
316+
resolve.select_world(&[package_id], None)?
317+
};
318+
319+
let opts = cpp::Opts::default();
320+
let mut generator = opts.build(None);
321+
let mut files = Files::default();
322+
323+
generator.generate(&resolve, world_id, &mut files)?;
324+
325+
let mut result = HashMap::new();
326+
for (filename, content) in files.iter() {
327+
result.insert(filename.to_string(), bytes_to_latin1_string(content));
328+
}
329+
330+
Ok(result)
331+
}
332+
288333
/// Generate Rust bindings using wit-bindgen-rust library
289334
fn generate_rust_bindings(&self, content: &str, world_name: Option<String>) -> HashMap<String, String> {
290335
match self.generate_rust_with_wit_bindgen(content, world_name.as_deref()) {

0 commit comments

Comments
 (0)