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
6 changes: 6 additions & 0 deletions .github/workflows/wasm-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ jobs:
- name: wasm32-unknown-unknown-example
target: wasm32-unknown-unknown
command: cargo build -p tinyxml2 --target wasm32-unknown-unknown --example wasm_parse
- name: wasm32-unknown-unknown-capi
target: wasm32-unknown-unknown
command: cargo build -p tinyxml2-capi --target wasm32-unknown-unknown --release
- name: wasm32-wasip1
target: wasm32-wasip1
command: cargo build -p tinyxml2 --target wasm32-wasip1
Expand All @@ -42,6 +45,9 @@ jobs:
- name: wasm32-wasip1-example
target: wasm32-wasip1
command: cargo build -p tinyxml2 --target wasm32-wasip1 --example wasm_parse
- name: wasm32-wasip1-capi
target: wasm32-wasip1
command: cargo build -p tinyxml2-capi --target wasm32-wasip1 --release
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,19 @@

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.1.1] - 2026-07-14

### Added
- **WebAssembly Support for C/C++ FFI**: Enabled compilation of the `tinyxml2-capi` FFI bindings crate for `wasm32-unknown-unknown` and `wasm32-wasip1` targets. C and C++ projects compiled to WebAssembly (via Emscripten or WASI SDK) can now link with the static library (`libtinyxml2_capi.a`) as a drop-in replacement.
- **CI Validation for C/C++ WASM**: Added automated GitHub Actions check to compile `tinyxml2-capi` for WASM targets.
- **WASM FFI Integration Guide**: Added detailed compilation and linking instructions for Emscripten (`emcc`) and WASI SDK (`clang`) under `docs/architecture/wasm.md`.

## [1.1.0] - 2026-07-01

### Added
- **`no_std` Support**: Added `no_std` support with `alloc` allocator feature-gated for resource-constrained environments.
- **Rust WASM Support**: Verified compilation and execution of `tinyxml2` core library under `wasm32-unknown-unknown` and `wasm32-wasip1`.
- **Abstract I/O**: File operations and stream writers are now feature-gated under the `std` feature.

## [1.0.0] - 2026-07-01

Expand Down
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ members = [
]

[workspace.package]
version = "1.1.0"
version = "1.1.1"
edition = "2024"
rust-version = "1.85.0"
license = "MIT"
Expand Down
7 changes: 5 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,15 +309,18 @@ parse_document()

---

## Phase 9: WASM & `no_std` Support (Target: Version 1.1.0) βœ… **COMPLETED**
## Phase 9: WASM & `no_std` Support (Target: Versions 1.1.0 & 1.1.1) βœ… **COMPLETED**

Enable tinyxml2-rs to run in resource-constrained embedded environments and web browsers.

### Key Deliverables
### Key Deliverables (v1.1.0)
- [x] **no_std compatibility** β€” Feature-gate standard library dependencies and use the `alloc` crate for all dynamic memory allocations (`Vec`, `String`, `Box`). Target: `#![no_std]` with `extern crate alloc`.
- [x] **WASM target support** β€” Validate the core crate on `wasm32-unknown-unknown` and `wasm32-wasip1`. JavaScript bindings are intentionally left to the host application boundary; see `docs/architecture/wasm.md`.
- [x] **Abstract I/O** β€” Gate file/stream writers behind the `std` feature and keep the core parser, DOM, and string serialization available without `std::io::Write`.

### Key Deliverables (v1.1.1)
- [x] **C/C++ FFI WASM Support** β€” Support compiling and linking the FFI bindings (`tinyxml2-capi`) on `wasm32-unknown-unknown` and `wasm32-wasip1` targets for C/C++ WebAssembly integration.

---

## Phase 10: XPath & Serde Integration (Target: Version 1.2.0) πŸ”² **PLANNED**
Expand Down
62 changes: 59 additions & 3 deletions docs/architecture/wasm.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,74 @@ feature. Validate no_std support with `--lib`, or from a consumer crate that
supplies the allocator, panic strategy, and host boundary required by that
environment.

## C and C++ WebAssembly Support

The C FFI compatibility layer (`tinyxml2-capi`) compiles to WebAssembly targets out of the box. C and C++ projects compiled to WebAssembly (via Emscripten or WASI SDK) can link against this compiled Rust artifact as a drop-in replacement.

> [!NOTE]
> The project's CI validates compiling the Rust artifacts (`libtinyxml2_capi.a` and `tinyxml2_capi.wasm`) for WASM targets. Compiling and linking the final C/C++ application remains the responsibility of the consumer's C toolchain (e.g. Emscripten or WASI SDK).

When compiled to `wasm32-unknown-unknown` or `wasm32-wasip1`, it generates:
- A WebAssembly binary (`tinyxml2_capi.wasm`)
- A static library (`libtinyxml2_capi.a`)

### Compiling the C FFI for WebAssembly

To compile the C FFI bindings library for WebAssembly:

```bash
# Target the browser / JavaScript environment (e.g. for Emscripten)
cargo build -p tinyxml2-capi --target wasm32-unknown-unknown --release

# Target WASI environments (e.g. for Wasmtime, Wasmer)
cargo build -p tinyxml2-capi --target wasm32-wasip1 --release
```

The resulting library `libtinyxml2_capi.a` will be located under `target/wasm32-unknown-unknown/release/` or `target/wasm32-wasip1/release/`.

### Linking in C/C++ WebAssembly Projects

#### 1. Browser/Emscripten Toolchain (`emcc`)
To compile a C/C++ file with Emscripten and link the Rust WASM static library:

```bash
emcc -Icrates/tinyxml2-capi/include -O3 \
crates/tinyxml2-capi/examples/basic.c \
target/wasm32-unknown-unknown/release/libtinyxml2_capi.a \
-o basic.js \
-s WASM=1 \
-s ALLOW_MEMORY_GROWTH=1
```

#### 2. WASI SDK Toolchain (`clang`)
To compile for a standalone WASI runtime (e.g., Wasmtime) using the WASI SDK:

```bash
/path/to/wasi-sdk/bin/clang -Icrates/tinyxml2-capi/include -O3 \
--sysroot=/path/to/wasi-sysroot \
crates/tinyxml2-capi/examples/basic.c \
target/wasm32-wasip1/release/libtinyxml2_capi.a \
-o basic.wasm
```

### ABI and Memory Considerations
- **Shared Memory**: Since Rust and C/C++ compile into a single WebAssembly module when linked statically, they share the same linear memory and allocator (supplied by the C runtime or Rust's target).
- **String Lifetimes**: Pointers returned by `tx_document_to_string`, `tx_element_name`, or other getters returning `*const c_char` point to UTF-8 C-strings borrowed from the `TxDocument`/`TxPrinter`-owned `CString` caches. Callers **must not free** these pointers. They become invalid as soon as the document is modified (mutated) or when the owning document/printer wrapper is freed.

## Validation

Use these commands when changing parser, DOM, or serialization code:
Use these commands when changing parser, DOM, serialization, or FFI code:

```bash
cargo check -p tinyxml2
cargo check -p tinyxml2 --no-default-features --lib
cargo check -p tinyxml2 --no-default-features --target wasm32-unknown-unknown --lib
cargo check -p tinyxml2 --target wasm32-wasip1 --lib
cargo build -p tinyxml2 --target wasm32-unknown-unknown --example wasm_parse
cargo build -p tinyxml2-capi --target wasm32-unknown-unknown --release
cargo build -p tinyxml2-capi --target wasm32-wasip1 --release
cargo test -p tinyxml2 --all-targets
cargo test -p tinyxml2-capi
```

Workspace crates that bind to native C/C++ code, such as `tinyxml2-capi`,
`tinyxml2-bench`, and `tinyxml2-cpp-helper`, remain native-only.
Workspace crates that bind to native C/C++ code, such as `tinyxml2-bench` and `tinyxml2-cpp-helper`, remain native-only.
Loading